diff --git a/package.jsonغ b/package.jsonغ deleted file mode 100644 index e3b2d50..0000000 --- a/package.jsonغ +++ /dev/null @@ -1,127 +0,0 @@ -{ - "name": "modstagram-next", - "version": "0.1.0", - "private": true, - "scripts": { - "start": "next start -p 3000 -H 0.0.0.0", - "dev": "next dev -p 3000 -H 0.0.0.0", - "build": "next build" - "lint": "next lint", - "postbuild": "next-sitemap" - }, - "dependencies": { - "@dnd-kit/core": "^6.3.1", - "@dnd-kit/modifiers": "^9.0.0", - "@dnd-kit/sortable": "^10.0.0", - "@dnd-kit/utilities": "^3.2.2", - "@headlessui/react": "^2.2.8", - "@hookform/resolvers": "^5.2.2", - "@radix-ui/react-alert-dialog": "^1.1.15", - "@radix-ui/react-avatar": "^1.1.10", - "@radix-ui/react-checkbox": "^1.3.3", - "@radix-ui/react-dialog": "^1.1.15", - "@radix-ui/react-dropdown-menu": "^2.1.16", - "@radix-ui/react-icons": "^1.3.2", - "@radix-ui/react-label": "^2.1.7", - "@radix-ui/react-navigation-menu": "^1.2.14", - "@radix-ui/react-popover": "^1.1.15", - "@radix-ui/react-progress": "^1.1.7", - "@radix-ui/react-radio-group": "^1.3.8", - "@radix-ui/react-scroll-area": "^1.2.10", - "@radix-ui/react-select": "^2.2.6", - "@radix-ui/react-separator": "^1.1.7", - "@radix-ui/react-slider": "^1.3.6", - "@radix-ui/react-slot": "^1.2.3", - "@radix-ui/react-switch": "^1.2.6", - "@radix-ui/react-tabs": "^1.1.13", - "@radix-ui/react-toast": "^1.2.15", - "@radix-ui/react-toggle": "^1.1.10", - "@radix-ui/react-toggle-group": "^1.1.11", - "@radix-ui/react-tooltip": "^1.2.8", - "@radix-ui/themes": "^3.2.1", - "@shadcn/ui": "^0.0.4", - "@tabler/icons-react": "^3.34.1", - "@tanstack/react-query": "^5.87.1", - "@tanstack/react-table": "^8.21.3", - "@vitalets/google-translate-api": "^9.2.1", - "axios": "^1.7.9", - "chart.js": "^4.5.0", - "class-variance-authority": "^0.7.1", - "clsx": "^2.1.1", - "embla-carousel-react": "^8.6.0", - "formik": "^2.4.6", - "framer-motion": "^12.23.12", - "i18next": "^25.3.6", - "i18next-browser-languagedetector": "^8.2.0", - "i18next-http-backend": "^3.0.2", - "jalali-moment": "^3.3.11", - "js-cookie": "^3.0.5", - "jszip": "^3.10.1", - "leaflet": "^1.9.4", - "lodash": "^4.17.21", - "lucide-react": "^0.541.0", - "mapbox-gl": "^3.9.3", - "next": "^15.5.2", - "next-i18next": "^15.4.2", - "next-seo": "^6.8.0", - "next-sitemap": "^4.2.3", - "next-themes": "^0.4.6", - "node-fetch": "^3.3.2", - "openai": "^5.21.0", - "radix-ui": "^1.4.3", - "rc-rate": "^2.13.0", - "react": "^18.3.1", - "react-chartjs-2": "^5.3.0", - "react-confetti": "^6.4.0", - "react-dom": "^18.3.1", - "react-easy-crop": "^5.5.0", - "react-hook-form": "^7.65.0", - "react-hot-toast": "^2.5.1", - "react-i18next": "^15.6.1", - "react-icons": "^5.5.0", - "react-leaflet": "^4.2.1", - "react-map-gl": "^7.1.8", - "react-modal": "^3.16.3", - "react-multi-date-picker": "^4.5.2", - "react-otp-input": "^3.1.1", - "react-slick": "^0.31.0", - "react-use": "^17.6.0", - "recharts": "^2.15.4", - "sharp": "^0.34.5", - "slick-carousel": "^1.8.1", - "socket.io-client": "^4.8.1", - "sonner": "^2.0.7", - "swiper": "^11.2.2", - "tailwind-merge": "^3.3.1", - "tailwindcss-rtl": "^0.9.0", - "three": "^0.180.0", - "translate-google": "^1.5.0", - "uuid": "^11.1.0", - "vaul": "^1.1.2", - "yet-another-react-lightbox": "^3.25.0", - "yup": "^1.7.1", - "zod": "^3.25.76" - }, - "devDependencies": { - "@eslint/eslintrc": "^3", - "@ffmpeg/ffmpeg": "^0.12.10", - "@ffmpeg/util": "^0.12.1", - "@tailwindcss/postcss": "^4.2.4", - "@types/js-cookie": "^3.0.6", - "@types/leaflet": "^1.9.20", - "@types/lodash": "^4.17.20", - "@types/node": "^20", - "@types/react": "^19", - "@types/react-dom": "^19", - "@types/react-modal": "^3.16.3", - "@types/react-slick": "^0.23.13", - "autoprefixer": "^10.4.21", - "eslint": "^9", - "eslint-config-next": "15.1.5", - "postcss": "^8.5.14", - "tailwindcss": "^4.2.4", - "ts-node": "^10.9.2", - "tw-animate-css": "^1.3.8", - "typescript": "^5" - } -} diff --git a/public/modstagram-back/.eslintrc.json b/public/modstagram-back/.eslintrc.json deleted file mode 100644 index 20328b0..0000000 --- a/public/modstagram-back/.eslintrc.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "env": { - "commonjs": true, - "es2021": true, - "node": true - }, - "extends": "standard", - "parserOptions": { - "ecmaVersion": "latest" - }, - "rules": { - "indent": ["error", 2] - } -} diff --git a/public/modstagram-back/.gitignore b/public/modstagram-back/.gitignore deleted file mode 100644 index 65d3ddc..0000000 --- a/public/modstagram-back/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -node_modules/ -dist/ -.env -.vscode/ \ No newline at end of file diff --git a/public/modstagram-back/boot/index.js b/public/modstagram-back/boot/index.js deleted file mode 100644 index 1a0d11f..0000000 --- a/public/modstagram-back/boot/index.js +++ /dev/null @@ -1,2 +0,0 @@ -const startMongoDB = require('./mongo') -startMongoDB() diff --git a/public/modstagram-back/boot/mongo.js b/public/modstagram-back/boot/mongo.js deleted file mode 100644 index 2d4259a..0000000 --- a/public/modstagram-back/boot/mongo.js +++ /dev/null @@ -1,24 +0,0 @@ -// const mongoose = require('mongoose') -// const { MONGO_DBNAME, MONGO_HOST, MONGO_PORT } = process.env -// mongoose.connection.on('error', (error) => { -// console.log('mongodb connection failed! ', error.message) -// }) -// const startMongoDB = () => { -// mongoose.connect(`mongodb://${MONGO_HOST}:${MONGO_PORT}/${MONGO_DBNAME}`, { -// }) -// } -// module.exports = startMongoDB - -const mongoose = require('mongoose') -mongoose.connection.on('error', (error) => { - console.log('mongodb connection failed! ', error.message) -}) -mongoose.connection.on('open', function () { - console.log('Database Connected! ') -}) -const startMongoDB = () => { - mongoose.connect(process.env.DATABASE_URL, { - authSource: 'admin' - }) -} -module.exports = startMongoDB diff --git a/public/modstagram-back/controllers/application/academy/academyCategoryController.js b/public/modstagram-back/controllers/application/academy/academyCategoryController.js deleted file mode 100644 index 07bfec8..0000000 --- a/public/modstagram-back/controllers/application/academy/academyCategoryController.js +++ /dev/null @@ -1,74 +0,0 @@ -const AcademyCategoryModel = require('../../../models/AcademyCategoryModel'); -// GET all categories -exports.getAll = async (req, res) => { - try { - const categories = await AcademyCategoryModel.find({}).sort({ createdAt: -1 }); - res.status(200).json({ success: true, categories }); - } catch (error) { - res.status(500).json({ success: false, message: error.message }); - } -}; - -// CREATE category -exports.create = async (req, res) => { - try { - const { title, status } = req.body; - - if (!title) { - return res.status(400).json({ success: false, message: "title is required" }); - } - - const newCategory = new AcademyCategoryModel({ - title, - status: status ?? true, - }); - - await newCategory.save(); - - res.status(201).json({ success: true, category: newCategory }); - } catch (error) { - res.status(500).json({ success: false, message: error.message }); - } -}; - -// UPDATE category -exports.update = async (req, res) => { - try { - const { id } = req.params; - const { title, status } = req.body; - - const updated = await AcademyCategoryModel.findByIdAndUpdate( - id, - { title, status }, - { new: true, runValidators: true } - ); - - if (!updated) { - return res.status(404).json({ success: false, message: "category not found" }); - } - - res.status(200).json({ success: true, category: updated }); - } catch (error) { - res.status(500).json({ success: false, message: error.message }); - } -}; - -// DELETE -exports.remove = async (req, res) => { - try { - const { id } = req.params; - - const deleted = await AcademyCategoryModel.findByIdAndDelete(id); - - if (!deleted) { - return res.status(404).json({ success: false, message: "category not found" }); - } - - res.status(200).json({ - success: true, - message: 'category deleted successfully' - }); - } catch (error) { - res.status(500).json({ success: false, message: error.message }); - } -}; diff --git a/public/modstagram-back/controllers/application/academy/academyControllers.js b/public/modstagram-back/controllers/application/academy/academyControllers.js deleted file mode 100644 index d11b344..0000000 --- a/public/modstagram-back/controllers/application/academy/academyControllers.js +++ /dev/null @@ -1,4430 +0,0 @@ -const jwt = require("jsonwebtoken"); -const fs = require("fs-extra"); -const path = require("path"); -const jMoment = require("moment-jalaali"); -const AcademyContentModel = require("../../../models/AcademyContentModel"); -const AcademyModel = require("../../../models/AcademyModel"); -const AcademyPaymentModel = require("../../../models/AcademyPaymentModel"); -const CourseModel = require("../../../models/CourseModel"); -const CoursePaymentModel = require("../../../models/CoursePaymentModel"); -const UserModel = require("../../../models/UserModel"); -const PaymentModel = require("../../../models/PaymentModel"); -const { default: axios } = require("axios"); -const AcademyLikeModel = require("../../../models/AcademyLikeModel"); -const CourseComment = require("../../../models/CourseComentModel"); -const IsPaymentCourse = require("../../../models/IsPaymentCourseModel"); -const Tax = require("../../../models/TaxModel"); -const AcademyCategoryModel = require('../../../models/AcademyCategoryModel'); - -const onServerRestart = async () => { - const CoursePayment = await CoursePaymentModel.findOne({ - cuorse_type: "pro", - }); - if (!CoursePayment) { - const newCoursePayment = new CoursePaymentModel({ - price: "60000", - cuorse_type: "pro", - }); - await newCoursePayment.save(); - - return console.log("اشتراک پرو ساخته شد"); - } - - console.log("اشتراک پرو موجود هست"); - const tax = await Tax.findOne({ - type: "course", - }); - if (!tax) { - const newTax = new Tax({ - tax: 8, - type: "course", - }); - await newTax.save(); - - return console.log("تکس ساخته شد"); - } - - console.log(" تکس موجود هست"); -}; -onServerRestart(); - -const findAcademy = async (req, res, next) => { - try { - const token = req.header("Authorization").split(" ")[1]; - if (!token) return res.status(401).send("Access Denied"); - const decodedToken = jwt.verify(token, process.env.APP_SECRET); - const userId = decodedToken.id; - - const user = await UserModel.findById(userId); - if (!user) { - return res.status(422).json({ - error: true, - message: "کاربر یافت نشد", - }); - } - const academy = await AcademyModel.findOne({ userId: userId }); - if (!academy) { - const newAcademy = new AcademyModel({ - userId: userId, - }); - await newAcademy.save(); - - return res.status(200).json({ - academy: newAcademy, - }); - } - - res.status(200).json({ - academy: academy, - }); - } catch (error) { - // در صورت بروز خطا، ارسال پیام خطا به کاربر - console.error("Error:", error); - res.status(500).json({ message: "err in creat" }); - } -}; -const findAcademyById = async (req, res, next) => { - try { - const { _id } = req.body; - - const academy = await AcademyModel.findById(_id); - if (!academy) { - res.status(500).json({ - academy: "اکادمی موحود نیست", - }); - } - - res.status(200).json({ - academy: academy, - }); - } catch (error) { - // در صورت بروز خطا، ارسال پیام خطا به کاربر - console.error("Error:", error); - res.status(500).json({ message: "err in creat" }); - } -}; -const academyProfile = async (req, res, next) => { - try { - const token = req.header("Authorization").split(" ")[1]; - if (!token) return res.status(401).send("Access Denied"); - const decodedToken = jwt.verify(token, process.env.APP_SECRET); - const userId = decodedToken.id; - - const user = await UserModel.findById(userId); - if (!user) { - return res.status(422).json({ - error: true, - message: "کاربر یافت نشد", - }); - } - const academy = await AcademyModel.findOne({ userId: userId }); - if (!academy) { - return res.status(200).json({ - message: "اکادمی پیدا نشد", - }); - } - - const { profile_image } = req.files; - const { name, sheba, bio, tag } = req.body; - - if (!profile_image) { - return res.status(422).json({ - error: true, - message: "اطلاعات ارسالی اشتباه است", - }); - } - - const uploadDir = path.join(__dirname, "../../../../storage/profiles"); - if (!fs.existsSync(uploadDir)) { - fs.mkdirSync(uploadDir, { recursive: true }); - } - - const uniqueFileName = `${name}-${Date.now()}${path.extname( - profile_image.name - )}`; - const filePath = path.join(uploadDir, uniqueFileName); - - await fs.move(profile_image.path, filePath); - - academy.academy_image = `/profiles/${uniqueFileName}`; - academy.academy_name = name; - academy.sheba = sheba; - academy.bio = bio; - academy.tag = tag; - await academy.save(); - - res.status(200).json({ - message: "ثبت شد", - }); - } catch (error) { - // در صورت بروز خطا، ارسال پیام خطا به کاربر - console.error("Error:", error); - res.status(500).json({ message: "err in update" }); - } -}; - -const creatCourse = async (req, res, next) => { - try { - const token = req.header("Authorization").split(" ")[1]; - if (!token) return res.status(401).send("Access Denied"); - const decodedToken = jwt.verify(token, process.env.APP_SECRET); - const userId = decodedToken.id; - - const user = await UserModel.findById(userId); - if (!user) { - return res.status(422).json({ - error: true, - message: "کاربر یافت نشد", - }); - } - - const academy = await AcademyModel.findOne({ userId: userId }); - if (!academy) { - return res.status(200).json({ - message: "اکادمی پیدا نشد", - }); - } - const { - price, - cuorse_name, - category, - offer, - caption, - course_time, - number_of_course_content, - teacher_number, - teacher_name, - } = req.body; - - const { course_image } = req.files; - - if (!course_image) { - return res.status(422).json({ - error: true, - message: "اطلاعات ارسالی اشتباه است", - }); - } - - const uploadDir = path.join(__dirname, "../../../../storage/profiles"); - if (!fs.existsSync(uploadDir)) { - fs.mkdirSync(uploadDir, { recursive: true }); - } - - const uniqueFileName = `${cuorse_name}-${Date.now()}${path.extname( - course_image.name - )}`; - const filePath = path.join(uploadDir, uniqueFileName); - - await fs.move(course_image.path, filePath); - - // ✅ ایجاد رکورد جدید - const newAcademy = new CourseModel({ - course_image: `/profiles/${uniqueFileName}`, - price, - cuorse_name, - category, - offer, - teacher_name, - academyId: academy._id, - caption, - course_time, - number_of_course_content, - teacher_number, - }); - - await newAcademy.save(); - - res.status(200).json({ - message: "ثبت شد", - }); - } catch (error) { - // در صورت بروز خطا، ارسال پیام خطا به کاربر - console.error("Error:", error); - res.status(500).json({ message: "err in update" }); - } -}; - -const updateCourse = async (req, res, next) => { - try { - const token = req.header("Authorization")?.split(" ")[1]; - if (!token) return res.status(401).send("Access Denied"); - - const decodedToken = jwt.verify(token, process.env.APP_SECRET); - const userId = decodedToken.id; - - const { - price, - cuorse_name, - category, - offer, - courseId, - teacher_name, - caption, - course_time, - number_of_course_content, - teacher_number, - } = req.body; - - // اعتبارسنجی courseId - if (!courseId) { - return res.status(422).json({ - error: true, - message: "آیدی دوره الزامی است", - }); - } - - const user = await UserModel.findById(userId); - if (!user) { - return res.status(422).json({ - error: true, - message: "کاربر یافت نشد", - }); - } - - const course = await CourseModel.findById(courseId); - if (!course) { - return res.status(422).json({ - error: true, - message: "پکیجی یافت نشد", - }); - } - - // ========== آپلود عکس جدید (اختیاری) ========== - const { course_image } = req.files || {}; - - if (course_image) { - // فقط اگه عکس جدید آپلود شده بود، آپلود کن - const uploadDir = path.join(__dirname, "../../../../storage/profiles"); - if (!fs.existsSync(uploadDir)) { - fs.mkdirSync(uploadDir, { recursive: true }); - } - - // استفاده از id به جای نام دوره برای نام فایل - const safeFileName = `course-${courseId}-${Date.now()}${path.extname( - course_image.name - )}`; - const filePath = path.join(uploadDir, safeFileName); - - await fs.move(course_image.path, filePath); - course.course_image = `/profiles/${safeFileName}`; - } - - // ========== به روز رسانی فیلدها (فقط فیلدهایی که ارسال شده) ========== - if (price !== undefined) course.price = price; - if (cuorse_name !== undefined) course.cuorse_name = cuorse_name; - if (category !== undefined) course.category = category; - if (offer !== undefined) course.offer = offer; - if (caption !== undefined) course.caption = caption; - if (course_time !== undefined) course.course_time = course_time; - if (number_of_course_content !== undefined) - course.number_of_course_content = number_of_course_content; - if (teacher_number !== undefined) course.teacher_number = teacher_number; - if (teacher_name !== undefined) course.teacher_name = teacher_name; - - await course.save(); - - res.status(200).json({ - success: true, - message: "دوره با موفقیت به روز رسانی شد", - data: { - course: course, - }, - }); - } catch (error) { - console.error("Error in updateCourse:", error); - res.status(500).json({ - success: false, - message: "خطا در به روز رسانی دوره", - error: error.message, - }); - } -}; -const deleteCourse = async (req, res, next) => { - try { - const token = req.header("Authorization").split(" ")[1]; - if (!token) return res.status(401).send("Access Denied"); - const decodedToken = jwt.verify(token, process.env.APP_SECRET); - const userId = decodedToken.id; - const { courseId } = req.body; - - const user = await UserModel.findById(userId); - if (!user) { - return res.status(422).json({ - error: true, - message: "کاربر یافت نشد", - }); - } - const course = await CourseModel.findById(courseId); - if (!course) { - return res.status(422).json({ - error: true, - message: "پکیجی یافت نشد", - }); - } - - course.status = "reject"; - await course.save(); - - res.status(200).json({ - message: "ثبت شد", - }); - } catch (error) { - // در صورت بروز خطا، ارسال پیام خطا به کاربر - console.error("Error:", error); - res.status(500).json({ message: "err in update" }); - } -}; -const getCourse = async (req, res, next) => { - try { - const token = req.header("Authorization")?.split(" ")[1]; - if (!token) return res.status(401).send("Access Denied"); - - const decodedToken = jwt.verify(token, process.env.APP_SECRET); - const userId = decodedToken.id; - - // گرفتن پارامترهای صفحه‌بندی - const page = parseInt(req.query.page) || 1; - const limit = parseInt(req.query.limit) || 10; - const skip = (page - 1) * limit; - - const user = await UserModel.findById(userId); - if (!user) { - return res.status(422).json({ - error: true, - message: "کاربر یافت نشد", - }); - } - - const academy = await AcademyModel.findOne({ userId: userId }); - if (!academy) { - return res.status(404).json({ - success: false, - message: "آکادمی پیدا نشد", - }); - } - - // ✅ شرط جستجو - فقط دوره‌های تایید شده - const query = { - academyId: academy._id, - status: "accept", - }; - - // دریافت تعداد کل دوره‌های تایید شده - const totalCourses = await CourseModel.countDocuments(query); - - // دریافت دوره‌های تایید شده با صفحه‌بندی - const courses = await CourseModel.find(query) - .sort({ createdAt: -1 }) - .skip(skip) - .limit(limit); - - // ✅ اگر دوره‌ای وجود نداشت، خطا نده، بلکه آرایه خالی برگردون - if (!courses || courses.length === 0) { - return res.status(200).json({ - success: true, - message: "هیچ دوره تایید شده‌ای یافت نشد", - data: { - courses: [], - pagination: { - currentPage: page, - totalPages: 0, - totalItems: 0, - itemsPerPage: limit, - hasNextPage: false, - hasPrevPage: false, - nextPage: null, - prevPage: null, - }, - }, - }); - } - - // محاسبات صفحه‌بندی - const totalPages = Math.ceil(totalCourses / limit); - const hasNextPage = page < totalPages; - const hasPrevPage = page > 1; - - res.status(200).json({ - success: true, - message: "لیست پکیج‌ها با موفقیت دریافت شد", - data: { - courses: courses, - pagination: { - currentPage: page, - totalPages: totalPages, - totalItems: totalCourses, - itemsPerPage: limit, - hasNextPage: hasNextPage, - hasPrevPage: hasPrevPage, - nextPage: hasNextPage ? page + 1 : null, - prevPage: hasPrevPage ? page - 1 : null, - }, - }, - }); - } catch (error) { - console.error("Error:", error); - res.status(500).json({ - success: false, - message: "خطا در دریافت پکیج‌ها", - error: error.message, - }); - } -}; - -const getCourses = async (req, res, next) => { - try { - // ========== 3. دریافت پارامترهای صفحه‌بندی ========== - const page = parseInt(req.query.page) || 1; - const limit = parseInt(req.query.limit) || 10; - const skip = (page - 1) * limit; - - // ========== 4. دریافت پارامترهای جستجو ========== - const search = req.query.search || ""; - const category = req.query.category || ""; - const minPrice = req.query.minPrice ? parseInt(req.query.minPrice) : 0; - const maxPrice = req.query.maxPrice - ? parseInt(req.query.maxPrice) - : 100000000; - const hasOffer = req.query.hasOffer === "true"; // تخفیف دار - const teacherName = req.query.teacherName || ""; - const type = req.query.type || ""; // normal, pro, legend - const status = req.query.status || "all"; // pending, accept, reject - const sortBy = req.query.sortBy || "createdAt"; - const sortOrder = req.query.sortOrder === "asc" ? 1 : -1; - const _id = req.query._id || ""; - // ========== 5. ساخت شرط جستجو (Query) ========== - let query = {}; - - // جستجو در نام دوره و کپشن - if (search) { - query.$or = [ - { cuorse_name: { $regex: search, $options: "i" } }, - { caption: { $regex: search, $options: "i" } }, - { teacher_name: { $regex: search, $options: "i" } }, - ]; - } - - // فیلتر بر اساس دسته بندی - if (category) { - query.category = category; - } - if (_id) { - query._id = _id; - } - // فیلتر بر اساس محدوده قیمت (تبدیل به عدد برای مقایسه) - if (minPrice > 0 || maxPrice < 100000000) { - query.price = { - $gte: minPrice.toString(), - $lte: maxPrice.toString(), - }; - } - - // فیلتر بر اساس تخفیف دار (offer وجود داشته باشد و از 0 بیشتر باشد) - if (hasOffer) { - query.offer = { $exists: true, $ne: "0", $ne: "" }; - } - - // فیلتر بر اساس نام مدرس - if (teacherName) { - query.teacher_name = { $regex: teacherName, $options: "i" }; - } - - // فیلتر بر اساس نوع دوره - if (type) { - query.type = type; - } - - // فیلتر بر اساس وضعیت - if (status !== "all") { - query.status = status; - } - - // ========== 6. دریافت آمار و اطلاعات ========== - // تعداد کل پکیج‌ها (بدون صفحه‌بندی) - const totalCourses = await CourseModel.countDocuments(query); - - // مجموع قیمت‌ها (تبدیل به عدد برای محاسبه) - const priceStats = await CourseModel.aggregate([ - { $match: query }, - { - $group: { - _id: null, - total: { $sum: { $toDouble: "$price" } }, - avg: { $avg: { $toDouble: "$price" } }, - min: { $min: { $toDouble: "$price" } }, - max: { $max: { $toDouble: "$price" } }, - }, - }, - ]); - - // تعداد دوره‌های با تخفیف - const offeredCourses = await CourseModel.countDocuments({ - ...query, - offer: { $exists: true, $ne: "0", $ne: "" }, - }); - - // تعداد دوره‌ها بر اساس نوع - const typeStats = await CourseModel.aggregate([ - { $match: query }, - { - $group: { - _id: "$type", - count: { $sum: 1 }, - }, - }, - ]); - - // ========== 7. دریافت پکیج‌ها با صفحه‌بندی ========== - const courses = await CourseModel.find(query) - .populate("user_id", "name email") // اطلاعات کاربر سازنده - .populate("likes", "name") // اطلاعات لایک‌ها - .sort({ [sortBy]: sortOrder }) - .skip(skip) - .limit(limit) - .lean(); - - // پردازش داده‌ها برای خروجی - const processedCourses = courses.map((course) => ({ - ...course, - priceNumber: parseInt(course.price) || 0, - offerNumber: parseInt(course.offer) || 0, - finalPrice: course.offer - ? (parseInt(course.price) * (100 - parseInt(course.offer))) / 100 - : parseInt(course.price), - likesCount: course.likes?.length || 0, - })); - - // ========== 8. محاسبات صفحه‌بندی ========== - const totalPages = Math.ceil(totalCourses / limit); - const hasNextPage = page < totalPages; - const hasPrevPage = page > 1; - - // محاسبه محدوده نمایش - const startItem = totalCourses === 0 ? 0 : (page - 1) * limit + 1; - const endItem = Math.min(page * limit, totalCourses); - - // ========== 9. ارسال پاسخ ========== - res.status(200).json({ - success: true, - message: "لیست پکیج‌ها با موفقیت دریافت شد", - data: { - courses: processedCourses, - stats: { - totalCourses, - offeredCourses, - averagePrice: Math.round(priceStats[0]?.avg || 0), - minPrice: priceStats[0]?.min || 0, - maxPrice: priceStats[0]?.max || 0, - totalPrice: priceStats[0]?.total || 0, - typeStats: typeStats, - }, - pagination: { - currentPage: page, - totalPages: totalPages, - totalItems: totalCourses, - itemsPerPage: limit, - hasNextPage: hasNextPage, - hasPrevPage: hasPrevPage, - nextPage: hasNextPage ? page + 1 : null, - prevPage: hasPrevPage ? page - 1 : null, - startItem: startItem, - endItem: endItem, - }, - filters: { - search: search, - category: category, - minPrice: minPrice, - maxPrice: maxPrice, - hasOffer: hasOffer, - teacherName: teacherName, - type: type, - sortBy: sortBy, - sortOrder: sortOrder === 1 ? "asc" : "desc", - status: status, - }, - }, - }); - } catch (error) { - console.error("Error in getCourses:", error); - res.status(500).json({ - success: false, - message: "خطا در دریافت پکیج‌ها", - error: error.message, - }); - } -}; - -const proPayment = async (req, res, next) => { - try { - const token = req.header("Authorization")?.split(" ")[1]; - if (!token) return res.status(401).send("Access Denied"); - - const decodedToken = jwt.verify(token, process.env.APP_SECRET); - const userId = decodedToken.id; - const { courseId } = req.body; - - // ========== 1. بررسی وجود CoursePayment ========== - const coursePayment = await CoursePaymentModel.findOne({ - cuorse_type: "pro", - }); - - if (!coursePayment) { - return res.status(404).json({ - error: true, - message: "قیمت‌گذاری برای نوع پرو یافت نشد", - }); - } - - const price = coursePayment.price; - - // ========== 2. اعتبارسنجی قیمت ========== - if (!price || isNaN(Number(price)) || Number(price) <= 0) { - return res.status(422).json({ - error: true, - message: "مبلغ نامعتبر است", - }); - } - - // ========== 3. بررسی وجود دوره ========== - const course = await CourseModel.findById(courseId); - if (!course) { - return res.status(404).json({ - error: true, - message: "پکیجی یافت نشد", - }); - } - - // ========== 4. محاسبه مبلغ ========== - const amount = Number(price) * 10; - - // مبلغ باید حداقل 1000 تومان باشد (طبق قوانین زرین‌پال) - if (amount < 1000) { - return res.status(422).json({ - error: true, - message: "مبلغ باید حداقل 1000 تومان باشد", - }); - } - - const callbackUrl = `https://api.modstagram.com/api/v1/academy/academy/course/pro?courseId=${courseId}&userId=${userId}`; - - // ========== 5. درخواست به زرین‌پال ========== - const zarinpalRes = await axios.post( - "https://api.zarinpal.com/pg/v4/payment/request.json", - { - merchant_id: - process.env.ZARINPAL_MERCHANT_ID || - "c7c41e8a-918f-4741-bcd5-58f3bc51db73", - amount: Math.round(amount), // حتماً عدد صحیح باشد - description: `خرید اشتراک پرو برای ${course.cuorse_name}`, - callback_url: callbackUrl, - metadata: { - user_id: userId, - course_id: courseId, - }, - }, - { - headers: { "Content-Type": "application/json" }, - timeout: 10000, // 10 ثانیه تایم‌اوت - } - ); - - const result = zarinpalRes.data; - - // ========== 6. بررسی پاسخ زرین‌پال ========== - if (result.data && result.data.code === 100) { - // ذخیره اطلاعات پرداخت در دیتابیس (اختیاری) - await PaymentModel.create({ - authority: result.data.authority, - amount: amount, - user_id: userId, - course_id: courseId, - status: "pending", - type: "pro", - createdAt: new Date(), - }); - - return res.status(200).json({ - success: true, - authority: result.data.authority, - paymentUrl: `https://www.zarinpal.com/pg/StartPay/${result.data.authority}`, - }); - } - - // خطای زرین‌پال - console.error("ZarinPal error:", result); - return res.status(422).json({ - error: true, - message: result.errors?.message || "خطا در ارتباط با درگاه پرداخت", - details: result.errors, - }); - } catch (error) { - console.error( - "Error in proPayment:", - error.response?.data || error.message - ); - res.status(500).json({ - error: true, - message: "خطا در پردازش پرداخت", - details: error.response?.data || error.message, - }); - } -}; - -const handleCoursePaymentCallback = async (req, res) => { - res.setHeader("Access-Control-Allow-Origin", "*"); - res.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS"); - res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization"); - - try { - const { Authority, Status, userId, courseId } = req.query; - - if (Status !== "OK") { - return res.redirect(`${process.env.APP_SITE}/offer/payment/failed`); - } - - // ========== 1. پیدا کردن قیمت ========== - const coursePayment = await CoursePaymentModel.findOne({ - cuorse_type: "pro", - }); - - if (!coursePayment) { - return res.redirect( - `${process.env.APP_SITE}/offer/payment/failed?message=price_not_found` - ); - } - - const price = coursePayment.price; - const amount = Number(price) * 10; - - // ========== 2. تایید پرداخت با زرین‌پال ========== - const verify = await axios.post( - "https://api.zarinpal.com/pg/v4/payment/verify.json", - { - merchant_id: - process.env.ZARINPAL_MERCHANT_ID || - "c7c41e8a-918f-4741-bcd5-58f3bc51db73", - authority: Authority, - amount: Math.round(amount), - }, - { - headers: { "Content-Type": "application/json" }, - timeout: 10000, - } - ); - - const data = verify.data.data; - - // ========== 3. بررسی نتیجه تایید ========== - if (data.code === 100) { - // ثبت پرداخت موفق - await PaymentModel.create({ - amount: amount / 10, - status: "successful", - authority: Authority, - ref_id: data.ref_id, - user_id: userId, - course_id: courseId, - type: "course", - verifiedAt: new Date(), - }); - - // به روز رسانی نوع دوره به pro - const course = await CourseModel.findById(courseId); - if (course) { - course.type = "pro"; - await course.save(); - } - - // به روز رسانی وضعیت کاربر (اشتراک پرو) - await UserModel.findByIdAndUpdate(userId, { - $set: { - "proSubscription.active": true, - "proSubscription.courseId": courseId, - "proSubscription.startDate": new Date(), - "proSubscription.purchaseDate": new Date(), - }, - }); - - return res.redirect( - `${process.env.APP_SITE}/settings/academy/course?payment=success` - ); - } - - // پرداخت ناموفق - return res.redirect( - `${process.env.APP_SITE}/offer/payment/failed?code=${data.code}` - ); - } catch (err) { - console.error("Error in handleCoursePaymentCallback:", err); - return res.redirect( - `${process.env.APP_SITE}/offer/payment/failed?message=verification_error` - ); - } -}; - -const creatCourseVideo = async (req, res, next) => { - console.log("=== New request received ==="); - console.log("Headers:", req.headers); - console.log("Body:", req.body); - console.log("File:", req.file); - - try { - const token = req.header("Authorization")?.split(" ")[1]; - if (!token) return res.status(401).send("Access Denied"); - const decodedToken = jwt.verify(token, process.env.APP_SECRET); - const userId = decodedToken.id; - - const { courseId, is_free, file_name } = req.body; - const videoFile = req.file; - - if (!videoFile) { - return res.status(422).json({ - error: true, - message: "فایل ویدیو ارسال نشده است", - }); - } - - if (!courseId) { - return res.status(422).json({ - error: true, - message: "شناسه دوره الزامی است", - }); - } - - // مسیر ذخیره‌سازی نهایی (مشابه سیستم پست‌ها) - const finalVideoDir = path.join( - __dirname, - "../../../storage/courses/videos" - ); - const safeFileName = `course-${courseId}-${Date.now()}${path.extname( - videoFile.originalname - )}`; - const filePath = path.join(finalVideoDir, safeFileName); - - // انتقال فایل از محل موقت به محل نهایی - await fs.rename(videoFile.path, filePath); - - // ایجاد رکورد جدید در دیتابیس - const newAcademyContent = new AcademyContentModel({ - course_video: `/storage/posts/videos/${safeFileName}`, - type: "video", - is_free: is_free === "true" || is_free === true, - courseId, - file_name: file_name || videoFile.originalname, - }); - - await newAcademyContent.save(); - - const course = await CourseModel.findById(courseId); - if (!course) { - return res.status(404).json({ - success: false, - message: "پکیج پیدا نشد", - }); - } - - course.number_of_course_content = `${ - Number(course.number_of_course_content) + 1 - }`; - await course.save(); - - res.status(200).json({ - success: true, - message: "ویدیو با موفقیت ثبت شد", - data: newAcademyContent, - }); - } catch (error) { - console.error("Error in creatCourseVideo:", error); - res.status(500).json({ - success: false, - message: "خطا در ثبت ویدیو", - error: error.message, - }); - } -}; - -const creatCourseVideoBase64 = async (req, res, next) => { - console.log("=== Base64 Video Upload ==="); - console.log("Body:", Object.keys(req.body)); - - try { - const token = req.header("Authorization")?.split(" ")[1]; - if (!token) return res.status(401).send("Access Denied"); - const decodedToken = jwt.verify(token, process.env.APP_SECRET); - const userId = decodedToken.id; - - const { courseId, is_free, file_name, video_base64, mime_type } = req.body; - - // اعتبارسنجی - if (!video_base64) { - return res.status(422).json({ - error: true, - message: "فایل ویدیو ارسال نشده است", - }); - } - - if (!courseId) { - return res.status(422).json({ - error: true, - message: "شناسه دوره الزامی است", - }); - } - - // تبدیل Base64 به بافر - const base64Data = video_base64.split(",")[1] || video_base64; - const buffer = Buffer.from(base64Data, "base64"); - - console.log("Buffer size:", buffer.length, "bytes"); - - // ایجاد دایرکتوری اگر وجود ندارد - const finalVideoDir = path.join( - process.cwd(), - "storage", - "courses", - "videos" - ); - if (!fs.existsSync(finalVideoDir)) { - fs.mkdirSync(finalVideoDir, { recursive: true }); - } - - // تعیین پسوند فایل از mime_type - let extension = ".mp4"; - if (mime_type === "video/mp4") extension = ".mp4"; - else if (mime_type === "video/quicktime") extension = ".mov"; - else if (mime_type === "video/x-msvideo") extension = ".avi"; - else if (mime_type === "video/webm") extension = ".webm"; - - const safeFileName = `course-${courseId}-${Date.now()}${extension}`; - const filePath = path.join(finalVideoDir, safeFileName); - - // ذخیره فایل - await fs.writeFileSync(filePath, buffer); - - console.log("File saved:", filePath); - - // ایجاد رکورد در دیتابیس - const newAcademyContent = new AcademyContentModel({ - course_video: `/storage/courses/videos/${safeFileName}`, - type: "video", - is_free: is_free === "true" || is_free === true, - courseId, - file_name: file_name, - }); - - await newAcademyContent.save(); - - // به روز رسانی تعداد محتواهای دوره - const course = await CourseModel.findById(courseId); - if (course) { - course.number_of_course_content = `${ - Number(course.number_of_course_content) + 1 - }`; - await course.save(); - } - - res.status(200).json({ - success: true, - message: "ویدیو با موفقیت ثبت شد", - data: newAcademyContent, - }); - } catch (error) { - console.error("Error in creatCourseVideoBase64:", error); - res.status(500).json({ - success: false, - message: "خطا در ثبت ویدیو", - error: error.message, - }); - } -}; - -const getCourseContent = async (req, res, next) => { - try { - // ✅ اصلاح: دریافت courseId از query یا params - const courseId = req.query.courseId || req.params.courseId; - - // اعتبارسنجی courseId - if (!courseId) { - return res.status(422).json({ - error: true, - message: "شناسه دوره الزامی است", - }); - } - - // گرفتن پارامترهای صفحه‌بندی - const page = parseInt(req.query.page) || 1; - const limit = parseInt(req.query.limit) || 10; - const skip = (page - 1) * limit; - - const academy = await CourseModel.findById(courseId); - if (!academy) { - return res.status(404).json({ - success: false, - message: "پکیج پیدا نشد", - }); - } - - // ✅ شرط جستجو - فقط دوره‌های تایید شده - const query = { - courseId: academy._id, - status: "accept", - }; - - // دریافت تعداد کل دوره‌های تایید شده - const totalCourses = await AcademyContentModel.countDocuments(query); - - // دریافت دوره‌های تایید شده با صفحه‌بندی - const courses = await AcademyContentModel.find(query) - .skip(skip) - .limit(limit); - - // ✅ اگر دوره‌ای وجود نداشت، خطا نده، بلکه آرایه خالی برگردون - if (!courses || courses.length === 0) { - return res.status(200).json({ - success: true, - message: "هیچ محتوایی یافت نشد", - data: { - courses: [], - pagination: { - currentPage: page, - totalPages: 0, - totalItems: 0, - itemsPerPage: limit, - hasNextPage: false, - hasPrevPage: false, - }, - }, - }); - } - - // محاسبات صفحه‌بندی - const totalPages = Math.ceil(totalCourses / limit); - const hasNextPage = page < totalPages; - const hasPrevPage = page > 1; - - res.status(200).json({ - success: true, - message: "لیست محتواها با موفقیت دریافت شد", - data: { - courses: courses, - pagination: { - currentPage: page, - totalPages: totalPages, - totalItems: totalCourses, - itemsPerPage: limit, - hasNextPage: hasNextPage, - hasPrevPage: hasPrevPage, - nextPage: hasNextPage ? page + 1 : null, - prevPage: hasPrevPage ? page - 1 : null, - }, - }, - }); - } catch (error) { - console.error("Error in getCourseContent:", error); - res.status(500).json({ - success: false, - message: "خطا در دریافت محتواها", - error: error.message, - }); - } -}; -// لایک کردن محتوا -const likeCourseContent = async (req, res, next) => { - try { - const token = req.header("Authorization")?.split(" ")[1]; - if (!token) return res.status(401).send("Access Denied"); - - const decodedToken = jwt.verify(token, process.env.APP_SECRET); - const userId = decodedToken.id; - - if (!userId) { - return res.status(422).json({ - error: true, - message: "برای لایک کردن وارد حساب کاربری خود شوید", - }); - } - - const { courseId } = req.body; - - // بررسی وجود دوره - const course = await CourseModel.findById(courseId); - if (!course) { - return res.status(404).json({ - success: false, - message: "پکیج پیدا نشد", - }); - } - - // بررسی اینکه آیا قبلاً لایک کرده است - const existingLike = await AcademyLikeModel.findOne({ - user_id: userId, - course_id: courseId, - }); - - if (existingLike) { - return res.status(400).json({ - success: false, - message: "شما قبلاً این دوره را لایک کرده‌اید", - }); - } - - // افزایش تعداد لایک‌های دوره - course.likes = (course.likes || 0) + 1; - await course.save(); - - // ایجاد رکورد لایک - await AcademyLikeModel.create({ - user_id: userId, - course_id: courseId, - createdAt: new Date(), - }); - - res.status(200).json({ - success: true, - message: "دوره با موفقیت لایک شد", - isLiked: true, - likesCount: course.likes, - }); - } catch (error) { - console.error("Error in likeCourseContent:", error); - res.status(500).json({ - success: false, - message: "خطا در لایک کردن محتوا", - error: error.message, - }); - } -}; - -// دیسلایک کردن محتوا (حذف لایک) -const dontLikeCourseContent = async (req, res, next) => { - try { - const token = req.header("Authorization")?.split(" ")[1]; - if (!token) return res.status(401).send("Access Denied"); - - const decodedToken = jwt.verify(token, process.env.APP_SECRET); - const userId = decodedToken.id; - - const { courseId } = req.body; - - // بررسی وجود دوره - const course = await CourseModel.findById(courseId); - if (!course) { - return res.status(404).json({ - success: false, - message: "پکیج پیدا نشد", - }); - } - - // پیدا کردن و حذف لایک - const deletedLike = await AcademyLikeModel.findOneAndDelete({ - user_id: userId, - course_id: courseId, - }); - - if (!deletedLike) { - return res.status(404).json({ - success: false, - message: "شما این دوره را لایک نکرده‌اید", - }); - } - - // کاهش تعداد لایک‌های دوره - course.likes = Math.max((course.likes || 0) - 1, 0); // جلوگیری از منفی شدن - await course.save(); - - res.status(200).json({ - success: true, - message: "لایک دوره با موفقیت حذف شد", - isLiked: false, - likesCount: course.likes, - }); - } catch (error) { - console.error("Error in dontLikeCourseContent:", error); - res.status(500).json({ - success: false, - message: "خطا در حذف لایک محتوا", - error: error.message, - }); - } -}; - -// بررسی وضعیت لایک (آیا کاربر لایک کرده است یا نه) -const isLikeCourseContent = async (req, res, next) => { - try { - const token = req.header("Authorization")?.split(" ")[1]; - if (!token) return res.status(401).send("Access Denied"); - - const decodedToken = jwt.verify(token, process.env.APP_SECRET); - const userId = decodedToken.id; - - const { courseId } = req.body; - - // پیدا کردن لایک - const academyLike = await AcademyLikeModel.findOne({ - user_id: userId, - course_id: courseId, - }); - - res.status(200).json({ - success: true, - isLiked: !!academyLike, // تبدیل به boolean - }); - } catch (error) { - console.error("Error in isLikeCourseContent:", error); - res.status(500).json({ - success: false, - message: "خطا در بررسی وضعیت لایک", - error: error.message, - }); - } -}; - -// دریافت تعداد لایک‌های یک دوره -const getCourseLikesCount = async (req, res, next) => { - try { - const { courseId } = req.params; - - const course = await CourseModel.findById(courseId); - if (!course) { - return res.status(404).json({ - success: false, - message: "دوره پیدا نشد", - }); - } - - const likesCount = await AcademyLikeModel.countDocuments({ - course_id: courseId, - }); - - res.status(200).json({ - success: true, - likesCount: likesCount, - courseLikes: course.likes || 0, - }); - } catch (error) { - console.error("Error in getCourseLikesCount:", error); - res.status(500).json({ - success: false, - message: "خطا در دریافت تعداد لایک‌ها", - error: error.message, - }); - } -}; - -// دریافت همه دوره‌هایی که کاربر لایک کرده است -const getUserLikedCourses = async (req, res, next) => { - try { - const token = req.header("Authorization")?.split(" ")[1]; - if (!token) return res.status(401).send("Access Denied"); - - const decodedToken = jwt.verify(token, process.env.APP_SECRET); - const userId = decodedToken.id; - - const page = parseInt(req.query.page) || 1; - const limit = parseInt(req.query.limit) || 10; - const skip = (page - 1) * limit; - - const likes = await AcademyLikeModel.find({ user_id: userId }) - .populate("course_id") - .sort({ createdAt: -1 }) - .skip(skip) - .limit(limit); - - const total = await AcademyLikeModel.countDocuments({ user_id: userId }); - - res.status(200).json({ - success: true, - data: likes, - pagination: { - currentPage: page, - totalPages: Math.ceil(total / limit), - totalItems: total, - itemsPerPage: limit, - }, - }); - } catch (error) { - console.error("Error in getUserLikedCourses:", error); - res.status(500).json({ - success: false, - message: "خطا در دریافت دوره‌های لایک شده", - error: error.message, - }); - } -}; - -// ==================== ساخت کامنت جدید ==================== -const createComment = async (req, res) => { - try { - const token = req.header("Authorization")?.split(" ")[1]; - if (!token) - return res.status(401).json({ error: true, message: "Access Denied" }); - - const decodedToken = jwt.verify(token, process.env.APP_SECRET); - const userId = decodedToken.id; - - const { course_id, comment, rate } = req.body; - - // اعتبارسنجی - if (!course_id || !comment) { - return res.status(422).json({ - error: true, - message: "شناسه دوره و متن کامنت الزامی است", - }); - } - - // بررسی وجود دوره - const course = await CourseModel.findById(course_id); - if (!course) { - return res.status(404).json({ - error: true, - message: "دوره پیدا نشد", - }); - } - - // ایجاد کامنت جدید - const newComment = await CourseComment.create({ - user_id: userId, - course_id: course_id, - comment: comment, - rate: rate || 0, - status: "accepted", // با توجه به مدل شما که default: 'accepted' است - }); - - // populate کردن اطلاعات کاربر - const populatedComment = await CourseComment.findById( - newComment._id - ).populate("user_id", "name username"); - - res.status(201).json({ - success: true, - message: "کامنت با موفقیت ثبت شد", - data: populatedComment, - }); - } catch (error) { - console.error("Error in createComment:", error); - res.status(500).json({ - success: false, - message: "خطا در ثبت کامنت", - error: error.message, - }); - } -}; - -// ==================== دریافت تعداد کل کامنت‌های یک دوره ==================== -const getTotalCommentsCount = async (req, res) => { - try { - const { courseId } = req.params; - const { status } = req.query; // اختیاری: فقط کامنت‌های با وضعیت خاص - - const query = { course_id: courseId }; - if (status) { - query.status = status; - } - - const totalComments = await CourseComment.countDocuments(query); - - // محاسبه میانگین امتیازات - const averageRate = await CourseComment.aggregate([ - { $match: { course_id: courseId, status: "accepted" } }, - { $group: { _id: null, avgRate: { $avg: "$rate" } } }, - ]); - - res.status(200).json({ - success: true, - data: { - totalComments: totalComments, - averageRate: averageRate[0]?.avgRate || 0, - courseId: courseId, - }, - }); - } catch (error) { - console.error("Error in getTotalCommentsCount:", error); - res.status(500).json({ - success: false, - message: "خطا در دریافت تعداد کامنت‌ها", - error: error.message, - }); - } -}; - -// ==================== دریافت کامنت‌ها با فیلترهای مختلف ==================== -const getCourseComments = async (req, res) => { - try { - const { courseId } = req.params; - const { - page = 1, - limit = 10, - status = "accepted", // 'accepted', 'pending', 'rejected', 'all' - minRate, - maxRate, - sortBy = "createdAt", - sortOrder = "desc", - userId, // اختیاری: کامنت‌های یک کاربر خاص - } = req.query; - - // ساخت شرط جستجو - const query = { course_id: courseId }; - - // فیلتر بر اساس وضعیت - if (status !== "all") { - query.status = status; - } - - // فیلتر بر اساس امتیاز - if (minRate || maxRate) { - query.rate = {}; - if (minRate) query.rate.$gte = parseInt(minRate); - if (maxRate) query.rate.$lte = parseInt(maxRate); - } - - // فیلتر بر اساس کاربر خاص - if (userId) { - query.user_id = userId; - } - - // تنظیمات مرتب‌سازی - const sortOptions = {}; - sortOptions[sortBy] = sortOrder === "desc" ? -1 : 1; - - // دریافت کامنت‌ها با pagination - const skip = (parseInt(page) - 1) * parseInt(limit); - - const [comments, totalComments] = await Promise.all([ - CourseComment.find(query) - .sort(sortOptions) - .skip(skip) - .limit(parseInt(limit)) - .populate("user_id", "name username profileImage"), - CourseComment.countDocuments(query), - ]); - - // محاسبه آمار کامنت‌ها - const stats = await CourseComment.aggregate([ - { $match: { course_id: courseId, status: "accepted" } }, - { - $group: { - _id: null, - totalAccepted: { $sum: 1 }, - averageRate: { $avg: "$rate" }, - rateDistribution: { - $push: "$rate", - }, - }, - }, - ]); - - const totalPages = Math.ceil(totalComments / parseInt(limit)); - - res.status(200).json({ - success: true, - message: "لیست کامنت‌ها با موفقیت دریافت شد", - data: { - comments: comments, - pagination: { - currentPage: parseInt(page), - totalPages: totalPages, - totalItems: totalComments, - itemsPerPage: parseInt(limit), - hasNextPage: parseInt(page) < totalPages, - hasPrevPage: parseInt(page) > 1, - }, - stats: { - totalComments: totalComments, - acceptedComments: stats[0]?.totalAccepted || 0, - averageRate: Math.round((stats[0]?.averageRate || 0) * 10) / 10, - rateDistribution: stats[0]?.rateDistribution || [], - }, - }, - }); - } catch (error) { - console.error("Error in getCourseComments:", error); - res.status(500).json({ - success: false, - message: "خطا در دریافت کامنت‌ها", - error: error.message, - }); - } -}; -// ==================== ویرایش وضعیت کامنت (برای همه قابل استفاده است) ==================== -const updateCommentStatus = async (req, res) => { - try { - const token = req.header("Authorization")?.split(" ")[1]; - if (!token) - return res.status(401).json({ error: true, message: "Access Denied" }); - - const decodedToken = jwt.verify(token, process.env.APP_SECRET); - const userId = decodedToken.id; - - const { commentId } = req.params; - const { status } = req.body; // 'pending', 'accepted', 'rejected' - - // اعتبارسنجی وضعیت - if (!["pending", "accepted", "rejected"].includes(status)) { - return res.status(422).json({ - error: true, - message: - "وضعیت نامعتبر است. وضعیت باید یکی از این موارد باشد: pending, accepted, rejected", - }); - } - - // پیدا کردن کامنت - const comment = await CourseComment.findById(commentId); - if (!comment) { - return res.status(404).json({ - error: true, - message: "کامنت پیدا نشد", - }); - } - - // بررسی دسترسی: یا خود صاحب کامنت است یا هر کاربر دیگری (طبق درخواست شما که همه بتوانند) - // اگر می‌خواهید فقط ادمین بتواند وضعیت را تغییر دهد، این بخش را تغییر دهید - const user = await UserModel.findById(userId); - const isOwner = comment.user_id.toString() === userId; - const isAdmin = user?.role === "admin"; - - if (!isOwner && !isAdmin) { - return res.status(403).json({ - error: true, - message: "شما اجازه تغییر وضعیت این کامنت را ندارید", - }); - } - - // به روز رسانی وضعیت - comment.status = status; - await comment.save(); - - // اگر کامنت تایید شد و امتیاز داشت، میانگین امتیاز دوره را به روز کن - if (status === "accepted" && comment.rate > 0) { - const averageRate = await CourseComment.aggregate([ - { $match: { course_id: comment.course_id, status: "accepted" } }, - { $group: { _id: null, avgRate: { $avg: "$rate" } } }, - ]); - - await CourseModel.findByIdAndUpdate(comment.course_id, { - averageRate: averageRate[0]?.avgRate || 0, - }); - } - - res.status(200).json({ - success: true, - message: `وضعیت کامنت با موفقیت به ${ - status === "accepted" - ? "تایید شده" - : status === "rejected" - ? "رد شده" - : "در انتظار" - } تغییر یافت`, - data: comment, - }); - } catch (error) { - console.error("Error in updateCommentStatus:", error); - res.status(500).json({ - success: false, - message: "خطا در تغییر وضعیت کامنت", - error: error.message, - }); - } -}; - -// ==================== دریافت کامنت‌های یک کاربر خاص ==================== -const getUserComments = async (req, res) => { - try { - const token = req.header("Authorization")?.split(" ")[1]; - if (!token) - return res.status(401).json({ error: true, message: "Access Denied" }); - - const decodedToken = jwt.verify(token, process.env.APP_SECRET); - const userId = decodedToken.id; - - const { page = 1, limit = 10, status = "all", courseId } = req.query; - - const query = { user_id: userId }; - - if (status !== "all") { - query.status = status; - } - - if (courseId) { - query.course_id = courseId; - } - - const skip = (parseInt(page) - 1) * parseInt(limit); - - const [comments, totalComments] = await Promise.all([ - CourseComment.find(query) - .sort({ createdAt: -1 }) - .skip(skip) - .limit(parseInt(limit)) - .populate("course_id", "cuorse_name packageImage"), - CourseComment.countDocuments(query), - ]); - - const totalPages = Math.ceil(totalComments / parseInt(limit)); - - res.status(200).json({ - success: true, - data: { - comments: comments, - pagination: { - currentPage: parseInt(page), - totalPages: totalPages, - totalItems: totalComments, - itemsPerPage: parseInt(limit), - }, - }, - }); - } catch (error) { - console.error("Error in getUserComments:", error); - res.status(500).json({ - success: false, - message: "خطا در دریافت کامنت‌های کاربر", - error: error.message, - }); - } -}; - -// ==================== حذف کامنت (اختیاری) ==================== -const deleteComment = async (req, res) => { - try { - const token = req.header("Authorization")?.split(" ")[1]; - if (!token) - return res.status(401).json({ error: true, message: "Access Denied" }); - - const decodedToken = jwt.verify(token, process.env.APP_SECRET); - const userId = decodedToken.id; - - const { commentId } = req.params; - - const comment = await CourseComment.findById(commentId); - if (!comment) { - return res.status(404).json({ - error: true, - message: "کامنت پیدا نشد", - }); - } - - // بررسی دسترسی: یا خود صاحب کامنت است یا ادمین - const user = await UserModel.findById(userId); - const isOwner = comment.user_id.toString() === userId; - const isAdmin = user?.role === "admin"; - - if (!isOwner && !isAdmin) { - return res.status(403).json({ - error: true, - message: "شما اجازه حذف این کامنت را ندارید", - }); - } - - await comment.deleteOne(); - - res.status(200).json({ - success: true, - message: "کامنت با موفقیت حذف شد", - }); - } catch (error) { - console.error("Error in deleteComment:", error); - res.status(500).json({ - success: false, - message: "خطا در حذف کامنت", - error: error.message, - }); - } -}; -// academyController.js - -const coursePayment = async (req, res, next) => { - try { - const token = req.header("Authorization")?.split(" ")[1]; - if (!token) { - return res.status(401).json({ - error: true, - message: "لطفا وارد حساب کاربری خود شوید", - }); - } - - const decodedToken = jwt.verify(token, process.env.APP_SECRET); - const userId = decodedToken.id; - const { courseId } = req.body; - - // ========== 1. بررسی وجود دوره ========== - const course = await CourseModel.findById(courseId); - if (!course) { - return res.status(404).json({ - error: true, - message: "دوره مورد نظر یافت نشد", - }); - } - - // ========== 2. بررسی خرید قبلی ========== - const existingPurchase = await IsPaymentCourse.findOne({ - user_id: userId, - course_id: course._id, - }); - - if (existingPurchase) { - return res.status(400).json({ - error: true, - message: "شما قبلاً این دوره را خریداری کرده‌اید", - }); - } - - // ========== 3. دریافت نرخ مالیات ========== - let taxRate = 9; // پیش‌فرض 9 درصد - const tax = await Tax.findOne({ type: "course" }); - if (tax && tax.tax) { - taxRate = Number(tax.tax); - } - - // ========== 4. محاسبه قیمت ========== - const offerNum = Number(course.offer) || 0; - const priceNum = Number(course.price); - - // قیمت پس از تخفیف - const discountedPrice = (priceNum / 100) * (100 - offerNum); - - // محاسبه مالیات - const taxAmount = discountedPrice * (taxRate / 100); - - // قیمت نهایی با مالیات (تومان) - const finalPrice = discountedPrice; - const finalTaxPrice = (discountedPrice / 100) * (100 - taxRate); - - // ========== 5. اعتبارسنجی قیمت ========== - if (!finalPrice || isNaN(finalPrice) || finalPrice <= 0) { - return res.status(422).json({ - error: true, - message: "مبلغ نامعتبر است", - }); - } - - // تبدیل به ریال (ضرب در 10 چون هر تومان = 10 ریال) - const amountInRials = Math.round(finalPrice * 10); - - // مبلغ باید حداقل 1000 تومان باشد (10000 ریال) - if (amountInRials < 10000) { - return res.status(422).json({ - error: true, - message: "مبلغ باید حداقل 1000 تومان باشد", - }); - } - - // ========== 6. ساخت کال‌بک URL ========== - const callbackUrl = `https://api.modstagram.com/api/v1/academy/academy/course/payment/verify?courseId=${courseId}&userId=${userId}`; - - // ========== 7. درخواست به زرین‌پال ========== - const zarinpalRes = await axios.post( - "https://api.zarinpal.com/pg/v4/payment/request.json", - { - merchant_id: process.env.ZARINPAL_MERCHANT_ID, - amount: amountInRials, - description: `خرید دوره ${course.cuorse_name}`, - callback_url: callbackUrl, - metadata: { - user_id: userId, - course_id: courseId, - price: finalPrice, - tax_rate: taxRate, - }, - }, - { - headers: { "Content-Type": "application/json" }, - timeout: 90000, - } - ); - - const result = zarinpalRes.data; - - // ========== 8. بررسی پاسخ زرین‌پال ========== - if (result.data && result.data.code === 100) { - // ذخیره اطلاعات پرداخت در حالت pending - await AcademyPaymentModel.create({ - price: finalPrice, - discountAmount: priceNum - discountedPrice, - taxAmount: finalTaxPrice, - taxRate: taxRate, - course_name: course.cuorse_name, - course_id: course._id, - academy_id: course.academyId, - user_id: userId, - payment_authority: result.data.authority, - status: "pending", - }); - - return res.status(200).json({ - success: true, - authority: result.data.authority, - paymentUrl: `https://www.zarinpal.com/pg/StartPay/${result.data.authority}`, - }); - } - - // خطای زرین‌پال - console.error("ZarinPal error:", result); - return res.status(422).json({ - error: true, - message: result.errors?.message || "خطا در ارتباط با درگاه پرداخت", - details: result.errors, - }); - } catch (error) { - console.error( - "Error in coursePayment:", - error.response?.data || error.message - ); - res.status(500).json({ - error: true, - message: "خطا در پردازش پرداخت", - details: error.response?.data || error.message, - }); - } -}; - -const CoursePaymentCallback = async (req, res) => { - try { - const { Authority, Status, courseId, userId } = req.query; - - // ========== 1. بررسی وضعیت پرداخت ========== - if (Status !== "OK") { - return res.redirect( - `${process.env.APP_SITE}/offer/payment/failed?message=payment_canceled` - ); - } - - // ========== 2. پیدا کردن دوره ========== - const course = await CourseModel.findById(courseId); - if (!course) { - return res.redirect( - `${process.env.APP_SITE}/offer/payment/failed?message=course_not_found` - ); - } - - // ========== 3. پیدا کردن رکورد پرداخت ========== - const paymentRecord = await AcademyPaymentModel.findOne({ - payment_authority: Authority, - course_id: courseId, - user_id: userId, - }); - - if (!paymentRecord) { - return res.redirect( - `${process.env.APP_SITE}/offer/payment/failed?message=payment_not_found` - ); - } - - // ========== 4. محاسبه مبلغ ========== - const amountInRials = Math.round(paymentRecord.price * 10); - - // ========== 5. تایید پرداخت با زرین‌پال ========== - const verify = await axios.post( - "https://api.zarinpal.com/pg/v4/payment/verify.json", - { - merchant_id: process.env.ZARINPAL_MERCHANT_ID, - authority: Authority, - amount: amountInRials, - }, - { - headers: { "Content-Type": "application/json" }, - timeout: 10000, - } - ); - - const data = verify.data.data; - - // ========== 6. بررسی نتیجه تایید ========== - if (data.code === 100) { - // به‌روزرسانی رکورد پرداخت - await AcademyPaymentModel.findByIdAndUpdate(paymentRecord._id, { - status: "success", - payment_ref_id: data.ref_id, - }); - - // ثبت خرید کاربر - await IsPaymentCourse.create({ - user_id: userId, - course_id: course._id, - price_paid: paymentRecord.price, - purchased_at: new Date(), - }); - - // هدایت به صفحه موفقیت - return res.redirect( - `${process.env.APP_SITE}/academy/${course._id}/success?payment=success` - ); - } - - // پرداخت ناموفق - await AcademyPaymentModel.findByIdAndUpdate(paymentRecord._id, { - status: "failed", - }); - - return res.redirect( - `${process.env.APP_SITE}/offer/payment/failed?code=${data.code}` - ); - } catch (err) { - console.error("Error in CoursePaymentCallback:", err); - return res.redirect( - `${process.env.APP_SITE}/offer/payment/failed?message=verification_error` - ); - } -}; -const getUserPurchasedCourses = async (req, res) => { - try { - const token = req.header("Authorization")?.split(" ")[1]; - if (!token) - return res.status(401).json({ error: true, message: "Access Denied" }); - - const decodedToken = jwt.verify(token, process.env.APP_SECRET); - const user_id = decodedToken.id; - - const { page = 1, limit = 10 } = req.query; - - // پیدا کردن تمام رکوردهای پرداخت برای این کاربر - const payments = await IsPaymentCourse.find({ user_id: user_id }) - .sort({ createdAt: -1 }) // جدیدترین اول - .skip((page - 1) * limit) - .limit(parseInt(limit)); - - // گرفتن اطلاعات کامل دوره‌ها - const courseIds = payments.map((payment) => payment.course_id); - - const courses = await CourseModel.find({ - _id: { $in: courseIds }, - status: "accept", // فقط دوره‌های تایید شده - }); - - // محاسبه تعداد کل - const total = await IsPaymentCourse.countDocuments({ user_id: user_id }); - - res.status(200).json({ - success: true, - data: { - courses: courses, - pagination: { - total, - page: parseInt(page), - pages: Math.ceil(total / limit), - limit: parseInt(limit), - }, - }, - }); - } catch (error) { - console.error("Error in getUserPurchasedCourses:", error); - res.status(500).json({ - success: false, - message: "خطا در دریافت دوره‌های خریداری شده", - error: error.message, - }); - } -}; - -// API با populate (روش بهتر) -const getUserPurchasedCoursesWithPopulate = async (req, res) => { - try { - const token = req.header("Authorization")?.split(" ")[1]; - if (!token) - return res.status(401).json({ error: true, message: "Access Denied" }); - - const decodedToken = jwt.verify(token, process.env.APP_SECRET); - const user_id = decodedToken.id; - - const { page = 1, limit = 10 } = req.query; - - const options = { - page: parseInt(page), - limit: parseInt(limit), - sort: { createdAt: -1 }, - populate: { - path: "course_id", - model: "Course", - match: { status: "accept" }, // فقط دوره‌های تایید شده - }, - }; - - const result = await IsPaymentCourse.paginate( - { user_id: user_id }, - options - ); - - // فیلتر کردن دوره‌هایی که populate شده‌اند و وجود دارند - const validCourses = result.docs - .filter((doc) => doc.course_id !== null) - .map((doc) => doc.course_id); - - res.status(200).json({ - success: true, - data: { - courses: validCourses, - pagination: { - total: result.totalDocs, - page: result.page, - totalPages: result.totalPages, - limit: result.limit, - hasNextPage: result.hasNextPage, - hasPrevPage: result.hasPrevPage, - }, - }, - }); - } catch (error) { - console.error("Error:", error); - res.status(500).json({ - success: false, - message: "خطا در دریافت دوره‌های خریداری شده", - }); - } -}; - -const getAllAcademyPayments = async (req, res) => { - try { - // 1. بررسی توکن - const token = req.header("Authorization")?.split(" ")[1]; - if (!token) { - return res.status(401).json({ - success: false, - message: "دسترسی غیرمجاز", - }); - } - - // 2. verify توکن - let decodedToken; - try { - decodedToken = jwt.verify(token, process.env.APP_SECRET); - } catch (jwtError) { - return res.status(401).json({ - success: false, - message: "توکن نامعتبر است", - }); - } - - const userId = decodedToken.id; - - // 3. پیدا کردن آکادمی - const academy = await AcademyModel.findOne({ userId: userId }); - - if (!academy) { - return res.status(404).json({ - success: false, - message: "آکادمی برای این کاربر یافت نشد", - }); - } - - const academy_id = academy._id; - const { page = 1, limit = 10, status } = req.query; - - // 4. ساخت فیلتر - let filter = { academy_id: academy_id }; - - if ( - status && - ["pending", "success", "failed", "settled"].includes(status) - ) { - filter.status = status; - } - - // 5. تنظیمات صفحه‌بندی - const pageNum = parseInt(page); - const limitNum = parseInt(limit); - const skip = (pageNum - 1) * limitNum; - - const options = { - page: pageNum, - limit: limitNum, - sort: { createdAt: -1 }, - populate: [ - { - path: "course_id", - model: "Course", - select: "cuorse_name price course_image category teacher_name", - }, - { - path: "user_id", - model: "User", - select: "user_name profile_image email phone", - }, - ], - }; - - // 6. دریافت پرداخت‌ها - const result = await AcademyPaymentModel.paginate(filter, options); - - // 7. محاسبه آمار دقیق‌تر - let totalAmount = 0; - let pendingCount = 0; - let acceptedCount = 0; - - if (result.docs && Array.isArray(result.docs)) { - totalAmount = result.docs.reduce((sum, p) => { - const price = parseInt(p.taxAmount) || 0; - return sum + price; - }, 0); - - pendingCount = result.docs.filter((p) => p.status === "pending").length; - acceptedCount = result.docs.filter((p) => p.status === "accept").length; - } - - // 8. پاسخ نهایی - res.status(200).json({ - success: true, - data: { - academy: { - _id: academy._id, - academy_name: academy.academy_name, - academy_image: academy.academy_image, - bio: academy.bio, - }, - payments: result.docs || [], - pagination: { - total: result.totalDocs || 0, - page: result.page || pageNum, - totalPages: result.totalPages || 1, - limit: result.limit || limitNum, - hasNextPage: result.hasNextPage || false, - hasPrevPage: result.hasPrevPage || false, - }, - stats: { - totalAmount: totalAmount, - pendingCount: pendingCount, - acceptedCount: acceptedCount, - }, - }, - }); - } catch (error) { - console.error("Error in getAllAcademyPayments:", error); - res.status(500).json({ - success: false, - message: "خطا در دریافت لیست پرداخت‌ها", - error: process.env.NODE_ENV === "development" ? error.message : undefined, - }); - } -}; -const checkCoursePurchase = async (req, res) => { - try { - const token = req.header("Authorization")?.split(" ")[1]; - if (!token) - return res.status(401).json({ error: true, message: "Access Denied" }); - - const decodedToken = jwt.verify(token, process.env.APP_SECRET); - const userId = decodedToken.id; - const { courseId } = req.params; - - // بررسی وجود کاربر و دوره - if (!userId || !courseId) { - return res.status(400).json({ - success: false, - message: "userId و courseId الزامی هستند", - }); - } - - // جستجو در دیتابیس - const purchase = await IsPaymentCourse.findOne({ - user_id: userId, - course_id: courseId, - }); - - // نتیجه - if (purchase) { - return res.status(200).json({ - success: true, - isPurchased: true, - message: "این دوره قبلاً خریداری شده است", - purchaseData: purchase, - }); - } else { - return res.status(200).json({ - success: true, - isPurchased: false, - message: "این دوره خریداری نشده است", - }); - } - } catch (error) { - console.error("Error in checkCoursePurchase:", error); - res.status(500).json({ - success: false, - message: "خطا در بررسی خرید دوره", - error: error.message, - }); - } -}; - -const getAcademyCourse = async (req, res, next) => { - try { - const { Id } = req.params; - - // گرفتن پارامترهای صفحه‌بندی - const page = parseInt(req.query.page) || 1; - const limit = parseInt(req.query.limit) || 10; - const skip = (page - 1) * limit; - - const academy = await AcademyModel.findById(Id); - if (!academy) { - return res.status(404).json({ - success: false, - message: "آکادمی پیدا نشد", - }); - } - - // ✅ شرط جستجو - فقط دوره‌های تایید شده - const query = { - academyId: academy._id, - status: "accept", - }; - - // دریافت تعداد کل دوره‌های تایید شده - const totalCourses = await CourseModel.countDocuments(query); - - // دریافت دوره‌های تایید شده با صفحه‌بندی - const courses = await CourseModel.find(query) - .sort({ createdAt: -1 }) - .skip(skip) - .limit(limit); - - // ✅ اگر دوره‌ای وجود نداشت، خطا نده، بلکه آرایه خالی برگردون - if (!courses || courses.length === 0) { - return res.status(200).json({ - success: true, - message: "هیچ دوره تایید شده‌ای یافت نشد", - data: { - courses: [], - pagination: { - currentPage: page, - totalPages: 0, - totalItems: 0, - itemsPerPage: limit, - hasNextPage: false, - hasPrevPage: false, - nextPage: null, - prevPage: null, - }, - }, - }); - } - - // محاسبات صفحه‌بندی - const totalPages = Math.ceil(totalCourses / limit); - const hasNextPage = page < totalPages; - const hasPrevPage = page > 1; - - res.status(200).json({ - success: true, - message: "لیست پکیج‌ها با موفقیت دریافت شد", - data: { - courses: courses, - pagination: { - currentPage: page, - totalPages: totalPages, - totalItems: totalCourses, - itemsPerPage: limit, - hasNextPage: hasNextPage, - hasPrevPage: hasPrevPage, - nextPage: hasNextPage ? page + 1 : null, - prevPage: hasPrevPage ? page - 1 : null, - }, - }, - }); - } catch (error) { - console.error("Error:", error); - res.status(500).json({ - success: false, - message: "خطا در دریافت پکیج‌ها", - error: error.message, - }); - } -}; - -// ==================== مدیریت پرداخت‌ها ==================== -const getAllPayments = async (req, res) => { - try { - const { page = 1, limit = 20, status, startDate, endDate } = req.query; - const skip = (parseInt(page) - 1) * parseInt(limit); - - let query = {}; - if (status) query.status = status; - if (startDate && endDate) { - query.createdAt = { - $gte: new Date(startDate), - $lte: new Date(endDate), - }; - } - - const payments = await AcademyPaymentModel.find(query) - .populate("user_id", "user_name profile_image email") - .populate("course_id", "cuorse_name price course_image") - .populate("academy_id", "academy_name academy_image sheba") - .sort({ createdAt: -1 }) - .skip(skip) - .limit(parseInt(limit)); - - const total = await AcademyPaymentModel.countDocuments(query); - - // آمار کلی پرداخت‌ها - const stats = await AcademyPaymentModel.aggregate([ - { $match: query }, - { - $group: { - _id: null, - totalAmount: { $sum: { $toDouble: "$price" } }, - totalCount: { $sum: 1 }, - pendingCount: { - $sum: { $cond: [{ $eq: ["$status", "pending"] }, 1, 0] }, - }, - settledCount: { - $sum: { $cond: [{ $eq: ["$status", "settled"] }, 1, 0] }, - }, - successCount: { - $sum: { $cond: [{ $eq: ["$status", "success"] }, 1, 0] }, - }, - }, - }, - ]); - - res.status(200).json({ - success: true, - data: { - payments, - stats: stats[0] || { - totalAmount: 0, - totalCount: 0, - pendingCount: 0, - settledCount: 0, - successCount: 0, - }, - pagination: { - currentPage: parseInt(page), - totalPages: Math.ceil(total / parseInt(limit)), - totalItems: total, - itemsPerPage: parseInt(limit), - }, - }, - }); - } catch (error) { - console.error(error); - res - .status(500) - .json({ success: false, message: "خطا در دریافت پرداخت‌ها" }); - } -}; - -const updatePaymentStatus = async (req, res) => { - try { - const { paymentId, status } = req.body; - - const payment = await AcademyPaymentModel.findByIdAndUpdate( - paymentId, - { status, updatedAt: new Date() }, - { new: true } - ); - - if (!payment) { - return res - .status(404) - .json({ success: false, message: "پرداخت یافت نشد" }); - } - - res.status(200).json({ - success: true, - message: "وضعیت پرداخت با موفقیت تغییر کرد", - data: payment, - }); - } catch (error) { - console.error(error); - res - .status(500) - .json({ success: false, message: "خطا در تغییر وضعیت پرداخت" }); - } -}; - -// ==================== مدیریت دوره‌ها ==================== -const getAllCourses = async (req, res) => { - try { - const { page = 1, limit = 20, status, type, category, search } = req.query; - const skip = (parseInt(page) - 1) * parseInt(limit); - - let query = {}; - if (status) query.status = status; - if (type) query.type = type; - if (category) query.category = category; - if (search) { - query.$or = [ - { cuorse_name: { $regex: search, $options: "i" } }, - { caption: { $regex: search, $options: "i" } }, - { teacher_name: { $regex: search, $options: "i" } }, - ]; - } - - const courses = await CourseModel.find(query) - .populate("academyId", "academy_name academy_image") - .populate("user_id", "user_name profile_image") - .sort({ createdAt: -1 }) - .skip(skip) - .limit(parseInt(limit)); - - const total = await CourseModel.countDocuments(query); - - // آمار دوره‌ها - const stats = await CourseModel.aggregate([ - { $match: query }, - { - $group: { - _id: null, - totalCourses: { $sum: 1 }, - totalPrice: { $sum: { $toDouble: "$price" } }, - normalCount: { - $sum: { $cond: [{ $eq: ["$type", "normal"] }, 1, 0] }, - }, - proCount: { $sum: { $cond: [{ $eq: ["$type", "pro"] }, 1, 0] } }, - legendCount: { - $sum: { $cond: [{ $eq: ["$type", "legend"] }, 1, 0] }, - }, - pendingCount: { - $sum: { $cond: [{ $eq: ["$status", "pending"] }, 1, 0] }, - }, - acceptCount: { - $sum: { $cond: [{ $eq: ["$status", "accept"] }, 1, 0] }, - }, - }, - }, - ]); - - res.status(200).json({ - success: true, - data: { - courses, - stats: stats[0] || {}, - pagination: { - currentPage: parseInt(page), - totalPages: Math.ceil(total / parseInt(limit)), - totalItems: total, - itemsPerPage: parseInt(limit), - }, - }, - }); - } catch (error) { - console.error(error); - res.status(500).json({ success: false, message: "خطا در دریافت دوره‌ها" }); - } -}; - -const updateCourseStatus = async (req, res) => { - try { - const { courseId, status, type } = req.body; - - console.log(courseId, status, type); - - const course = await CourseModel.findById(courseId); - - if (!course) { - return res.status(404).json({ success: false, message: "دوره یافت نشد" }); - } - - if (status) course.status = status; - if (type) course.type = type; - await course.save(); - - res.status(200).json({ - success: true, - message: "دوره با موفقیت به‌روزرسانی شد", - data: course, - courseId: courseId, - status: status, - type: type, - }); - } catch (error) { - console.error(error); - res - .status(500) - .json({ success: false, message: "خطا در به‌روزرسانی دوره" }); - } -}; - -const admindeleteCourse = async (req, res) => { - try { - const { courseId } = req.params; - - const course = await CourseModel.findByIdAndDelete(courseId); - - if (!course) { - return res.status(404).json({ success: false, message: "دوره یافت نشد" }); - } - - // حذف تمام پرداخت‌های مرتبط با این دوره - await AcademyPaymentModel.deleteMany({ course_id: courseId }); - - res.status(200).json({ - success: true, - message: "دوره با موفقیت حذف شد", - }); - } catch (error) { - console.error(error); - res.status(500).json({ success: false, message: "خطا در حذف دوره" }); - } -}; - -// ==================== مدیریت دوره‌های خریداری شده ==================== -const getAllPurchasedCourses = async (req, res) => { - try { - const { page = 1, limit = 20, userId, courseId, status } = req.query; - const skip = (parseInt(page) - 1) * parseInt(limit); - - let query = {}; - if (userId) query.user_id = userId; - if (courseId) query.course_id = courseId; - if (status) query.status = status; - - const purchases = await IsPaymentCourse.find(query) - .populate("user_id", "user_name profile_image email phone") - .populate("course_id", "cuorse_name price course_image teacher_name") - .sort({ createdAt: -1 }) - .skip(skip) - .limit(parseInt(limit)); - - const total = await IsPaymentCourse.countDocuments(query); - - // آمار خریدها - const stats = await IsPaymentCourse.aggregate([ - { $match: query }, - { - $group: { - _id: null, - totalPurchases: { $sum: 1 }, - uniqueUsers: { $addToSet: "$user_id" }, - }, - }, - ]); - - res.status(200).json({ - success: true, - data: { - purchases, - stats: { - totalPurchases: stats[0]?.totalPurchases || 0, - uniqueUsers: stats[0]?.uniqueUsers?.length || 0, - }, - pagination: { - currentPage: parseInt(page), - totalPages: Math.ceil(total / parseInt(limit)), - totalItems: total, - itemsPerPage: parseInt(limit), - }, - }, - }); - } catch (error) { - console.error(error); - res - .status(500) - .json({ success: false, message: "خطا در دریافت دوره‌های خریداری شده" }); - } -}; - -// ==================== مدیریت آکادمی‌ها ==================== -const getAllAcademies = async (req, res) => { - try { - const { page = 1, limit = 20, search } = req.query; - const skip = (parseInt(page) - 1) * parseInt(limit); - - let query = {}; - if (search) { - query.academy_name = { $regex: search, $options: "i" }; - } - - const academies = await AcademyModel.find(query) - .populate("userId", "user_name profile_image email") - .sort({ createdAt: -1 }) - .skip(skip) - .limit(parseInt(limit)); - - const total = await AcademyModel.countDocuments(query); - - // آمار آکادمی‌ها - const stats = await AcademyModel.aggregate([ - { - $group: { - _id: null, - totalAcademies: { $sum: 1 }, - totalRate: { $sum: "$rate" }, - avgRate: { $avg: "$rate" }, - }, - }, - ]); - - res.status(200).json({ - success: true, - data: { - academies, - stats: stats[0] || {}, - pagination: { - currentPage: parseInt(page), - totalPages: Math.ceil(total / parseInt(limit)), - totalItems: total, - itemsPerPage: parseInt(limit), - }, - }, - }); - } catch (error) { - console.error(error); - res - .status(500) - .json({ success: false, message: "خطا در دریافت آکادمی‌ها" }); - } -}; - -const updateAcademyStatus = async (req, res) => { - try { - const { academyId, status, rate, sheba } = req.body; - - const updateData = {}; - if (status) updateData.status = status; - if (rate) updateData.rate = rate; - if (sheba) updateData.sheba = sheba; - - const academy = await AcademyModel.findByIdAndUpdate( - academyId, - updateData, - { new: true } - ); - - if (!academy) { - return res - .status(404) - .json({ success: false, message: "آکادمی یافت نشد" }); - } - - res.status(200).json({ - success: true, - message: "آکادمی با موفقیت به‌روزرسانی شد", - data: academy, - }); - } catch (error) { - console.error(error); - res - .status(500) - .json({ success: false, message: "خطا در به‌روزرسانی آکادمی" }); - } -}; - -// ==================== مدیریت تنظیمات (تکس و قیمت پرو) ==================== -const getSettings = async (req, res) => { - try { - let settings = await SettingModel.findOne(); - - if (!settings) { - settings = await SettingModel.create({ - taxRate: 9, - proPrice: 99000, - legendPrice: 199000, - minWithdrawAmount: 50000, - maxWithdrawAmount: 10000000, - }); - } - - res.status(200).json({ - success: true, - data: settings, - }); - } catch (error) { - console.error(error); - res.status(500).json({ success: false, message: "خطا در دریافت تنظیمات" }); - } -}; - -const updateSettings = async (req, res) => { - try { - const { - taxRate, - proPrice, - legendPrice, - minWithdrawAmount, - maxWithdrawAmount, - } = req.body; - - const settings = await SettingModel.findOneAndUpdate( - {}, - { - taxRate, - proPrice, - legendPrice, - minWithdrawAmount, - maxWithdrawAmount, - updatedAt: new Date(), - }, - { new: true, upsert: true } - ); - - res.status(200).json({ - success: true, - message: "تنظیمات با موفقیت به‌روزرسانی شد", - data: settings, - }); - } catch (error) { - console.error(error); - res - .status(500) - .json({ success: false, message: "خطا در به‌روزرسانی تنظیمات" }); - } -}; - -const getCoursePrices = async (req, res) => { - try { - const proPrice = await CoursePaymentModel.findOne({ cuorse_type: "pro" }); - - const legendPrice = await CoursePaymentModel.findOne({ - cuorse_type: "legend", - }); - - const normalPrice = await CoursePaymentModel.findOne({ - cuorse_type: "normal", - }); - - res.status(200).json({ - success: true, - data: { - pro: proPrice - ? { price: proPrice.price, _id: proPrice._id } - : { price: "60000" }, - legend: legendPrice - ? { price: legendPrice.price, _id: legendPrice._id } - : { price: "199000" }, - normal: normalPrice - ? { price: normalPrice.price, _id: normalPrice._id } - : { price: "0" }, - }, - }); - } catch (error) { - console.error(error); - res - .status(500) - .json({ success: false, message: "خطا در دریافت قیمت دوره‌ها" }); - } -}; - -const updateCoursePrice = async (req, res) => { - try { - const { courseType, price } = req.body; - - if (!courseType || !price) { - return res - .status(400) - .json({ success: false, message: "نوع دوره و قیمت الزامی است" }); - } - - let coursePayment = await CoursePaymentModel.findOne({ - cuorse_type: courseType, - }); - - if (coursePayment) { - coursePayment.price = price.toString(); - await coursePayment.save(); - } else { - coursePayment = new CoursePaymentModel({ - price: price.toString(), - cuorse_type: courseType, - }); - await coursePayment.save(); - } - - res.status(200).json({ - success: true, - message: `قیمت دوره ${ - courseType === "pro" - ? "پرو" - : courseType === "legend" - ? "لجند" - : "معمولی" - } با موفقیت به‌روزرسانی شد`, - data: coursePayment, - }); - } catch (error) { - console.error(error); - res - .status(500) - .json({ success: false, message: "خطا در به‌روزرسانی قیمت دوره" }); - } -}; - -const getTax = async (req, res) => { - try { - let tax = await Tax.findOne({ type: "course" }); - - if (!tax) { - tax = new Tax({ tax: 8, type: "course" }); - await tax.save(); - } - - res.status(200).json({ - success: true, - data: { - tax: tax.tax, - _id: tax._id, - type: tax.type, - }, - }); - } catch (error) { - console.error(error); - res.status(500).json({ success: false, message: "خطا در دریافت مالیات" }); - } -}; - -const updateTax = async (req, res) => { - try { - const { tax } = req.body; - - if (tax === undefined || tax === null) { - return res - .status(400) - .json({ success: false, message: "مقدار مالیات الزامی است" }); - } - - let taxRecord = await Tax.findOne({ type: "course" }); - - if (taxRecord) { - taxRecord.tax = tax; - await taxRecord.save(); - } else { - taxRecord = new Tax({ tax: tax, type: "course" }); - await taxRecord.save(); - } - - res.status(200).json({ - success: true, - message: "مالیات با موفقیت به‌روزرسانی شد", - data: taxRecord, - }); - } catch (error) { - console.error(error); - res - .status(500) - .json({ success: false, message: "خطا در به‌روزرسانی مالیات" }); - } -}; - -const getAllSettings = async (req, res) => { - try { - const proPrice = await CoursePaymentModel.findOne({ cuorse_type: "pro" }); - const legendPrice = await CoursePaymentModel.findOne({ - cuorse_type: "legend", - }); - - let tax = await Tax.findOne({ type: "course" }); - if (!tax) { - tax = new Tax({ tax: 8, type: "course" }); - await tax.save(); - } - - res.status(200).json({ - success: true, - data: { - tax: tax.tax, - prices: { - pro: proPrice ? proPrice.price : "60000", - legend: legendPrice ? legendPrice.price : "199000", - }, - }, - }); - } catch (error) { - console.error(error); - res.status(500).json({ success: false, message: "خطا در دریافت تنظیمات" }); - } -}; - -const updateAllSettings = async (req, res) => { - try { - const { tax, proPrice, legendPrice } = req.body; - - if (tax !== undefined) { - let taxRecord = await Tax.findOne({ type: "course" }); - if (taxRecord) { - taxRecord.tax = tax; - await taxRecord.save(); - } else { - taxRecord = new Tax({ tax: tax, type: "course" }); - await taxRecord.save(); - } - } - - if (proPrice !== undefined) { - let proRecord = await CoursePaymentModel.findOne({ cuorse_type: "pro" }); - if (proRecord) { - proRecord.price = proPrice.toString(); - await proRecord.save(); - } else { - proRecord = new CoursePaymentModel({ - price: proPrice.toString(), - cuorse_type: "pro", - }); - await proRecord.save(); - } - } - - if (legendPrice !== undefined) { - let legendRecord = await CoursePaymentModel.findOne({ - cuorse_type: "legend", - }); - if (legendRecord) { - legendRecord.price = legendPrice.toString(); - await legendRecord.save(); - } else { - legendRecord = new CoursePaymentModel({ - price: legendPrice.toString(), - cuorse_type: "legend", - }); - await legendRecord.save(); - } - } - - res.status(200).json({ - success: true, - message: "تنظیمات با موفقیت به‌روزرسانی شد", - }); - } catch (error) { - console.error(error); - res - .status(500) - .json({ success: false, message: "خطا در به‌روزرسانی تنظیمات" }); - } -}; - -const getPaymentStats = async (req, res) => { - try { - const stats = await AcademyPaymentModel.aggregate([ - { - $group: { - _id: null, - totalAmount: { $sum: { $toDouble: "$price" } }, - totalCount: { $sum: 1 }, - pendingCount: { - $sum: { $cond: [{ $eq: ["$status", "pending"] }, 1, 0] }, - }, - settledCount: { - $sum: { $cond: [{ $eq: ["$status", "settled"] }, 1, 0] }, - }, - successCount: { - $sum: { $cond: [{ $eq: ["$status", "success"] }, 1, 0] }, - }, - }, - }, - ]); - - const result = stats[0] || { - totalAmount: 0, - totalCount: 0, - pendingCount: 0, - settledCount: 0, - successCount: 0, - }; - - result.averageAmount = - result.totalCount > 0 - ? Math.round(result.totalAmount / result.totalCount) - : 0; - - res.status(200).json({ - success: true, - data: result, - }); - } catch (error) { - console.error("Error in getPaymentStats:", error); - res.status(500).json({ - success: false, - message: "خطا در دریافت آمار پرداخت‌ها", - error: process.env.NODE_ENV === "development" ? error.message : undefined, - }); - } -}; - -const getCourseById = async (req, res) => { - try { - const { id } = req.params; - const course = await CourseModel.findById(id) - .populate("academyId", "academy_name academy_image") - .populate("user_id", "user_name profile_image"); - - if (!course) { - return res.status(404).json({ success: false, message: "دوره یافت نشد" }); - } - - res.status(200).json({ - success: true, - data: course, - }); - } catch (error) { - console.error(error); - res.status(500).json({ success: false, message: "خطا در دریافت دوره" }); - } -}; - -const createCourse = async (req, res) => { - try { - const courseData = req.body; - const newCourse = new CourseModel(courseData); - await newCourse.save(); - - res.status(201).json({ - success: true, - message: "دوره با موفقیت ایجاد شد", - data: newCourse, - }); - } catch (error) { - console.error(error); - res.status(500).json({ success: false, message: "خطا در ایجاد دوره" }); - } -}; - -const getCourseStats = async (req, res) => { - try { - const stats = await CourseModel.aggregate([ - { - $group: { - _id: null, - totalCourses: { $sum: 1 }, - normalCount: { - $sum: { $cond: [{ $eq: ["$type", "normal"] }, 1, 0] }, - }, - proCount: { $sum: { $cond: [{ $eq: ["$type", "pro"] }, 1, 0] } }, - legendCount: { - $sum: { $cond: [{ $eq: ["$type", "legend"] }, 1, 0] }, - }, - pendingCount: { - $sum: { $cond: [{ $eq: ["$status", "pending"] }, 1, 0] }, - }, - acceptCount: { - $sum: { $cond: [{ $eq: ["$status", "accept"] }, 1, 0] }, - }, - rejectCount: { - $sum: { $cond: [{ $eq: ["$status", "reject"] }, 1, 0] }, - }, - }, - }, - ]); - - res.status(200).json({ - success: true, - data: stats[0] || {}, - }); - } catch (error) { - console.error(error); - res - .status(500) - .json({ success: false, message: "خطا در دریافت آمار دوره‌ها" }); - } -}; - -const getPurchasedStats = async (req, res) => { - try { - const stats = await IsPaymentCourse.aggregate([ - { - $group: { - _id: null, - totalPurchases: { $sum: 1 }, - uniqueUsers: { $addToSet: "$user_id" }, - }, - }, - ]); - - res.status(200).json({ - success: true, - data: { - totalPurchases: stats[0]?.totalPurchases || 0, - uniqueUsers: stats[0]?.uniqueUsers?.length || 0, - }, - }); - } catch (error) { - console.error(error); - res - .status(500) - .json({ success: false, message: "خطا در دریافت آمار خریدها" }); - } -}; - -const getAcademyById = async (req, res) => { - try { - const { id } = req.params; - const academy = await AcademyModel.findById(id).populate( - "userId", - "user_name profile_image email" - ); - - if (!academy) { - return res - .status(404) - .json({ success: false, message: "آکادمی یافت نشد" }); - } - - res.status(200).json({ - success: true, - data: academy, - }); - } catch (error) { - console.error(error); - res.status(500).json({ success: false, message: "خطا در دریافت آکادمی" }); - } -}; - -const createAcademy = async (req, res) => { - try { - const academyData = req.body; - const newAcademy = new AcademyModel(academyData); - await newAcademy.save(); - - res.status(201).json({ - success: true, - message: "آکادمی با موفقیت ایجاد شد", - data: newAcademy, - }); - } catch (error) { - console.error(error); - res.status(500).json({ success: false, message: "خطا در ایجاد آکادمی" }); - } -}; - -const updateAcademy = async (req, res) => { - try { - const { id } = req.params; - const updateData = req.body; - - const academy = await AcademyModel.findByIdAndUpdate(id, updateData, { - new: true, - }); - - if (!academy) { - return res - .status(404) - .json({ success: false, message: "آکادمی یافت نشد" }); - } - - res.status(200).json({ - success: true, - message: "آکادمی با موفقیت به‌روزرسانی شد", - data: academy, - }); - } catch (error) { - console.error(error); - res - .status(500) - .json({ success: false, message: "خطا در به‌روزرسانی آکادمی" }); - } -}; - -const deleteAcademy = async (req, res) => { - try { - const { id } = req.params; - const academy = await AcademyModel.findByIdAndDelete(id); - - if (!academy) { - return res - .status(404) - .json({ success: false, message: "آکادمی یافت نشد" }); - } - - await CourseModel.deleteMany({ academyId: id }); - - res.status(200).json({ - success: true, - message: "آکادمی با موفقیت حذف شد", - }); - } catch (error) { - console.error(error); - res.status(500).json({ success: false, message: "خطا در حذف آکادمی" }); - } -}; - -const getAcademyStats = async (req, res) => { - try { - const stats = await AcademyModel.aggregate([ - { - $group: { - _id: null, - totalAcademies: { $sum: 1 }, - totalRate: { $sum: "$rate" }, - avgRate: { $avg: "$rate" }, - }, - }, - ]); - - res.status(200).json({ - success: true, - data: stats[0] || { - totalAcademies: 0, - totalRate: 0, - avgRate: 0, - }, - }); - } catch (error) { - console.error(error); - res - .status(500) - .json({ success: false, message: "خطا در دریافت آمار آکادمی‌ها" }); - } -}; -const deleteCourseVideo = async (req, res, next) => { - try { - const token = req.header("Authorization")?.split(" ")[1]; - if (!token) return res.status(401).send("Access Denied"); - const decodedToken = jwt.verify(token, process.env.APP_SECRET); - const userId = decodedToken.id; - - const { courseContentId, courseId } = req.body; - const courseContent = await AcademyContentModel.findById(courseContentId); - - if (!courseContent) { - return res.status(404).json({ - error: true, - message: "ویدعو یافت نشد", - }); - } - - courseContent.status = "reject"; - - await courseContent.save(); - - const course = await CourseModel.findById(courseId); - if (course) { - course.number_of_course_content = `${ - Number(course.number_of_course_content) - 1 - }`; - await course.save(); - } - - res.status(200).json({ - success: true, - message: "ویدیو با موفقیت پاک شد", - }); - } catch (error) { - console.error("Error:", error); - res.status(500).json({ - success: false, - message: "خطا در حذف ویدیو", - error: error.message, - }); - } -}; - -const getChunkDir = (uploadKey) => { - return path.join(process.cwd(), "storage", "temp-chunks", uploadKey); -}; - -setInterval(async () => { - const tempDir = path.join(process.cwd(), "storage", "temp-chunks"); - if (await fs.pathExists(tempDir)) { - const dirs = await fs.readdir(tempDir); - const now = Date.now(); - for (const dir of dirs) { - const dirPath = path.join(tempDir, dir); - const stat = await fs.stat(dirPath); - if (now - stat.mtimeMs > 30 * 60 * 1000) { - // 30 دقیقه - await fs.remove(dirPath); - console.log(`Cleaned up old upload: ${dir}`); - } - } - } -}, 60 * 60 * 1000); - -const creatCourseVideoChunk = async (req, res, next) => { - console.log("=== Chunk Video Upload ==="); - console.log("Chunk index:", req.body.chunkIndex); - - try { - const token = req.header("Authorization")?.split(" ")[1]; - if (!token) return res.status(401).send("Access Denied"); - const decodedToken = jwt.verify(token, process.env.APP_SECRET); - const userId = decodedToken.id; - - const { - courseId, - is_free, - file_name, - chunk, - chunkIndex, - totalChunks, - originalFileName, - fileSize, - mime_type, - } = req.body; - - if (!chunk) { - return res.status(422).json({ - error: true, - message: "تکه فایل ارسال نشده است", - }); - } - - if (!courseId) { - return res.status(422).json({ - error: true, - message: "شناسه دوره الزامی است", - }); - } - - const base64Data = chunk.split(",")[1] || chunk; - const buffer = Buffer.from(base64Data, "base64"); - - const uploadKey = `${courseId}_${originalFileName}`; - const chunkDir = getChunkDir(uploadKey); - - await fs.ensureDir(chunkDir); - - const metaPath = path.join(chunkDir, "meta.json"); - if (chunkIndex === "0" || chunkIndex === 0) { - const metaData = { - totalChunks: parseInt(totalChunks), - file_name: file_name, - originalFileName: originalFileName, - fileSize: fileSize, - mime_type: mime_type, - courseId: courseId, - is_free: is_free, - createdAt: Date.now(), - }; - await fs.writeJson(metaPath, metaData); - } - - if (!(await fs.pathExists(metaPath))) { - return res.status(404).json({ - error: true, - message: "جلسه آپلود یافت نشد", - }); - } - - const chunkPath = path.join(chunkDir, `chunk_${chunkIndex}`); - await fs.writeFile(chunkPath, buffer); - - console.log( - `✅ Chunk ${parseInt(chunkIndex) + 1}/${totalChunks} saved to disk (${ - buffer.length - } bytes)` - ); - - res.status(200).json({ - success: true, - message: `تکه ${ - parseInt(chunkIndex) + 1 - } از ${totalChunks} با موفقیت دریافت شد`, - chunkIndex: chunkIndex, - totalChunks: totalChunks, - }); - } catch (error) { - console.error("Error in creatCourseVideoChunk:", error); - res.status(500).json({ - success: false, - message: "خطا در دریافت تکه ویدیو", - error: error.message, - }); - } -}; - -const mergeVideoChunks = async (req, res, next) => { - console.log("=== Merge Video Chunks ==="); - - try { - const token = req.header("Authorization")?.split(" ")[1]; - if (!token) return res.status(401).send("Access Denied"); - const decodedToken = jwt.verify(token, process.env.APP_SECRET); - const userId = decodedToken.id; - - const { courseId, originalFileName, totalChunks } = req.body; - - const uploadKey = `${courseId}_${originalFileName}`; - const chunkDir = getChunkDir(uploadKey); - const metaPath = path.join(chunkDir, "meta.json"); - - if (!(await fs.pathExists(chunkDir)) || !(await fs.pathExists(metaPath))) { - return res.status(404).json({ - error: true, - message: "داده‌های آپلود یافت نشد", - }); - } - - const metaData = await fs.readJson(metaPath); - - const existingChunks = await fs.readdir(chunkDir); - const chunkFiles = existingChunks.filter((f) => f.startsWith("chunk_")); - - if (chunkFiles.length !== parseInt(totalChunks)) { - return res.status(422).json({ - error: true, - message: `تعداد تکه‌ها کامل نیست. دریافت شده: ${chunkFiles.length}، مورد نیاز: ${totalChunks}`, - }); - } - - const chunks = []; - for (let i = 0; i < parseInt(totalChunks); i++) { - const chunkPath = path.join(chunkDir, `chunk_${i}`); - if (!(await fs.pathExists(chunkPath))) { - return res.status(422).json({ - error: true, - message: `تکه ${i + 1} پیدا نشد`, - }); - } - const chunkBuffer = await fs.readFile(chunkPath); - chunks.push(chunkBuffer); - } - - const completeBuffer = Buffer.concat(chunks); - console.log("Original file size:", completeBuffer.length, "bytes"); - - const finalVideoDir = path.join( - process.cwd(), - "storage", - "courses", - "videos" - ); - await fs.ensureDir(finalVideoDir); - - let extension = ".mp4"; - if (metaData.mime_type === "video/mp4") extension = ".mp4"; - else if (metaData.mime_type === "video/quicktime") extension = ".mov"; - else if (metaData.mime_type === "video/x-msvideo") extension = ".avi"; - else if (metaData.mime_type === "video/webm") extension = ".webm"; - - const safeFileName = `course-${courseId}-${Date.now()}${extension}`; - const filePath = path.join(finalVideoDir, safeFileName); - - await fs.writeFile(filePath, completeBuffer); - console.log("Original file saved:", filePath); - - const newAcademyContent = new AcademyContentModel({ - course_video: `/storage/courses/videos/${safeFileName}`, - type: "video", - is_free: metaData.is_free === "true" || metaData.is_free === true, - courseId: courseId, - file_name: metaData.file_name || metaData.originalFileName, - }); - - await newAcademyContent.save(); - - const course = await CourseModel.findById(courseId); - if (course) { - course.number_of_course_content = `${ - Number(course.number_of_course_content) + 1 - }`; - await course.save(); - } - - await fs.remove(chunkDir); - - res.status(200).json({ - success: true, - message: "ویدیو با موفقیت ثبت شد (در حال پردازش...)", - data: newAcademyContent, - }); - - if (completeBuffer.length > 20 * 1024 * 1024) { - // اجرای غیرهمزمان بدون await - compressVideoInBackground(filePath, safeFileName, newAcademyContent._id); - } - } catch (error) { - console.error("Error in mergeVideoChunks:", error); - res.status(500).json({ - success: false, - message: "خطا در ترکیب ویدیو", - error: error.message, - }); - } -}; - -const compressVideoInBackground = async (filePath, fileName, contentId) => { - console.log(`Starting background compression for ${fileName}`); - - const dir = path.dirname(filePath); - const tempPath = path.join(dir, `temp-${fileName}`); - const { exec } = require("child_process"); - const util = require("util"); - const execPromise = util.promisify(exec); - - try { - await execPromise( - `ffmpeg -i "${filePath}" -c:v libx264 -crf 28 -preset veryfast -c:a aac -b:a 128k -movflags +faststart "${tempPath}" -y` - ); - - const compressedStat = await fs.stat(tempPath); - const originalStat = await fs.stat(filePath); - - if (compressedStat.size < originalStat.size) { - await fs.rename(tempPath, filePath); - console.log( - `✅ Background compression done: ${( - originalStat.size / - 1024 / - 1024 - ).toFixed(2)}MB → ${(compressedStat.size / 1024 / 1024).toFixed(2)}MB` - ); - } else { - await fs.remove(tempPath); - console.log("Compression didn't reduce size, keeping original"); - } - } catch (error) { - console.error("Background compression failed:", error.message); - if (await fs.pathExists(tempPath)) { - await fs.remove(tempPath); - } - } -}; - -const getUploadStatus = async (req, res) => { - try { - const { courseId, originalFileName } = req.query; - const uploadKey = `${courseId}_${originalFileName}`; - const chunkDir = getChunkDir(uploadKey); - - if (!(await fs.pathExists(chunkDir))) { - return res.status(200).json({ - success: true, - uploadedChunks: [], - totalChunks: 0, - }); - } - - const files = await fs.readdir(chunkDir); - const chunkFiles = files - .filter((f) => f.startsWith("chunk_")) - .map((f) => parseInt(f.replace("chunk_", ""))) - .sort((a, b) => a - b); - - const metaPath = path.join(chunkDir, "meta.json"); - let totalChunks = 0; - if (await fs.pathExists(metaPath)) { - const metaData = await fs.readJson(metaPath); - totalChunks = metaData.totalChunks; - } - - res.status(200).json({ - success: true, - uploadedChunks: chunkFiles, - totalChunks: totalChunks, - }); - } catch (error) { - res.status(500).json({ success: false, error: error.message }); - } -}; - - - -// ایجاد slug یکتا -const generateUniqueSlug = async (title, excludeId = null) => { - let slug = title - .replace(/[^\u0600-\u06FF\uFB8A\u067E\u0686\u06AF\u200C\uFB8E\u0698a-zA-Z0-9\s]/g, '') - .trim() - .replace(/\s+/g, '-') - .toLowerCase(); - - let uniqueSlug = slug; - let counter = 1; - - while (true) { - const query = { slug: uniqueSlug }; - if (excludeId) query._id = { $ne: excludeId }; - const exists = await AcademyCategoryModel.findOne(query); - if (!exists) break; - uniqueSlug = `${slug}-${counter}`; - counter++; - } - - return uniqueSlug; -}; - -// ==================== GET - دریافت لیست دسته‌بندی‌ها ==================== -const getAll = async (req, res) => { - try { - const { - page = 1, - limit = 20, - sortBy = 'order', - sortOrder = 'asc', - status, - parent, - search, - is_featured, - withChildren = 'false' - } = req.query; - - let query = {}; - - if (status) query.status = status; - if (parent !== undefined) query.parent = parent === 'null' ? null : parent; - if (is_featured === 'true') query.is_featured = true; - - if (search) { - query.$or = [ - { title: { $regex: search, $options: 'i' } }, - { description: { $regex: search, $options: 'i' } } - ]; - } - - const sortOptions = {}; - sortOptions[sortBy] = sortOrder === 'asc' ? 1 : -1; - - const options = { - page: parseInt(page), - limit: parseInt(limit), - sort: sortOptions, - populate: [ - { path: 'parent', select: 'title slug' }, - { path: 'created_by', select: 'user_name name' }, - { path: 'updated_by', select: 'user_name name' } - ] - }; - - let categories = await AcademyCategoryModel.paginate(query, options); - - // دریافت درخت دسته‌بندی (اختیاری) - if (withChildren === 'true' && !parent) { - const tree = await AcademyCategoryModel.getTree(); - categories = { ...categories, tree }; - } - - res.status(200).json({ - success: true, - message: 'لیست دسته‌بندی‌ها با موفقیت دریافت شد', - data: categories - }); - } catch (error) { - console.error('Error in getAll:', error); - res.status(500).json({ - success: false, - message: 'خطا در دریافت دسته‌بندی‌ها', - error: error.message - }); - } -}; - -// ==================== GET - دریافت یک دسته‌بندی ==================== -const getOne = async (req, res) => { - try { - const { id } = req.params; - const { includeCourses = 'false' } = req.query; - - let query = AcademyCategoryModel.findById(id); - - query = query.populate('parent', 'title slug icon color'); - query = query.populate('children', 'title slug icon color course_count order'); - query = query.populate('created_by', 'user_name name'); - - if (includeCourses === 'true') { - query = query.populate({ - path: 'courses', - select: 'cuorse_name course_image price offer', - options: { limit: 10 } - }); - } - - const category = await query; - - if (!category) { - return res.status(404).json({ - success: false, - message: 'دسته‌بندی یافت نشد' - }); - } - - res.status(200).json({ - success: true, - message: 'دسته‌بندی با موفقیت دریافت شد', - data: category - }); - } catch (error) { - console.error('Error in getOne:', error); - res.status(500).json({ - success: false, - message: 'خطا در دریافت دسته‌بندی', - error: error.message - }); - } -}; - -// ==================== GET - دریافت درخت دسته‌بندی ==================== -const getTree = async (req, res) => { - try { - const tree = await AcademyCategoryModel.getTree(); - - res.status(200).json({ - success: true, - message: 'درخت دسته‌بندی با موفقیت دریافت شد', - data: tree - }); - } catch (error) { - console.error('Error in getTree:', error); - res.status(500).json({ - success: false, - message: 'خطا در دریافت درخت دسته‌بندی', - error: error.message - }); - } -}; - -// ==================== GET - دریافت توسط اسلاگ ==================== -const getBySlug = async (req, res) => { - try { - const { slug } = req.params; - const { page = 1, limit = 20 } = req.query; - - const category = await AcademyCategoryModel.getBySlug(slug); - - if (!category) { - return res.status(404).json({ - success: false, - message: 'دسته‌بندی یافت نشد' - }); - } - - // دریافت دوره‌های این دسته - const courses = await CourseModel.find({ - category_id: category._id, - status: 'accept' - }) - .sort({ createdAt: -1 }) - .skip((page - 1) * limit) - .limit(parseInt(limit)); - - const totalCourses = await CourseModel.countDocuments({ - category_id: category._id, - status: 'accept' - }); - - res.status(200).json({ - success: true, - message: 'دسته‌بندی با موفقیت دریافت شد', - data: { - category, - courses: { - data: courses, - pagination: { - page: parseInt(page), - limit: parseInt(limit), - total: totalCourses, - pages: Math.ceil(totalCourses / limit) - } - } - } - }); - } catch (error) { - console.error('Error in getBySlug:', error); - res.status(500).json({ - success: false, - message: 'خطا در دریافت دسته‌بندی', - error: error.message - }); - } -}; - -// ==================== POST - ایجاد دسته‌بندی جدید ==================== -const create = async (req, res) => { - try { - const token = req.header("Authorization")?.split(" ")[1]; - if (!token) return res.status(401).json({ success: false, message: "Access Denied" }); - - const decodedToken = jwt.verify(token, process.env.APP_SECRET); - const userId = decodedToken.id; - - const { - title, - description, - icon, - color, - parent, - order, - image, - is_featured, - seo_title, - seo_description - } = req.body; - - // اعتبارسنجی - if (!title || title.trim().length < 2) { - return res.status(422).json({ - success: false, - message: 'عنوان دسته‌بندی باید حداقل ۲ کاراکتر باشد' - }); - } - - // بررسی تکراری نبودن عنوان - const existingTitle = await AcademyCategoryModel.findOne({ title }); - if (existingTitle) { - return res.status(409).json({ - success: false, - message: 'این عنوان قبلاً ثبت شده است' - }); - } - - // تولید slug یکتا - const slug = await generateUniqueSlug(title); - - // بررسی وجود parent - let level = 0; - if (parent) { - const parentCategory = await AcademyCategoryModel.findById(parent); - if (!parentCategory) { - return res.status(404).json({ - success: false, - message: 'دسته‌بندی والد یافت نشد' - }); - } - level = parentCategory.level + 1; - - if (level > 3) { - return res.status(422).json({ - success: false, - message: 'عمق دسته‌بندی نمی‌تواند بیشتر از ۳ سطح باشد' - }); - } - } - - const newCategory = new AcademyCategoryModel({ - title, - slug, - description: description || null, - icon: icon || null, - color: color || '#3B82F6', - parent: parent || null, - level, - order: order || 0, - image: image || null, - is_featured: is_featured || false, - seo_title: seo_title || title, - seo_description: seo_description || description, - created_by: userId, - status: 'active' - }); - - await newCategory.save(); - - res.status(201).json({ - success: true, - message: 'دسته‌بندی با موفقیت ایجاد شد', - data: newCategory - }); - } catch (error) { - console.error('Error in create:', error); - res.status(500).json({ - success: false, - message: 'خطا در ایجاد دسته‌بندی', - error: error.message - }); - } -}; - -// ==================== PUT/PATCH - ویرایش دسته‌بندی ==================== -const update = async (req, res) => { - try { - const token = req.header("Authorization")?.split(" ")[1]; - if (!token) return res.status(401).json({ success: false, message: "Access Denied" }); - - const decodedToken = jwt.verify(token, process.env.APP_SECRET); - const userId = decodedToken.id; - - const { id } = req.params; - const updateData = req.body; - - const category = await AcademyCategoryModel.findById(id); - if (!category) { - return res.status(404).json({ - success: false, - message: 'دسته‌بندی یافت نشد' - }); - } - - // بررسی تکراری نبودن عنوان - if (updateData.title && updateData.title !== category.title) { - const existingTitle = await AcademyCategoryModel.findOne({ - title: updateData.title, - _id: { $ne: id } - }); - if (existingTitle) { - return res.status(409).json({ - success: false, - message: 'این عنوان قبلاً ثبت شده است' - }); - } - - // آپدیت slug - updateData.slug = await generateUniqueSlug(updateData.title, id); - } - - // بررسی parent - if (updateData.parent) { - if (updateData.parent === id) { - return res.status(422).json({ - success: false, - message: 'یک دسته‌بندی نمی‌تواند والد خودش باشد' - }); - } - - const parentCategory = await AcademyCategoryModel.findById(updateData.parent); - if (!parentCategory) { - return res.status(404).json({ - success: false, - message: 'دسته‌بندی والد یافت نشد' - }); - } - - updateData.level = parentCategory.level + 1; - - if (updateData.level > 3) { - return res.status(422).json({ - success: false, - message: 'عمق دسته‌بندی نمی‌تواند بیشتر از ۳ سطح باشد' - }); - } - } - - updateData.updated_by = userId; - updateData.updatedAt = new Date(); - - const updatedCategory = await AcademyCategoryModel.findByIdAndUpdate( - id, - updateData, - { new: true, runValidators: true } - ); - - res.status(200).json({ - success: true, - message: 'دسته‌بندی با موفقیت به‌روزرسانی شد', - data: updatedCategory - }); - } catch (error) { - console.error('Error in update:', error); - res.status(500).json({ - success: false, - message: 'خطا در به‌روزرسانی دسته‌بندی', - error: error.message - }); - } -}; - -// ==================== DELETE - حذف (سافت دیلیت) ==================== -const remove = async (req, res) => { - try { - const token = req.header("Authorization")?.split(" ")[1]; - if (!token) return res.status(401).json({ success: false, message: "Access Denied" }); - - const decodedToken = jwt.verify(token, process.env.APP_SECRET); - const userId = decodedToken.id; - - const { id } = req.params; - const { permanent = 'false' } = req.query; - - const category = await AcademyCategoryModel.findById(id); - if (!category) { - return res.status(404).json({ - success: false, - message: 'دسته‌بندی یافت نشد' - }); - } - - // بررسی وجود زیردسته‌ها - const hasChildren = await AcademyCategoryModel.exists({ parent: id }); - if (hasChildren) { - return res.status(422).json({ - success: false, - message: 'این دسته‌بندی دارای زیردسته است. ابتدا زیردسته‌ها را حذف کنید' - }); - } - - // بررسی وجود دوره در این دسته - const hasCourses = await CourseModel.exists({ category_id: id }); - if (hasCourses && permanent === 'true') { - return res.status(422).json({ - success: false, - message: 'این دسته‌بندی دارای دوره است. ابتدا دوره‌ها را جابه‌جا کنید' - }); - } - - if (permanent === 'true') { - // حذف فیزیکی - await category.deleteOne(); - res.status(200).json({ - success: true, - message: 'دسته‌بندی با موفقیت حذف شد' - }); - } else { - // سافت دیلیت - category.status = 'deleted'; - category.updated_by = userId; - await category.save(); - - res.status(200).json({ - success: true, - message: 'دسته‌بندی با موفقیت غیرفعال شد' - }); - } - } catch (error) { - console.error('Error in remove:', error); - res.status(500).json({ - success: false, - message: 'خطا در حذف دسته‌بندی', - error: error.message - }); - } -}; - -// ==================== POST - تغییر وضعیت (اکتیو/غیراکتیو) ==================== -const toggleStatus = async (req, res) => { - try { - const token = req.header("Authorization")?.split(" ")[1]; - if (!token) return res.status(401).json({ success: false, message: "Access Denied" }); - - const decodedToken = jwt.verify(token, process.env.APP_SECRET); - const userId = decodedToken.id; - - const { id } = req.params; - const { status } = req.body; // 'active' or 'inactive' - - if (!['active', 'inactive'].includes(status)) { - return res.status(422).json({ - success: false, - message: 'وضعیت نامعتبر است' - }); - } - - const category = await AcademyCategoryModel.findByIdAndUpdate( - id, - { - status, - updated_by: userId, - updatedAt: new Date() - }, - { new: true } - ); - - if (!category) { - return res.status(404).json({ - success: false, - message: 'دسته‌بندی یافت نشد' - }); - } - - res.status(200).json({ - success: true, - message: `وضعیت دسته‌بندی با موفقیت به ${status === 'active' ? 'فعال' : 'غیرفعال'} تغییر کرد`, - data: category - }); - } catch (error) { - console.error('Error in toggleStatus:', error); - res.status(500).json({ - success: false, - message: 'خطا در تغییر وضعیت دسته‌بندی', - error: error.message - }); - } -}; - -// ==================== POST - افزایش تعداد دوره‌ها ==================== -const incrementCourseCount = async (req, res) => { - try { - const { id } = req.params; - const { increment = 1 } = req.body; - - const category = await AcademyCategoryModel.incrementCourseCount(id, increment); - - if (!category) { - return res.status(404).json({ - success: false, - message: 'دسته‌بندی یافت نشد' - }); - } - - res.status(200).json({ - success: true, - message: 'تعداد دوره‌ها به‌روزرسانی شد', - data: { course_count: category.course_count } - }); - } catch (error) { - console.error('Error in incrementCourseCount:', error); - res.status(500).json({ - success: false, - message: 'خطا در به‌روزرسانی تعداد دوره‌ها', - error: error.message - }); - } -}; - -// ==================== GET - دریافت دسته‌بندی‌های ویژه (featured) ==================== -const getFeatured = async (req, res) => { - try { - const { limit = 10 } = req.query; - - const categories = await AcademyCategoryModel.find({ - is_featured: true, - status: 'active' - }) - .sort({ order: 1 }) - .limit(parseInt(limit)) - .populate('parent', 'title slug'); - - res.status(200).json({ - success: true, - message: 'دسته‌بندی‌های ویژه با موفقیت دریافت شد', - data: categories - }); - } catch (error) { - console.error('Error in getFeatured:', error); - res.status(500).json({ - success: false, - message: 'خطا در دریافت دسته‌بندی‌های ویژه', - error: error.message - }); - } -}; - - -module.exports = { - // ========================================== - // 🏢 ماژول آکادمی (Academy) - // ========================================== - - // پیدا کردن آکادمی کاربر جاری - findAcademy, - - // پیدا کردن آکادمی با شناسه - findAcademyById, - - // تکمیل و ویرایش پروفایل آکادمی - academyProfile, - - // تغییر وضعیت آکادمی (فعال/غیرفعال - فقط ادمین) - updateAcademyStatus, - - // دریافت اطلاعات یک آکادمی با شناسه - getAcademyById, - - // ایجاد آکادمی جدید (دستی - معمولاً خودکار ایجاد می‌شود) - createAcademy, - - // ویرایش اطلاعات آکادمی - updateAcademy, - - // حذف آکادمی (به همراه تمام دوره‌های آن) - deleteAcademy, - - // دریافت آمار کلی آکادمی‌ها (تعداد، میانگین امتیاز و...) - getAcademyStats, - - // ========================================== - // 📚 ماژول دوره‌ها (Course) - // ========================================== - - // ایجاد دوره جدید - creatCourse, - - // ویرایش اطلاعات دوره - updateCourse, - - // حذف دوره (تغییر وضعیت به reject) - deleteCourse, - - // دریافت لیست دوره‌های آکادمی جاری - getCourse, - - // دریافت لیست همه دوره‌ها با فیلتر و جستجو - getCourses, - - // دریافت دوره‌های یک آکادمی خاص - getAcademyCourse, - - // آپلود ویدیو با روش Multipart - creatCourseVideo, - - // آپلود ویدیو با روش Base64 (برای فایل‌های کوچک) - creatCourseVideoBase64, - - // ========================================== - // 💳 ماژول پرداخت (Payment) - // ========================================== - - // پرداخت برای اشتراک پرو - proPayment, - - // کال‌بک درگاه پرداخت زرین‌پال (اشتراک پرو) - handleCoursePaymentCallback, - - // پرداخت برای خرید دوره - coursePayment, - - // کال‌بک درگاه پرداخت زرین‌پال (خرید دوره) - CoursePaymentCallback, - - // ========================================== - // 🎬 ماژول محتوای دوره (Course Content) - // ========================================== - - // دریافت محتوای دوره (لیست ویدیوها و فایل‌ها) - getCourseContent, - - // حذف ویدیو از دوره - deleteCourseVideo, - - // لایک کردن محتوا - likeCourseContent, - - // حذف لایک (دیسلایک) - dontLikeCourseContent, - - // دریافت تعداد لایک‌های یک دوره - getCourseLikesCount, - - // دریافت لیست دوره‌های لایک شده توسط کاربر - getUserLikedCourses, - - // بررسی وضعیت لایک کاربر (آیا لایک کرده یا نه) - isLikeCourseContent, - - // ========================================== - // 💬 ماژول کامنت‌ها (Comments) - // ========================================== - - // ایجاد کامنت جدید - createComment, - - // دریافت تعداد کل کامنت‌های یک دوره - getTotalCommentsCount, - - // دریافت لیست کامنت‌های یک دوره (با فیلتر و صفحه‌بندی) - getCourseComments, - - // تغییر وضعیت کامنت (تایید/رد/در انتظار) - updateCommentStatus, - - // دریافت کامنت‌های یک کاربر خاص - getUserComments, - - // حذف کامنت - deleteComment, - - // ========================================== - // 🛒 ماژول دوره‌های خریداری شده (Purchased) - // ========================================== - - // دریافت دوره‌های خریداری شده توسط کاربر جاری - getUserPurchasedCourses, - - // دریافت دوره‌های خریداری شده (با populate - روش بهینه) - getUserPurchasedCoursesWithPopulate, - - // دریافت همه پرداخت‌های آکادمی - getAllAcademyPayments, - - // بررسی خرید یک دوره توسط کاربر (برای صفحه دوره) - checkCoursePurchase, - - // ========================================== - // 👑 ماژول مدیریتی (Admin Panel) - // ========================================== - - // ------ مدیریت پرداخت‌ها ------ - - // دریافت همه پرداخت‌های سیستم (ادمین) - getAllPayments, - - // تغییر وضعیت پرداخت (pending/success/settled/failed) - updatePaymentStatus, - - // ------ مدیریت دوره‌ها ------ - - // دریافت همه دوره‌های سیستم (ادمین) - getAllCourses, - - // تغییر وضعیت دوره (تایید/رد/در انتظار) - updateCourseStatus, - - // حذف کامل دوره از سیستم (ادمین) - admindeleteCourse, - - // ------ مدیریت دوره‌های خریداری شده ------ - - // دریافت همه خریدهای سیستم (ادمین) - getAllPurchasedCourses, - - // ------ مدیریت آکادمی‌ها ------ - - // دریافت همه آکادمی‌های سیستم (ادمین) - getAllAcademies, - - // ------ مدیریت تنظیمات ------ - - // دریافت تنظیمات (تکس، قیمت‌ها و...) - getSettings, - - // به‌روزرسانی تنظیمات - updateSettings, - - // دریافت قیمت دوره‌ها (پرو، لجند، معمولی) - getCoursePrices, - - // به‌روزرسانی قیمت یک نوع دوره - updateCoursePrice, - - // دریافت درصد مالیات - getTax, - - // به‌روزرسانی درصد مالیات - updateTax, - - // دریافت همه تنظیمات یکجا - getAllSettings, - - // به‌روزرسانی همه تنظیمات یکجا - updateAllSettings, - - // ========================================== - // 📊 ماژول آمار (Stats) - // ========================================== - - // دریافت آمار پرداخت‌ها - getPaymentStats, - - // دریافت اطلاعات یک دوره با شناسه - getCourseById, - - // ایجاد دوره جدید (ادمین) - createCourse, - - // ویرایش دوره (ادمین) - updateCourse, - - // دریافت آمار کلی دوره‌ها - getCourseStats, - - // دریافت آمار دوره‌های خریداری شده - getPurchasedStats, - - // ========================================== - // 📹 ماژول آپلود تکه‌تکه (Chunk Upload) - // ========================================== - - // دریافت تکه ویدیو (هر بار یک تکه) - creatCourseVideoChunk, - - // ادغام تکه‌ها بعد از اتمام آپلود - mergeVideoChunks, - - // بررسی وضعیت آپلود (برای ادامه از جای قطع شده) - getUploadStatus, - - // ========================================== - // 🏷️ ماژول دسته‌بندی آکادمی (Category) - // ========================================== - - // دریافت لیست دسته‌بندی‌ها (با فیلتر و صفحه‌بندی) - getAll, - - // دریافت یک دسته‌بندی با شناسه - getOne, - - // دریافت درخت دسته‌بندی (ساختار سلسله‌مراتبی والد-فرزند) - getTree, - - // دریافت دسته‌بندی با اسلاگ (برای سئو و لینک‌های زیبا) - getBySlug, - - // ایجاد دسته‌بندی جدید - create, - - // ویرایش دسته‌بندی - update, - - // حذف دسته‌بندی (سافت دیلیت - فقط غیرفعال می‌شود) - remove, - - // تغییر وضعیت دسته‌بندی (فعال/غیرفعال) - toggleStatus, - - // افزایش تعداد دوره‌های دسته‌بندی - incrementCourseCount, - - // دریافت دسته‌بندی‌های ویژه (برای نمایش در صفحه اصلی) - getFeatured -}; \ No newline at end of file diff --git a/public/modstagram-back/controllers/application/academy/helpers/chatHelpers.js b/public/modstagram-back/controllers/application/academy/helpers/chatHelpers.js deleted file mode 100644 index a22af9f..0000000 --- a/public/modstagram-back/controllers/application/academy/helpers/chatHelpers.js +++ /dev/null @@ -1,72 +0,0 @@ -const moment = require('moment-jalaali') -const MessageModel = require('../models/MessageModel') -const UserModel = require('../models/UserModel') - -function formatTimeOnly(date) { - return moment(date).locale('fa').format('HH:mm:ss') -} - -async function enrichMessage(message) { - const doc = message._doc ? { ...message._doc } : { ...message } - let replyTo = null - - if (doc.replyToId) { - const parent = await MessageModel.findById(doc.replyToId).lean() - if (parent) { - const parentUser = - String(parent.senderId) === String(doc.senderId) - ? await UserModel.findById(doc.senderId).select('first_name last_name user_name').lean() - : await UserModel.findById(parent.senderId).select('first_name last_name user_name').lean() - replyTo = { - _id: parent._id, - content: (parent.content || 'پیام').slice(0, 200), - senderName: parentUser - ? `${parentUser.first_name || ''} ${parentUser.last_name || ''}`.trim() || parentUser.user_name - : 'کاربر' - } - } - } - - return { - ...doc, - createdAt: formatTimeOnly(doc.createdAt), - replyTo, - forwardedFrom: doc.forwardedFrom || undefined - } -} - -function emitChatEvents(io, message, senderId, receiverId) { - const payload = message - const roomA = `chat:${senderId}:${receiverId}` - const roomB = `chat:${receiverId}:${senderId}` - io.to(roomA).to(roomB).emit('newMessage', payload) - io.to(`user:${senderId}`).to(`user:${receiverId}`).emit('chatListUpdate', { - senderId, - receiverId, - message: payload - }) -} - -function parseForwardedContent(content) { - if (!content) return { body: '', forwardedFrom: null } - try { - const line = content.split('\n')[0] - const j = JSON.parse(line) - if (j.forwardedFrom) { - return { - forwardedFrom: j.forwardedFrom, - body: content.replace(/^\{.*\}\n?/, '').trim() - } - } - } catch (_) { - /* not json */ - } - return { body: content, forwardedFrom: null } -} - -module.exports = { - formatTimeOnly, - enrichMessage, - emitChatEvents, - parseForwardedContent -} diff --git a/public/modstagram-back/controllers/application/academy/index.js b/public/modstagram-back/controllers/application/academy/index.js deleted file mode 100644 index 67ae759..0000000 --- a/public/modstagram-back/controllers/application/academy/index.js +++ /dev/null @@ -1,357 +0,0 @@ -const express = require('express'); -const app = express(); -const path = require('path'); -const http = require('http').createServer(app); -const cors = require('cors'); -const moment = require('moment-jalaali'); -const MessageModel = require('./models/MessageModel'); -const fs = require('fs-extra'); -const cron = require('node-cron'); -const UserModel = require('./models/UserModel'); -const blockCheck = require('./middlewares/blockCheck'); -const rateLimit = require('express-rate-limit'); -const { default: axios } = require('axios'); - -const allowedOrigins = [ - 'http://localhost:3000', - 'http://localhost:3001', // اضافه شد — مهم برای توسعه فرانت - 'http://localhost:3002', - 'http://localhost:3003', - 'http://localhost', - 'https://modstagram.com', - 'https://www.modstagram.com', - 'https://api.modstagram.com', - 'https://panel.modstagram.com', - 'https://www.panel.modstagram.com', - 'https://panel.modstagram.ir', - 'https://www.panel.modstagram.ir', - 'ionic://localhost', - 'capacitor://localhost', - // IPهای محلی (برای تست در شبکه داخلی) - /^http:\/\/192\.168\.\d{1,3}\.\d{1,3}:\d+$/, - /^http:\/\/10\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d+$/, -]; - -app.use(cors({ - origin: (origin, callback) => { - // در محیط توسعه، همه originها مجاز باشن - if (process.env.NODE_ENV !== 'production') { - return callback(null, true); - } - - // اگر origin وجود نداشته باشه (مثل درخواست از موبایل یا Postman) اجازه بده - if (!origin) { - return callback(null, true); - } - - // چک لیست یا RegExp - const isAllowed = allowedOrigins.some(item => { - if (typeof item === 'string') return item === origin; - if (item instanceof RegExp) return item.test(origin); - return false; - }); - - if (isAllowed) { - callback(null, true); - } else { - callback(new Error('Not allowed by CORS')); - } - }, - methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'], - allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With', 'x-no-toast'], - credentials: true, - optionsSuccessStatus: 200 // برای مرورگرهای قدیمی -})); - -// Socket.IO CORS -const io = require('socket.io')(http, { - cors: { - origin: (origin, callback) => { - if (process.env.NODE_ENV !== 'production') { - return callback(null, true); - } - - if (!origin) { - return callback(null, true); - } - - const isAllowed = allowedOrigins.some(item => { - if (typeof item === 'string') return item === origin; - if (item instanceof RegExp) return item.test(origin); - return false; - }); - - if (isAllowed) { - callback(null, true); - } else { - callback(new Error('Not allowed by CORS')); - } - }, - methods: ['GET', 'POST', 'PATCH', 'PUT', 'DELETE', 'OPTIONS'], - credentials: true - } -}); - -// افزایش limit برای Base64 (1000mb کافیه) -app.use(express.json({ limit: '1000mb' })); -app.use(express.urlencoded({ limit: '1000mb', extended: true })); - -app.use('/storage', express.static(path.join(__dirname, 'storage'))); -app.use('/storage/profiles', express.static(path.join(__dirname, '../storage/profiles'))); -app.use('/storage/carts', express.static(path.join(__dirname, '../storage/carts'))); -app.use('/storage/posts', express.static(path.join(__dirname, '../storage/posts'))); -app.use('/storage/messages', express.static(path.join(__dirname, '../storage/messages'))); -app.use('/storage/tickets', express.static(path.join(__dirname, '../storage/tickets'))); -app.use('/storage/advertising', express.static(path.join(__dirname, '../storage/advertising'))); -app.use('/storage/services', express.static(path.join(__dirname, '../storage/services'))); - -require('./boot'); - -// غیرفعال کردن پارس‌کننده‌های بدنه برای روت‌های آپلود فایل -app.use((req, res, next) => { - if (req.path === '/api/v1/posts/create' && req.method === 'POST') { - console.log('DEBUG: Skipping body parsers for /api/v1/posts/create'); - return next(); - } - express.json()(req, res, next); -}); -app.use((req, res, next) => { - if (req.path === '/api/v1/posts/create' && req.method === 'POST') { - return next(); - } - express.urlencoded({ extended: true })(req, res, next); -}); - -require('./middlewares')(app); - -const limiter = rateLimit({ - windowMs: 3 * 60 * 1000, - max: 3000, - standardHeaders: true, - legacyHeaders: false, - message: 'تعداد درخواست‌های شما بیشتر از حد مجاز است، لطفاً بعداً دوباره تلاش کنید.', - handler: (req, res) => { - const retryAfter = Math.ceil((req.rateLimit.resetTime - Date.now()) / 1000); - res.set('Retry-After', retryAfter); - res.status(429).json({ - error: `شما بیش از حد مجاز درخواست ارسال کرده‌اید. لطفاً بعد از ${retryAfter} ثانیه دوباره تلاش کنید.` - }); - } -}); -app.use(limiter); -app.set('trust proxy', 'loopback'); - -require('./routes')(app); - -const { enrichMessage, emitChatEvents, parseForwardedContent } = require('./helpers/chatHelpers') - -app.get('/api/v1/chat', async (req, res) => { - try { - const { senderId, receiverId, limit, page } = req.query - const pageNumber = parseInt(page) || 1 - const limitPerPage = parseInt(limit) || 40 - - const filter = { - $or: [ - { senderId, receiverId }, - { senderId: receiverId, receiverId: senderId } - ] - } - - const totalMessagesCount = await MessageModel.countDocuments(filter) - const totalPages = Math.ceil(totalMessagesCount / limitPerPage) || 1 - const skip = (pageNumber - 1) * limitPerPage - - const messages = await MessageModel.find(filter) - .sort({ createdAt: -1 }) - .skip(skip) - .limit(limitPerPage) - - await MessageModel.updateMany( - { _id: { $in: messages.map((m) => m._id) }, receiverId: senderId }, - { $set: { readStatus: 1 } } - ) - - const enriched = await Promise.all(messages.map((m) => enrichMessage(m))) - res.json({ messages: enriched.reverse(), totalPages }) - } catch (error) { - console.error('Error fetching messages:', error) - res.status(500).json({ error: 'Server error' }) - } -}) - -app.post('/api/v1/chat', [blockCheck], async (req, res) => { - try { - const { senderId, receiverId, content, replyToId, forwardedFrom: fwdBody } = req.body - const { body, forwardedFrom: fwdParsed } = parseForwardedContent(content) - - const payload = { - senderId, - receiverId, - content: body || content, - replyToId: replyToId || undefined, - forwardedFrom: fwdBody || fwdParsed || undefined - } - - const newMessage = new MessageModel(payload) - await newMessage.save() - const formatted = await enrichMessage(newMessage) - - res.status(201).json({ data: formatted }) - emitChatEvents(io, formatted, senderId, receiverId) - } catch (error) { - console.error('Error sending message:', error) - res.status(500).json({ error: 'Server error' }) - } -}) -app.get('/api/v1/chat/read', async (req, res) => { - try { - const { senderId, receiverId } = req.query // شناسه فرستنده و گیرنده از درخواست دریافت شود - // پیدا کردن تمام پیام‌هایی که کاربر دوم مشاهده کرده است و کاربر اول آنها را ارسال کرده است - const messages = await MessageModel.find( - { senderId: receiverId, receiverId: senderId } // برای مواقعی که شناسه‌ها معکوس باشند - ) - // به روزرسانی وضعیت خوانده شده یا نشده بودن پیام‌ها به "خوانده شده" - await MessageModel.updateMany({ _id: { $in: messages.map(message => message._id) } }, { $set: { readStatus: 1 } }) - res.status(200).json({ message: 'Message read status updated successfully' }) - } catch (error) { - console.error('Error updating message read status:', error) - res.status(500).json({ error: 'Server error' }) - } -}) - -app.post("/api/v1/notification/send-sms", async (req, res) => { - const { receiverId, message } = req.body; - const user = await UserModel.findById(receiverId); - if (!user || !user.mobile) return res.status(404).json({ error: "User not found" }); - console.log("3"); - - const mobile = user.mobile - const user_name = user.user_name - const data = JSON.stringify({ - mobile, - templateId: '876533', - parameters: [ - { name: 'USER', value: user_name } - ] - }) - - const config = { - method: 'post', - url: 'https://api.sms.ir/v1/send/verify', - headers: { - 'Content-Type': 'application/json', - Accept: 'text/plain', - 'x-api-key': '2JKxGbTzE64t0YTkjip6RYHnm9mq1haMlidF8WWwQunwubHFVW6iaMmfFQbMXEDt' - }, - data - } - - axios(config) - .then(function (response) { - console.log(response); - - }) - .catch(function (error) { - console.log(error) - }) - - res.status(200).json({ success: true }); -}); - -app.post('/api/v1/chat/file', [blockCheck], async (req, res) => { - try { - const { senderId, receiverId, content, replyToId, fileType } = req.body - const { file } = req.files - let fileUrl = null - if (file) { - const uploadDir = path.join(__dirname, '../storage/messages') - if (!fs.existsSync(uploadDir)) { - fs.mkdirSync(uploadDir, { recursive: true }) - } - const uniqueFileName = `${Date.now()}-${file.name}` - const filePath = path.join(uploadDir, uniqueFileName) - await fs.move(file.path, filePath) - fileUrl = `/messages/${uniqueFileName}` - } - - const newMessage = new MessageModel({ - senderId, - receiverId, - content: content || '', - file: fileUrl, - fileType: fileType || undefined, - replyToId: replyToId || undefined - }) - await newMessage.save() - const formatted = await enrichMessage(newMessage) - - res.status(201).json({ data: formatted }) - emitChatEvents(io, formatted, senderId, receiverId) - } catch (error) { - console.error('Error sending message:', error) - res.status(500).json({ error: 'Server error' }) - } -}) -// Errors -require('./middlewares/exception')(app) -require('./middlewares/404')(app) -io.on('connection', (socket) => { - socket.on('joinUser', ({ userId }) => { - if (userId) socket.join(`user:${userId}`) - }) - - socket.on('joinChat', ({ userId, receiverId }) => { - if (userId && receiverId) { - socket.join(`chat:${userId}:${receiverId}`) - socket.join(`chat:${receiverId}:${userId}`) - } - }) - - socket.on('typing', ({ senderId, receiverId }) => { - io.to(`chat:${receiverId}:${senderId}`).emit('userTyping', { userId: senderId }) - }) - - socket.on('stopTyping', ({ senderId, receiverId }) => { - io.to(`chat:${receiverId}:${senderId}`).emit('userStoppedTyping', { userId: senderId }) - }) - - socket.on('messageSeen', async ({ messageId, senderId, receiverId }) => { - try { - if (messageId) { - await MessageModel.findByIdAndUpdate(messageId, { readStatus: 1 }) - io.to(`chat:${receiverId}:${senderId}`).emit('messageStatusUpdate', { - messageId, - status: 'seen' - }) - } - } catch (e) { - console.error('messageSeen error', e) - } - }) -}) - -// Free Project -require('./services/AdvertisingCron') -require('./services/ProjectCron') -cron.schedule('0 0 1 * *', async () => { - try { - await UserModel.updateMany({}, { - daily_free_request: 1, - last_free_request_date: new Date(), - monthly_free_offer: 1, - last_free_offer_date: new Date() - }) - console.log('Monthly free requests reset for all users.') - } catch (error) { - console.error('Error resetting daily free requests:', error) - } -}, { - scheduled: true, - timezone: 'Asia/Tehran' -}) -module.exports = (port) => { - http.listen(port, () => { - console.log(`HTTP server is running on port ${port}`) - }) -} diff --git a/public/modstagram-back/controllers/application/academy/models/AcademyCategoryModel.js b/public/modstagram-back/controllers/application/academy/models/AcademyCategoryModel.js deleted file mode 100644 index be50bf0..0000000 --- a/public/modstagram-back/controllers/application/academy/models/AcademyCategoryModel.js +++ /dev/null @@ -1,190 +0,0 @@ -const mongoose = require('mongoose'); -const mongoosePaginate = require('mongoose-paginate-v2'); -const timestamp = require('mongoose-timestamp'); - -const AcademyCategorySchema = new mongoose.Schema({ - title: { - type: String, - required: [true, 'عنوان دسته‌بندی الزامی است'], - trim: true, - minLength: [2, 'عنوان باید حداقل ۲ کاراکتر باشد'], - maxLength: [100, 'عنوان باید حداکثر ۱۰۰ کاراکتر باشد'], - unique: true, - index: true, - }, - slug: { - type: String, - required: true, - unique: true, - lowercase: true, - trim: true, - index: true, - }, - description: { - type: String, - required: false, - trim: true, - maxLength: 500, - default: null, - }, - icon: { - type: String, - required: false, - default: null, - }, - color: { - type: String, - required: false, - default: '#3B82F6', - match: /^#[0-9A-F]{6}$/i, - }, - parent: { - type: mongoose.Schema.Types.ObjectId, - ref: 'AcademyCategory', - required: false, - default: null, - index: true, - }, - level: { - type: Number, - required: true, - default: 0, - min: 0, - max: 3, - }, - order: { - type: Number, - required: true, - default: 0, - index: true, - }, - image: { - type: String, - required: false, - default: null, - }, - course_count: { - type: Number, - required: true, - default: 0, - min: 0, - }, - status: { - type: String, - enum: ['active', 'inactive', 'deleted'], - required: true, - default: 'active', - index: true, - }, - is_featured: { - type: Boolean, - required: true, - default: false, - index: true, - }, - seo_title: { - type: String, - required: false, - trim: true, - maxLength: 70, - }, - seo_description: { - type: String, - required: false, - trim: true, - maxLength: 160, - }, - created_by: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: true, - }, - updated_by: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: false, - }, -}, { - toJSON: { virtuals: true }, - toObject: { virtuals: true } -}); - -// Virtual برای زیردسته‌ها -AcademyCategorySchema.virtual('children', { - ref: 'AcademyCategory', - localField: '_id', - foreignField: 'parent', - justOne: false, - options: { sort: { order: 1, title: 1 } } -}); - -// Virtual برای دوره‌های این دسته -AcademyCategorySchema.virtual('courses', { - ref: 'Course', - localField: '_id', - foreignField: 'category_id', - justOne: false, - match: { status: 'accept' } -}); - -// Middleware: قبل از save -AcademyCategorySchema.pre('save', async function(next) { - if (this.isModified('title') || this.isNew) { - // تولید slug - this.slug = this.title - .replace(/[^\u0600-\u06FF\uFB8A\u067E\u0686\u06AF\u200C\uFB8E\u0698a-zA-Z0-9\s]/g, '') - .trim() - .replace(/\s+/g, '-') - .toLowerCase(); - - // اگه parent داره، سطح رو محاسبه کن - if (this.parent) { - const parent = await this.constructor.findById(this.parent); - if (parent) { - this.level = parent.level + 1; - } - } else { - this.level = 0; - } - } - next(); -}); - -// استاتیک متدها -AcademyCategorySchema.statics = { - // دریافت درخت دسته‌بندی‌ها - async getTree() { - const categories = await this.find({ status: 'active', parent: null }) - .sort({ order: 1, title: 1 }) - .populate({ - path: 'children', - match: { status: 'active' }, - options: { sort: { order: 1, title: 1 } }, - populate: { - path: 'children', - match: { status: 'active' }, - options: { sort: { order: 1, title: 1 } } - } - }); - return categories; - }, - - // افزایش تعداد دوره‌ها - async incrementCourseCount(categoryId, increment = 1) { - return this.findByIdAndUpdate(categoryId, { - $inc: { course_count: increment } - }); - }, - - // دریافت دسته‌بندی با اسلاگ - async getBySlug(slug) { - return this.findOne({ slug, status: 'active' }) - .populate('children') - .populate('parent'); - } -}; - -AcademyCategorySchema.plugin(timestamp); -AcademyCategorySchema.plugin(mongoosePaginate); - -module.exports = mongoose.model('AcademyCategory', AcademyCategorySchema); \ No newline at end of file diff --git a/public/modstagram-back/controllers/application/academy/models/AcademyContentModel.js b/public/modstagram-back/controllers/application/academy/models/AcademyContentModel.js deleted file mode 100644 index 092990f..0000000 --- a/public/modstagram-back/controllers/application/academy/models/AcademyContentModel.js +++ /dev/null @@ -1,71 +0,0 @@ -const mongoose = require('mongoose'); -const timestamp = require('mongoose-timestamp'); -const mongoosePaginate = require('mongoose-paginate-v2'); - -const modelSchema = new mongoose.Schema({ - course_images: { - type: [String], // آرایه‌ای از مسیرهای تصاویر - required: false, - default: [], - }, - course_video: { - type: String, // مسیر ویدئو - required: false, - trim: true, - default: null, - }, - type: { - type: String, // نوع پست: 'image' یا 'video' - required: true, - enum: ['image', 'video'], - }, - files: [ - { - path: { type: String, required: false }, - type: { type: String, enum: ['image', 'video'], required: false }, - } - ], - caption: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 1000, - default: null, - }, - status: { - type: String, - required: false, - trim: true, - enum: ['pending', 'accept', 'reject'], - default: 'accept', - }, - user_id: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - }, - likes: [{ - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - }], - comments: { - type: Object, - default: null, - }, - courseId: { - type: String, - }, - - is_free: { - type: Boolean, - }, - file_name: { - type: String, - }, - -}); - -modelSchema.plugin(timestamp); -modelSchema.plugin(mongoosePaginate); -const PostModel = mongoose.model('AcademyContent', modelSchema); -module.exports = PostModel; \ No newline at end of file diff --git a/public/modstagram-back/controllers/application/academy/models/AcademyLikeModel.js b/public/modstagram-back/controllers/application/academy/models/AcademyLikeModel.js deleted file mode 100644 index 358f036..0000000 --- a/public/modstagram-back/controllers/application/academy/models/AcademyLikeModel.js +++ /dev/null @@ -1,25 +0,0 @@ -const mongoose = require("mongoose"); -const timestamp = require("mongoose-timestamp"); -const mongoosePaginate = require("mongoose-paginate-v2"); - -const modelSchema = new mongoose.Schema({ - - user_id: { - type: String, - required: true, - trim: true, - default: 0, - }, - course_id: { - type: String, - required: true, - trim: true, - default: 0, - }, - -}); - -modelSchema.plugin(timestamp); -modelSchema.plugin(mongoosePaginate); -const PostModel = mongoose.model("Likes", modelSchema); -module.exports = PostModel; diff --git a/public/modstagram-back/controllers/application/academy/models/AcademyModel.js b/public/modstagram-back/controllers/application/academy/models/AcademyModel.js deleted file mode 100644 index 9f8e758..0000000 --- a/public/modstagram-back/controllers/application/academy/models/AcademyModel.js +++ /dev/null @@ -1,55 +0,0 @@ -const mongoose = require("mongoose"); -const timestamp = require("mongoose-timestamp"); -const mongoosePaginate = require("mongoose-paginate-v2"); - -const modelSchema = new mongoose.Schema({ - academy_image: { - type: String, - required: false, - trim: true, - default: null, - }, - academy_name: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null, - }, - userId: { - type: String, - required: true, - }, - rate: { - type: Number, - trim: true, - default: 0 - }, - number_of_rate: { - type: Number, - trim: true, - default: 0 - }, - sheba: { - type: String, - required: false, - default: null - }, - bio: { - type: String, - required: false, - default: null - }, - tag: { - type: Object, - required: false, - default: null - }, - -}); - -modelSchema.plugin(timestamp); -modelSchema.plugin(mongoosePaginate); -const PostModel = mongoose.model("Academy", modelSchema); -module.exports = PostModel; diff --git a/public/modstagram-back/controllers/application/academy/models/AcademyPaymentModel.js b/public/modstagram-back/controllers/application/academy/models/AcademyPaymentModel.js deleted file mode 100644 index b7c9fa7..0000000 --- a/public/modstagram-back/controllers/application/academy/models/AcademyPaymentModel.js +++ /dev/null @@ -1,24 +0,0 @@ -const mongoose = require("mongoose"); -const timestamp = require("mongoose-timestamp"); -const mongoosePaginate = require("mongoose-paginate-v2"); - -const modelSchema = new mongoose.Schema({ - price: { type: Number, required: true }, // قیمت نهایی شامل مالیات - discountAmount: { type: Number, default: 0 }, // مبلغ تخفیف - taxAmount: { type: Number, default: 0 }, // مبلغ مالیات - taxRate: { type: Number, default: 9 }, // درصد مالیات - course_name: { type: String, required: true }, - course_id: { type: mongoose.Schema.Types.ObjectId, ref: "Course", required: true }, - academy_id: { type: mongoose.Schema.Types.ObjectId, ref: "Academy", required: true }, - user_id: { type: mongoose.Schema.Types.ObjectId, ref: "User", required: true }, - payment_authority: { type: String }, - payment_ref_id: { type: String }, - status: { type: String, enum: ["pending", "success", "failed", "settled"], default: "success" }, - - -}); - -modelSchema.plugin(timestamp); -modelSchema.plugin(mongoosePaginate); -const PostModel = mongoose.model("AcademyPayment", modelSchema); -module.exports = PostModel; diff --git a/public/modstagram-back/controllers/application/academy/models/AdminModel.js b/public/modstagram-back/controllers/application/academy/models/AdminModel.js deleted file mode 100644 index 4bca3a2..0000000 --- a/public/modstagram-back/controllers/application/academy/models/AdminModel.js +++ /dev/null @@ -1,80 +0,0 @@ -const mongoose = require('mongoose') -const mongoosePaginate = require('mongoose-paginate-v2') -const timestamp = require('mongoose-timestamp') -const adminSchema = new mongoose.Schema({ - mobile: { - type: String, - required: false, - trim: true, - unique: true - }, - otp: { - type: String, - required: false, - trim: true, - minLength: 6, - maxLength: 6 - }, - user_name: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - password: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - first_name: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - last_name: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - user_type: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - profile_image: { - type: String, - required: false, - trim: true - }, - gender: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - last_online: { - type: Date, // ذخیره تاریخ و زمان آخرین بازدید - default: Date.now // تنظیم تاریخ به تاریخ فعلی - } -}) - -adminSchema.plugin(timestamp) -adminSchema.plugin(mongoosePaginate) -const AdminModel = mongoose.model('Admin', adminSchema) -module.exports = AdminModel diff --git a/public/modstagram-back/controllers/application/academy/models/AdvertisingCategoryModel.js b/public/modstagram-back/controllers/application/academy/models/AdvertisingCategoryModel.js deleted file mode 100644 index 855035a..0000000 --- a/public/modstagram-back/controllers/application/academy/models/AdvertisingCategoryModel.js +++ /dev/null @@ -1,23 +0,0 @@ -const mongoose = require('mongoose') -const mongoosePaginate = require('mongoose-paginate-v2') -const timestamp = require('mongoose-timestamp') -const advertisingCategorySchema = new mongoose.Schema({ - title: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - status: { - type: Boolean, - required: false, - default: true - } -}) - -advertisingCategorySchema.plugin(timestamp) -advertisingCategorySchema.plugin(mongoosePaginate) -const AdvertisingCategoryModel = mongoose.model('AdvertisingCategory', advertisingCategorySchema) -module.exports = AdvertisingCategoryModel diff --git a/public/modstagram-back/controllers/application/academy/models/AdvertisingCommentModel.js b/public/modstagram-back/controllers/application/academy/models/AdvertisingCommentModel.js deleted file mode 100644 index f6ea2b4..0000000 --- a/public/modstagram-back/controllers/application/academy/models/AdvertisingCommentModel.js +++ /dev/null @@ -1,32 +0,0 @@ -const mongoose = require('mongoose') -const timestamp = require('mongoose-timestamp') -const mongoosePaginate = require('mongoose-paginate-v2') - -const advertisingCommentSchema = new mongoose.Schema({ - advertisingId: { - type: mongoose.Schema.Types.ObjectId, - ref: 'Advertising', - required: true - }, - userId: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: true - }, - text: { - type: String, - required: true, - trim: true - }, - status: { - type: String, - enum: ['pending', 'accepted', 'rejected'], - default: 'pending' - } -}) - -advertisingCommentSchema.plugin(timestamp) -advertisingCommentSchema.plugin(mongoosePaginate) -const AdvertisingComment = mongoose.model('AdvertisingComment', advertisingCommentSchema) - -module.exports = AdvertisingComment diff --git a/public/modstagram-back/controllers/application/academy/models/AdvertisingFeaturesModel.js b/public/modstagram-back/controllers/application/academy/models/AdvertisingFeaturesModel.js deleted file mode 100644 index 4081d59..0000000 --- a/public/modstagram-back/controllers/application/academy/models/AdvertisingFeaturesModel.js +++ /dev/null @@ -1,27 +0,0 @@ -const mongoose = require('mongoose') -const mongoosePaginate = require('mongoose-paginate-v2') -const timestamp = require('mongoose-timestamp') -const advertisingFeaturesSchema = new mongoose.Schema({ - title: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - status: { - type: Boolean, - required: false, - default: true - }, - type: { - type: String, - default: 'boolean' - } -}) - -advertisingFeaturesSchema.plugin(timestamp) -advertisingFeaturesSchema.plugin(mongoosePaginate) -const AdvertisingFeaturesModel = mongoose.model('AdvertisingFeatures', advertisingFeaturesSchema) -module.exports = AdvertisingFeaturesModel diff --git a/public/modstagram-back/controllers/application/academy/models/AdvertisingLikeModel.js b/public/modstagram-back/controllers/application/academy/models/AdvertisingLikeModel.js deleted file mode 100644 index f8552dd..0000000 --- a/public/modstagram-back/controllers/application/academy/models/AdvertisingLikeModel.js +++ /dev/null @@ -1,20 +0,0 @@ -const mongoose = require('mongoose') - -const advertisingLikeSchema = new mongoose.Schema({ - advertisingId: { - type: mongoose.Schema.Types.ObjectId, - ref: 'Advertising', - required: true - }, - userId: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: true - } - -}) - -// تعریف مدل AdvertisingLikeModel -const AdvertisingLikeModel = mongoose.model('AdvertisingLike', advertisingLikeSchema) - -module.exports = AdvertisingLikeModel diff --git a/public/modstagram-back/controllers/application/academy/models/AdvertisingModel.js b/public/modstagram-back/controllers/application/academy/models/AdvertisingModel.js deleted file mode 100644 index 3046a48..0000000 --- a/public/modstagram-back/controllers/application/academy/models/AdvertisingModel.js +++ /dev/null @@ -1,230 +0,0 @@ -const mongoose = require('mongoose') -const mongoosePaginate = require('mongoose-paginate-v2') -const timestamp = require('mongoose-timestamp') -const advertisingSchema = new mongoose.Schema({ - title: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - category: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - description: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 1024, - default: null - }, - province: { - type: Object, - default: null - }, - city: { - type: Object, - default: null - }, - neighbourhood: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - address: { - type: String, - trim: true, - minLength: 1, - maxLength: 512, - default: null - }, - lat: { - type: String, - trim: true, - minLength: 1, - maxLength: 256, - default: null - }, - lng: { - type: String, - trim: true, - minLength: 1, - maxLength: 256, - default: null - }, - images: [{ - type: String, - required: false, - trim: true, - default: null - }], - services: [{ - title: { - type: String, - required: true, - trim: true - }, - originalPrice: { - type: String, - required: true - }, - discountPrice: { - type: String, - required: false - }, - discountPercentage: { - type: Number, - required: false - }, - status: { - type: String, - default: "UnderReview", - required: false - }, - image: { - type: String, - required: false, - trim: true - } - }], - features: [{ - title: { - type: String, - required: false, - trim: true - }, - value: { - type: Boolean, - required: true - } - }], - contactInfo: { - phone: { - type: String, - required: false, - trim: true, - default: null - }, - mobile: { - type: String, - required: false, - trim: true, - default: null - }, - telegramLink: { - type: String, - required: false, - trim: true, - default: null - }, - whatsappNumber: { - type: String, - required: false, - trim: true, - default: null - }, - instagramLink: { - type: String, - required: false, - trim: true, - default: null - }, - saveInfoForNextAds: { - type: Boolean, - required: true, - default: false - } - }, - type: { - type: String, - enum: ['free', 'normal', 'special', 'highlight'], - default: 'normal' - }, - status: { - type: String, - enum: ['pre_payment', 'paid', 'accepted', 'rejected', 'expired'], - default: 'pre_payment' - }, - payment_status: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - creator_id: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User' - }, - reject_reason: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 1024, - default: null - }, - mostDiscountPercentage: { - type: Number, - required: false - }, - showDiscount: { - type: Boolean, - required: false, - default: false - }, - likesCount: { - type: Number, - default: 0 - }, - commentsCount: { - type: Number, - default: 0 - }, - ratings: [{ - userId: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: true - }, - rating: { - type: Number, - required: true, - min: 1, - max: 5 - } - }], - averageRating: { - type: Number, - default: 0 - }, - ratingsCount: { - type: Number, - default: 0 - }, - viewCount: { - type: Number, - default: 0 - }, - acceptedAt: { - type: Date, - default: null - } -}) - -advertisingSchema.plugin(timestamp) -advertisingSchema.plugin(mongoosePaginate) -const AdvertisingModel = mongoose.model('Advertising', advertisingSchema) -module.exports = AdvertisingModel diff --git a/public/modstagram-back/controllers/application/academy/models/AdvertisingProfile.js b/public/modstagram-back/controllers/application/academy/models/AdvertisingProfile.js deleted file mode 100644 index 70dfc5a..0000000 --- a/public/modstagram-back/controllers/application/academy/models/AdvertisingProfile.js +++ /dev/null @@ -1,113 +0,0 @@ -const mongoose = require('mongoose') -const timestamp = require('mongoose-timestamp') -const mongoosePaginate = require('mongoose-paginate-v2') - -const advertisingProfileSchema = new mongoose.Schema({ - user: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: true - }, - profile_image: { - type: String, - required: false, - trim: true, - default: null - }, - image_count: { - type: Number, - default: 0 - }, - like_count: { - type: Number, - default: 0 - }, - comment_count: { - type: Number, - default: 0 - }, - vitrine_name: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - category: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - about_us: { - type: String, - required: false, - minLength: 1, - maxLength: 1024, - default: null - }, - province: { - type: Object, - default: null - }, - city: { - type: Object, - default: null - }, - lat: { - type: String, - trim: true, - minLength: 1, - maxLength: 512, - default: null - }, - lng: { - type: String, - trim: true, - minLength: 1, - maxLength: 512, - default: null - }, - address: { - type: String, - required: false, - trim: true, - default: null - }, - neighbourhood: { - type: String, - required: false, - trim: true, - default: null - }, - adTotalRatings: { - type: Number, - default: 0 - }, - adRatingsCount: { - type: Number, - default: 0 - }, - adAverageRating: { - type: Number, - default: 0 - }, - contactInfo: { - phone: String, - mobile: String, - telegramLink: String, - whatsappNumber: String, - instagramLink: String, - saveInfoForNextAds: { type: Boolean, default: false } - } -}) - -advertisingProfileSchema.plugin(timestamp) -advertisingProfileSchema.plugin(mongoosePaginate) - -const AdvertisingProfileModel = mongoose.model('AdvertisingProfile', advertisingProfileSchema) - -module.exports = AdvertisingProfileModel diff --git a/public/modstagram-back/controllers/application/academy/models/AdvertisingRatingModel.js b/public/modstagram-back/controllers/application/academy/models/AdvertisingRatingModel.js deleted file mode 100644 index ac8b79b..0000000 --- a/public/modstagram-back/controllers/application/academy/models/AdvertisingRatingModel.js +++ /dev/null @@ -1,26 +0,0 @@ -const mongoose = require('mongoose') -const timestamp = require('mongoose-timestamp') - -const advertisingRatingSchema = new mongoose.Schema({ - advertisingId: { - type: mongoose.Schema.Types.ObjectId, - ref: 'Advertising', - required: true - }, - userId: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: true - }, - rating: { - type: Number, - required: true, - min: 1, - max: 5 - } -}) - -advertisingRatingSchema.plugin(timestamp) - -const AdvertisingRatingModel = mongoose.model('AdvertisingRating', advertisingRatingSchema) -module.exports = AdvertisingRatingModel diff --git a/public/modstagram-back/controllers/application/academy/models/AdvertisingTypeModel.js b/public/modstagram-back/controllers/application/academy/models/AdvertisingTypeModel.js deleted file mode 100644 index 5b49649..0000000 --- a/public/modstagram-back/controllers/application/academy/models/AdvertisingTypeModel.js +++ /dev/null @@ -1,25 +0,0 @@ -const mongoose = require('mongoose') - -const advertisingTypeSchema = new mongoose.Schema({ - name: { - type: String, - required: true, - trim: true, - minLength: 1, - maxLength: 255 - }, - price: { - type: Number, - required: true, - trim: true, - minLength: 1, - maxLength: 255 - }, - status: { - type: String, - default: 'active' - } -}) - -const AdvertisingTypeModel = mongoose.model('AdvertisingType', advertisingTypeSchema) -module.exports = AdvertisingTypeModel diff --git a/public/modstagram-back/controllers/application/academy/models/CommentModel.js b/public/modstagram-back/controllers/application/academy/models/CommentModel.js deleted file mode 100644 index 5fbabc9..0000000 --- a/public/modstagram-back/controllers/application/academy/models/CommentModel.js +++ /dev/null @@ -1,54 +0,0 @@ -const mongoose = require('mongoose') -const timestamp = require('mongoose-timestamp') -const mongoosePaginate = require('mongoose-paginate-v2') - -const commentSchema = new mongoose.Schema({ - user: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: true - }, - project: { - type: mongoose.Schema.Types.ObjectId, - ref: 'Project', - required: false - }, - offer: { - type: mongoose.Schema.Types.ObjectId, - ref: 'Offer', - required: false - }, - creator: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: true - }, - rating: { - type: Number, - required: true - }, - comment: { - type: String, - trim: true - }, - post: { - type: mongoose.Schema.Types.ObjectId, - ref: 'Post', - required: false - }, - comment_for: { - type: String, - enum: ['user', 'project', 'post'], - required: true - }, - status: { - type: String, - enum: ['pending', 'accepted', 'rejected'], - default: 'pending' - } -}) - -commentSchema.plugin(timestamp) -commentSchema.plugin(mongoosePaginate) -const CommentModel = mongoose.model('Comment', commentSchema) -module.exports = CommentModel diff --git a/public/modstagram-back/controllers/application/academy/models/CourseComentModel.js b/public/modstagram-back/controllers/application/academy/models/CourseComentModel.js deleted file mode 100644 index b5c7d5c..0000000 --- a/public/modstagram-back/controllers/application/academy/models/CourseComentModel.js +++ /dev/null @@ -1,40 +0,0 @@ -const mongoose = require("mongoose"); -const timestamp = require("mongoose-timestamp"); -const mongoosePaginate = require("mongoose-paginate-v2"); - -const modelSchema = new mongoose.Schema({ - - user_id: { - type: String, - required: true, - trim: true, - }, - course_id: { - type: String, - required: true, - trim: true, - }, - comment: { - type: String, - required: true, - trim: true, - default: 0, - }, - rate: { - type: String, - required: true, - trim: true, - default: 0, - }, - status: { - type: String, - enum: ['pending', 'accepted', 'rejected'], - default: 'accepted' - } - -}); - -modelSchema.plugin(timestamp); -modelSchema.plugin(mongoosePaginate); -const PostModel = mongoose.model("CourseComment", modelSchema); -module.exports = PostModel; diff --git a/public/modstagram-back/controllers/application/academy/models/CourseModel.js b/public/modstagram-back/controllers/application/academy/models/CourseModel.js deleted file mode 100644 index f8a5e67..0000000 --- a/public/modstagram-back/controllers/application/academy/models/CourseModel.js +++ /dev/null @@ -1,79 +0,0 @@ -const mongoose = require("mongoose"); -const timestamp = require("mongoose-timestamp"); -const mongoosePaginate = require("mongoose-paginate-v2"); - -const modelSchema = new mongoose.Schema({ - price: { - type: String, - required: true, - }, - cuorse_name: { - type: String, - required: true, - }, - category:{ - type: String - }, - offer: { - type: String - }, - academyId:{ - type: String - }, - caption: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 1000, - default: null, - }, - status: { - type: String, - required: false, - trim: true, - enum: ['pending', 'accept', 'reject'], - default: 'accept', - }, - user_id: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - }, - likes: { - type: Number, - required: false, - trim: true, - default: 0, - }, - comments: { - type: Object, - default: null, - }, - type: { - type: String, - required: false, - trim: true, - enum: ['normal', 'pro', 'legend'], - default: "normal", - }, - course_time: { - type: String - }, - number_of_course_content: { - type: String - }, - teacher_number: { - type: String - }, - course_image: { - type: String - }, - teacher_name: { - type: String - }, -}); - -modelSchema.plugin(timestamp); -modelSchema.plugin(mongoosePaginate); -const PostModel = mongoose.model("Course", modelSchema); -module.exports = PostModel; diff --git a/public/modstagram-back/controllers/application/academy/models/CoursePaymentModel.js b/public/modstagram-back/controllers/application/academy/models/CoursePaymentModel.js deleted file mode 100644 index cb6de53..0000000 --- a/public/modstagram-back/controllers/application/academy/models/CoursePaymentModel.js +++ /dev/null @@ -1,22 +0,0 @@ -const mongoose = require("mongoose"); -const timestamp = require("mongoose-timestamp"); -const mongoosePaginate = require("mongoose-paginate-v2"); - -const modelSchema = new mongoose.Schema({ - price: { - type: String, - required: true, - }, - cuorse_type: { - type: String, - required: false, - trim: true, - enum: ['normal', 'pro', 'legend'], - }, - -}); - -modelSchema.plugin(timestamp); -modelSchema.plugin(mongoosePaginate); -const PostModel = mongoose.model("CoursePayment", modelSchema); -module.exports = PostModel; diff --git a/public/modstagram-back/controllers/application/academy/models/ExpertiseModel.js b/public/modstagram-back/controllers/application/academy/models/ExpertiseModel.js deleted file mode 100644 index 29b490a..0000000 --- a/public/modstagram-back/controllers/application/academy/models/ExpertiseModel.js +++ /dev/null @@ -1,47 +0,0 @@ -// const mongoose = require('mongoose') -// const timestamp = require('mongoose-timestamp') - -// const subExpertiseSchema = new mongoose.Schema({ -// id: { -// type: mongoose.Schema.Types.ObjectId, -// ref: 'ExpertiseModel' -// }, -// name: { -// type: String -// } -// }) - -// const expertiseSchema = new mongoose.Schema({ -// expertise: { -// type: String, -// unique: true -// }, -// sub_expertise: [subExpertiseSchema] -// }) - -// expertiseSchema.plugin(timestamp) - -// const ExpertiseModel = mongoose.model('Expertise', expertiseSchema) -// module.exports = ExpertiseModel - -const mongoose = require('mongoose') -const timestamp = require('mongoose-timestamp') - -const subExpertiseSchema = new mongoose.Schema({ - name: { - type: String - } -}) - -const expertiseSchema = new mongoose.Schema({ - expertise: { - type: String, - unique: true - }, - sub_expertise: [subExpertiseSchema] -}) - -expertiseSchema.plugin(timestamp) - -const ExpertiseModel = mongoose.model('Expertise', expertiseSchema) -module.exports = ExpertiseModel diff --git a/public/modstagram-back/controllers/application/academy/models/IsPaymentCourseModel.js b/public/modstagram-back/controllers/application/academy/models/IsPaymentCourseModel.js deleted file mode 100644 index 0524f3c..0000000 --- a/public/modstagram-back/controllers/application/academy/models/IsPaymentCourseModel.js +++ /dev/null @@ -1,15 +0,0 @@ -const mongoose = require("mongoose"); -const timestamp = require("mongoose-timestamp"); -const mongoosePaginate = require("mongoose-paginate-v2"); - -const modelSchema = new mongoose.Schema({ - user_id: { type: mongoose.Schema.Types.ObjectId, ref: "User", required: true }, - course_id: { type: mongoose.Schema.Types.ObjectId, ref: "Course", required: true }, - price_paid: { type: Number, required: true }, // قیمت پرداخت شده - purchased_at: { type: Date, default: Date.now }, -}); - -modelSchema.plugin(timestamp); -modelSchema.plugin(mongoosePaginate); -const PostModel = mongoose.model("IsPaymentCourse", modelSchema); -module.exports = PostModel; diff --git a/public/modstagram-back/controllers/application/academy/models/LikeModel.js b/public/modstagram-back/controllers/application/academy/models/LikeModel.js deleted file mode 100644 index 1957530..0000000 --- a/public/modstagram-back/controllers/application/academy/models/LikeModel.js +++ /dev/null @@ -1,25 +0,0 @@ -const mongoose = require('mongoose') -const timestamp = require('mongoose-timestamp') - -const likeSchema = new mongoose.Schema({ - postId: { - type: mongoose.Schema.Types.ObjectId, - ref: 'Post', - required: true - }, - userId: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: true - }, - likes: [{ - type: mongoose.Schema.Types.ObjectId, - ref: 'User' - }] -}) - -// تعریف مدل LikeModel -likeSchema.plugin(timestamp) -const LikeModel = mongoose.model('Like', likeSchema) - -module.exports = LikeModel diff --git a/public/modstagram-back/controllers/application/academy/models/MessageModel.js b/public/modstagram-back/controllers/application/academy/models/MessageModel.js deleted file mode 100644 index 594f7c4..0000000 --- a/public/modstagram-back/controllers/application/academy/models/MessageModel.js +++ /dev/null @@ -1,51 +0,0 @@ -const mongoose = require('mongoose') -const { Schema } = mongoose - -const messageSchema = new Schema({ - senderId: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: true - }, - receiverId: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: true - }, - content: { - type: String, - required: false, - trim: true - }, - file: { - type: String, - required: false - }, - fileType: { - type: String, - enum: ['image', 'video', 'file', 'voice', 'location'], - required: false - }, - replyToId: { - type: mongoose.Schema.Types.ObjectId, - ref: 'Message', - required: false - }, - forwardedFrom: { - userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }, - userName: String, - displayName: String - }, - createdAt: { - type: Date, - default: Date.now - }, - readStatus: { - type: Number, - default: 0 - } -}) - -const MessageModel = mongoose.model('Message', messageSchema) - -module.exports = MessageModel diff --git a/public/modstagram-back/controllers/application/academy/models/NotificationModel.js b/public/modstagram-back/controllers/application/academy/models/NotificationModel.js deleted file mode 100644 index ff79e19..0000000 --- a/public/modstagram-back/controllers/application/academy/models/NotificationModel.js +++ /dev/null @@ -1,37 +0,0 @@ -const mongoose = require('mongoose') -const timestamp = require('mongoose-timestamp') -const mongoosePaginate = require('mongoose-paginate-v2') - -const notificationSchema = new mongoose.Schema({ - user_id: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', // مرجع به مدل کاربر - required: true - }, - project_post_id: { - type: mongoose.Schema.Types.ObjectId, - required: false - }, - type: { - type: String, - required: true - }, - title: { - type: String, - required: true - }, - description: { - type: String, - required: true - }, - read: { - type: Boolean, - default: false // وضعیت خوانده شده یا نشده - } -}) - -notificationSchema.plugin(timestamp) -notificationSchema.plugin(mongoosePaginate) - -const NotificationModel = mongoose.model('Notification', notificationSchema) -module.exports = NotificationModel diff --git a/public/modstagram-back/controllers/application/academy/models/OfferModel.js b/public/modstagram-back/controllers/application/academy/models/OfferModel.js deleted file mode 100644 index ec36550..0000000 --- a/public/modstagram-back/controllers/application/academy/models/OfferModel.js +++ /dev/null @@ -1,32 +0,0 @@ -const mongoose = require('mongoose') -const mongoosePaginate = require('mongoose-paginate-v2') -const timestamp = require('mongoose-timestamp') - -const offerSchema = new mongoose.Schema({ - sender: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: true - }, - receiver: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: true - }, - status: { - type: String, - enum: ['pending', 'accepted', 'rejected'], // وضعیت درخواست - default: 'pending' - }, - transaction_id: { - type: mongoose.Schema.Types.ObjectId, - ref: 'Payment', - default: null - } -}) - -offerSchema.plugin(timestamp) -offerSchema.plugin(mongoosePaginate) - -const OfferModel = mongoose.model('Offer', offerSchema) -module.exports = OfferModel diff --git a/public/modstagram-back/controllers/application/academy/models/OfferTypeModel.js b/public/modstagram-back/controllers/application/academy/models/OfferTypeModel.js deleted file mode 100644 index fa2b49c..0000000 --- a/public/modstagram-back/controllers/application/academy/models/OfferTypeModel.js +++ /dev/null @@ -1,21 +0,0 @@ -const mongoose = require('mongoose') - -const offerTypeModelSchema = new mongoose.Schema({ - name: { - type: String, - required: true, - trim: true, - minLength: 1, - maxLength: 255 - }, - price: { - type: Number, - required: true, - trim: true, - minLength: 1, - maxLength: 255 - } -}) - -const OfferTypeModel = mongoose.model('OfferTypeModel', offerTypeModelSchema) -module.exports = OfferTypeModel diff --git a/public/modstagram-back/controllers/application/academy/models/PaymentModel.js b/public/modstagram-back/controllers/application/academy/models/PaymentModel.js deleted file mode 100644 index c78a252..0000000 --- a/public/modstagram-back/controllers/application/academy/models/PaymentModel.js +++ /dev/null @@ -1,46 +0,0 @@ -const mongoose = require('mongoose') -const timestamp = require('mongoose-timestamp') -const mongoosePaginate = require('mongoose-paginate-v2') - -const paymentSchema = new mongoose.Schema({ - amount: { - type: Number, - required: true - }, - status: { - type: String, - enum: ['pending', 'successful', 'failed'], - default: 'pending' - }, - authority: { - type: String, - required: false - }, - user_id: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User' - }, - project_id: { - type: mongoose.Schema.Types.ObjectId, - ref: 'Project' - }, - advertising_id: { - type: mongoose.Schema.Types.ObjectId, - ref: 'Advertising' - }, - type: { - type: String, - required: true - }, - installment_step: { - type: String, - required: false, - default: null - } -}) - -paymentSchema.plugin(timestamp) -paymentSchema.plugin(mongoosePaginate) - -const PaymentModel = mongoose.model('Payment', paymentSchema) -module.exports = PaymentModel diff --git a/public/modstagram-back/controllers/application/academy/models/PostModel.js b/public/modstagram-back/controllers/application/academy/models/PostModel.js deleted file mode 100644 index ff6d8cc..0000000 --- a/public/modstagram-back/controllers/application/academy/models/PostModel.js +++ /dev/null @@ -1,60 +0,0 @@ -const mongoose = require('mongoose'); -const timestamp = require('mongoose-timestamp'); -const mongoosePaginate = require('mongoose-paginate-v2'); - -const modelSchema = new mongoose.Schema({ - post_images: { - type: [String], // آرایه‌ای از مسیرهای تصاویر - required: false, - default: [], - }, - post_video: { - type: String, // مسیر ویدئو - required: false, - trim: true, - default: null, - }, - type: { - type: String, // نوع پست: 'image' یا 'video' - required: true, - enum: ['image', 'video'], - }, - files: [ - { - path: { type: String, required: true }, - type: { type: String, enum: ['image', 'video'], required: true }, - } - ], - caption: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 1000, - default: null, - }, - status: { - type: String, - required: false, - trim: true, - enum: ['pending', 'accept', 'reject'], - default: 'pending', - }, - user_id: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - }, - likes: [{ - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - }], - comments: { - type: Object, - default: null, - }, -}); - -modelSchema.plugin(timestamp); -modelSchema.plugin(mongoosePaginate); -const PostModel = mongoose.model('Post', modelSchema); -module.exports = PostModel; \ No newline at end of file diff --git a/public/modstagram-back/controllers/application/academy/models/ProjectModel.js b/public/modstagram-back/controllers/application/academy/models/ProjectModel.js deleted file mode 100644 index 4b4382e..0000000 --- a/public/modstagram-back/controllers/application/academy/models/ProjectModel.js +++ /dev/null @@ -1,186 +0,0 @@ -const mongoose = require('mongoose') -const timestamp = require('mongoose-timestamp') -const mongoosePaginate = require('mongoose-paginate-v2') -const projectSchema = new mongoose.Schema({ - title: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - expertise: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - sub_expertise: { - type: [String], // تغییر نوع به آرایه از استرینگ - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - gender: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - age: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - conversation_projects: { - type: Boolean, - required: false, - default: null - }, - province: { - type: Object, - default: null - }, - city: { - type: Object, - default: null - }, - offer_time: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - offer_price: { - type: Number, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - description: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 1024, - default: null - }, - project_type: { - type: String, - enum: ['free', 'normal', 'force', 'highlight'], - default: 'normal' - }, - payment_status: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - // فیلد برای وضعیت پروژه - status: { - type: String, - enum: ['pre_payment', 'paid', 'accepted', 'rejected', 'done', 'cancled', 'ongoing'], - default: 'pre_payment' - }, - public_status: { - type: String, - enum: ['public', 'private'], - default: 'public' - }, - created_for_user: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - default: null - }, - creator_id: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User' - }, - requested_users: [{ - type: mongoose.Schema.Types.ObjectId, - ref: 'User' - }], - selected_user: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - default: null - }, - final_price: { - type: Number, - required: false, - default: null - }, - final_time: { - type: Number, - required: false, - default: null - }, - installments: [{ - installment_number: { - type: Number, - required: true - }, - amount: { - type: Number, - required: true - }, - due_date: { - type: Date, - required: true - } - }], - reject_reason: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 1024, - default: null - }, - ratings: [{ - creator_id: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: true - }, - rating: { - type: Number, - required: true - }, - comment: { - type: String, - trim: true - } - }], - acceptedAt: { - type: Date, - default: null - }, - isExpired: { - type: Boolean, - default: false - } - -}) - -projectSchema.plugin(timestamp) -// اضافه کردن پیجینیشن به مدل -projectSchema.plugin(mongoosePaginate) -const ProjectModel = mongoose.model('Project', projectSchema) -module.exports = ProjectModel diff --git a/public/modstagram-back/controllers/application/academy/models/RequestModel.js b/public/modstagram-back/controllers/application/academy/models/RequestModel.js deleted file mode 100644 index 3049ec1..0000000 --- a/public/modstagram-back/controllers/application/academy/models/RequestModel.js +++ /dev/null @@ -1,33 +0,0 @@ -const mongoose = require('mongoose') -const timestamp = require('mongoose-timestamp') - -const requestSchema = new mongoose.Schema({ - project: { - type: mongoose.Schema.Types.ObjectId, - ref: 'Project', - required: true - }, - user: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: true - }, - time: { - type: Number, - required: true - }, - price: { - type: Number, - required: true - }, - status: { - type: String, - enum: ['pending', 'accepted', 'rejected'], - default: 'pending' - } -}) - -requestSchema.plugin(timestamp) - -const RequestModel = mongoose.model('Request', requestSchema) -module.exports = RequestModel diff --git a/public/modstagram-back/controllers/application/academy/models/SettingsModel.js b/public/modstagram-back/controllers/application/academy/models/SettingsModel.js deleted file mode 100644 index 8d41208..0000000 --- a/public/modstagram-back/controllers/application/academy/models/SettingsModel.js +++ /dev/null @@ -1,19 +0,0 @@ -// models/Setting.js -const mongoose = require('mongoose') -const timestamp = require('mongoose-timestamp') - -const settingSchema = new mongoose.Schema({ - key: { - type: String, - required: true, - unique: true - }, - value: { - type: String, - required: true - } -}) -settingSchema.plugin(timestamp) - -const SettingModel = mongoose.model('Setting', settingSchema) -module.exports = SettingModel diff --git a/public/modstagram-back/controllers/application/academy/models/StateCity.js b/public/modstagram-back/controllers/application/academy/models/StateCity.js deleted file mode 100644 index 5f24232..0000000 --- a/public/modstagram-back/controllers/application/academy/models/StateCity.js +++ /dev/null @@ -1,19 +0,0 @@ -const mongoose = require('mongoose') - -const provincesSchema = new mongoose.Schema({ - id: Number, - name: String, - slug: String -}) - -const citiesSchema = new mongoose.Schema({ - id: Number, - name: String, - slug: String, - province_id: Number -}) - -const ProvinceModel = mongoose.model('Province', provincesSchema) -const CityModel = mongoose.model('City', citiesSchema) - -module.exports = { ProvinceModel, CityModel } diff --git a/public/modstagram-back/controllers/application/academy/models/TaxModel.js b/public/modstagram-back/controllers/application/academy/models/TaxModel.js deleted file mode 100644 index 70b27e7..0000000 --- a/public/modstagram-back/controllers/application/academy/models/TaxModel.js +++ /dev/null @@ -1,15 +0,0 @@ -const mongoose = require("mongoose"); -const timestamp = require("mongoose-timestamp"); -const mongoosePaginate = require("mongoose-paginate-v2"); - -const modelSchema = new mongoose.Schema({ - type: { type: String, enum: ["course", "product", "service"], required: true }, - tax: { type: Number, required: true, default: 9 }, // درصد مالیات - is_active: { type: Boolean, default: true }, - -}); - -modelSchema.plugin(timestamp); -modelSchema.plugin(mongoosePaginate); -const PostModel = mongoose.model("Tax", modelSchema); -module.exports = PostModel; diff --git a/public/modstagram-back/controllers/application/academy/models/TicketMessageModel.js b/public/modstagram-back/controllers/application/academy/models/TicketMessageModel.js deleted file mode 100644 index b054d05..0000000 --- a/public/modstagram-back/controllers/application/academy/models/TicketMessageModel.js +++ /dev/null @@ -1,20 +0,0 @@ -const mongoose = require('mongoose') -const timestamp = require('mongoose-timestamp') -const mongoosePaginate = require('mongoose-paginate-v2') - -const ticketMessageSchema = new mongoose.Schema({ - text: { type: String, required: false }, - file: { - type: String, // مسیر فایل در ذخیره شود - required: false // فایل اختیاری است - }, - senderType: { type: String, enum: ['User', 'Admin'], required: true }, - senderId: { type: mongoose.Schema.Types.ObjectId, refPath: 'senderType', required: true }, - ticket: { type: mongoose.Schema.Types.ObjectId, ref: 'Ticket', required: true } -}) - -ticketMessageSchema.plugin(timestamp) -// اضافه کردن پیجینیشن به مدل -ticketMessageSchema.plugin(mongoosePaginate) -const TicketMessageModel = mongoose.model('TicketMessage', ticketMessageSchema) -module.exports = TicketMessageModel diff --git a/public/modstagram-back/controllers/application/academy/models/TicketModel.js b/public/modstagram-back/controllers/application/academy/models/TicketModel.js deleted file mode 100644 index 4157fb3..0000000 --- a/public/modstagram-back/controllers/application/academy/models/TicketModel.js +++ /dev/null @@ -1,24 +0,0 @@ -const mongoose = require('mongoose') -const timestamp = require('mongoose-timestamp') -const mongoosePaginate = require('mongoose-paginate-v2') - -const ticketSchema = new mongoose.Schema({ - title: { type: String, required: true }, - status: { type: String, enum: ['Pending', 'Answered', 'Customer Response', 'Closed'], default: 'Pending' }, - user: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true }, - new_message: { - type: Boolean, - default: false // وضعیت خوانده شده یا نشده - } -}) - -ticketSchema.pre('save', function (next) { - this.updatedAt = Date.now() - next() -}) - -ticketSchema.plugin(timestamp) -// اضافه کردن پیجینیشن به مدل -ticketSchema.plugin(mongoosePaginate) -const TicketModel = mongoose.model('Ticket', ticketSchema) -module.exports = TicketModel diff --git a/public/modstagram-back/controllers/application/academy/models/TypeAndPriceModel.js b/public/modstagram-back/controllers/application/academy/models/TypeAndPriceModel.js deleted file mode 100644 index 2b059d1..0000000 --- a/public/modstagram-back/controllers/application/academy/models/TypeAndPriceModel.js +++ /dev/null @@ -1,21 +0,0 @@ -const mongoose = require('mongoose') - -const typeAndPriceSchema = new mongoose.Schema({ - name: { - type: String, - required: true, - trim: true, - minLength: 1, - maxLength: 255 - }, - price: { - type: Number, - required: true, - trim: true, - minLength: 1, - maxLength: 255 - } -}) - -const TypeAndPriceModel = mongoose.model('TypeAndPrice', typeAndPriceSchema) -module.exports = TypeAndPriceModel diff --git a/public/modstagram-back/controllers/application/academy/models/UserModel.js b/public/modstagram-back/controllers/application/academy/models/UserModel.js deleted file mode 100644 index 66b025a..0000000 --- a/public/modstagram-back/controllers/application/academy/models/UserModel.js +++ /dev/null @@ -1,381 +0,0 @@ -const mongoose = require('mongoose') -const mongoosePaginate = require('mongoose-paginate-v2') -const timestamp = require('mongoose-timestamp') -const userSchema = new mongoose.Schema({ - mobile: { - type: String, - required: false, - trim: true, - unique: true - }, - otp: { - type: String, - required: false, - trim: true, - minLength: 6, - maxLength: 6, - default: null - }, - user_name: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - password: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - first_name: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - last_name: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - user_type: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - is_verified: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: 'none' - }, - profile_image: { - type: String, - required: false, - trim: true, - default: null - }, - national_card_image: { - type: String, - required: false, - trim: true, - default: null - }, - expertise: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - sub_expertise: { - type: [String], // تغییر نوع به آرایه از استرینگ - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - gender: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - height: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - weight: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - size: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - eye_color: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - hair_color: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - cooperation_type: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - cooperation_abroad: { - type: Boolean, - required: false, - default: null - }, - conversation_projects: { - type: Boolean, - required: false, - default: null - }, - bio: { - type: String, - required: false, - minLength: 1, - maxLength: 1024, - default: null - }, - national_code: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - birthday: { - type: Date, - required: false, - default: null - }, - is_Register: { - type: String, - - default: false - }, - shaba: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - address: { - type: String, - trim: true, - minLength: 1, - maxLength: 512, - default: null - }, - province: { - type: Object, - default: null - }, - city: { - type: Object, - default: null - }, - lat: { - type: String, - trim: true, - minLength: 1, - maxLength: 512, - default: null - }, - lng: { - type: String, - trim: true, - minLength: 1, - maxLength: 512, - default: null - }, - show_location: { - type: Boolean, - required: false, - default: null - }, - rate: { - type: String, - trim: true, - maxLength: 512, - default: null - }, - referral_code: { - type: String, - trim: true, - minLength: 1, - maxLength: 512, - default: null - }, - shop_id: { - type: mongoose.Schema.Types.ObjectId, - ref: 'Shop', - default: null - }, - last_online: { - type: Date, // ذخیره تاریخ و زمان آخرین بازدید - default: Date.now // تنظیم تاریخ به تاریخ فعلی - }, - business_license: { - type: String, - required: false, - trim: true, - default: null - }, - user_level: { - type: String, - trim: true, - minLength: 1, - maxLength: 512, - default: null - }, - user_score: { - type: String, - trim: true, - minLength: 1, - maxLength: 512, - default: null - }, - last_post: { - type: Object, - default: null - }, - // user_ratings: [{ - // project_id: { - // type: mongoose.Schema.Types.ObjectId, - // ref: 'Project', - // required: true - // }, - // creator_id: { - // type: mongoose.Schema.Types.ObjectId, - // ref: 'User', - // required: true - // }, - // rating: { - // type: Number, - // required: true - // }, - // comment: { - // type: String, - // trim: true - // } - // }], - daily_free_request: { - type: Number, - default: 1 - }, - last_free_request_date: { - type: Date, - default: null - }, - blocked_by: [{ - type: mongoose.Schema.Types.ObjectId, - ref: 'User' - }], - blocked_users: [{ - type: mongoose.Schema.Types.ObjectId, - ref: 'User' - }], - block_status: { - type: Boolean, - required: false, - default: null - }, - advertising_profiles: [{ - type: mongoose.Schema.Types.ObjectId, - ref: 'AdvertisingProfile' - }], - services: [{ - title: { - type: String, - required: true, - trim: true - }, - originalPrice: { - type: String, - required: true - }, - discountPrice: { - type: String, - required: false - }, - discountPercentage: { - type: Number, - required: false - }, - status: { - type: String, - default: "UnderReview", - required: false - }, - image: { - type: String, - required: false, - trim: true - } - }], - monthly_free_offer: { - type: Number, - default: 1 - }, - last_free_offer_date: { - type: Date, - default: null - } - // contactInfo: { - // phone: String, - // mobile: String, - // telegramLink: String, - // whatsappNumber: String, - // instagramLink: String, - // saveInfoForNextAds: { type: Boolean, default: false } - // }, - // adTotalRatings: { - // type: Number, - // default: 0 - // }, - // adRatingsCount: { - // type: Number, - // default: 0 - // }, - // adAverageRating: { - // type: Number, - // default: 0 - // } -}) - -userSchema.plugin(timestamp) -userSchema.plugin(mongoosePaginate) -const UserModel = mongoose.model('User', userSchema) -module.exports = UserModel diff --git a/public/modstagram-back/controllers/application/academy/models/VersionModel.js b/public/modstagram-back/controllers/application/academy/models/VersionModel.js deleted file mode 100644 index 51aaf0b..0000000 --- a/public/modstagram-back/controllers/application/academy/models/VersionModel.js +++ /dev/null @@ -1,12 +0,0 @@ -// models/VersionModel.js -const mongoose = require('mongoose') - -const versionSchema = new mongoose.Schema({ - version: { type: String, required: true }, - mandatory: { type: Boolean, required: true }, - releaseNotes: { type: String }, - updateUrls: { type: [String], required: true } // لینک‌های آپدیت -}) - -const VersionModel = mongoose.model('Version', versionSchema) -module.exports = VersionModel diff --git a/public/modstagram-back/controllers/application/academy/models/license.js b/public/modstagram-back/controllers/application/academy/models/license.js deleted file mode 100644 index 13c59a2..0000000 --- a/public/modstagram-back/controllers/application/academy/models/license.js +++ /dev/null @@ -1,14 +0,0 @@ -const mongoose = require('mongoose') -const mongoosePaginate = require('mongoose-paginate-v2') -const timestamp = require('mongoose-timestamp') -const license = new mongoose.Schema({ - - userId : String, - Confirmation : { type : Boolean, default : false}, - licenseImg : { type : String }, -}) - -license.plugin(timestamp) -license.plugin(mongoosePaginate) -const LicenseMoldel = mongoose.model('license', license) -module.exports = LicenseMoldel diff --git a/public/modstagram-back/controllers/application/advertising/advertisingController.js b/public/modstagram-back/controllers/application/advertising/advertisingController.js deleted file mode 100644 index 59d3667..0000000 --- a/public/modstagram-back/controllers/application/advertising/advertisingController.js +++ /dev/null @@ -1,1414 +0,0 @@ -/* eslint-disable eqeqeq */ -/* eslint-disable camelcase */ -const jwt = require('jsonwebtoken') -const { check, validationResult } = require('express-validator') -const { ProvinceModel, CityModel } = require('../../../models/StateCity') -const UserModel = require('../../../models/UserModel') -const AdvertisingModel = require('../../../models/AdvertisingModel') -const fs = require('fs-extra') -const path = require('path') -const AdvertisingTypeModel = require('../../../models/AdvertisingTypeModel') -const AdvertisingCategoryModel = require('../../../models/AdvertisingCategoryModel') -const AdvertisingFeaturesModel = require('../../../models/AdvertisingFeaturesModel') -const AdvertisingLikeModel = require('../../../models/AdvertisingLikeModel') -const AdvertisingComment = require('../../../models/AdvertisingCommentModel') -const AdvertisingRatingModel = require('../../../models/AdvertisingRatingModel') -const AdvertisingProfileModel = require('../../../models/AdvertisingProfile') - -const createAdvertisingValidationRules = () => { - return [ - check('title').notEmpty().withMessage('عنوان نمی‌تواند خالی باشد'), - check('category').notEmpty().withMessage('دسته‌بندی نمی‌تواند خالی باشد'), - check('province').notEmpty().withMessage('استان نمی‌تواند خالی باشد'), - check('city').notEmpty().withMessage('شهر نمی‌تواند خالی باشد') - ] -} -// تابع کمکی برای ذخیره تصاویر -const saveFile = async (file, folder, userName) => { - const uploadDir = path.join(__dirname, '../../../../storage', folder) - if (!fs.existsSync(uploadDir)) fs.mkdirSync(uploadDir, { recursive: true }) - - const uniqueFileName = `${userName}-${Date.now()}${Math.random().toString().slice(2, 11)}${path.extname(file.name)}` - const filePath = path.join(uploadDir, uniqueFileName) - await fs.move(file.path, filePath) - return `/${folder}/${uniqueFileName}` -} - -const createAdvertising = async (req, res, next) => { - try { - // ✅ بررسی Authorization header - const authHeader = req.header('Authorization') - if (!authHeader) return res.status(401).json({ error: true, message: 'Access Denied' }) - - const token = authHeader.split(' ')[1] - if (!token) return res.status(401).json({ error: true, message: 'Access Denied' }) - - let decodedToken - try { - decodedToken = jwt.verify(token, process.env.APP_SECRET) - } catch (err) { - return res.status(401).json({ error: true, message: 'توکن نامعتبر است' }) - } - - const user = await UserModel.findById(decodedToken.id) - if (!user) return res.status(422).json({ error: true, message: 'شما دسترسی به این بخش ندارید' }) - - // ✅ اعتبارسنجی فرم - const errors = validationResult(req) - if (!errors.isEmpty()) return res.status(422).json({ errors: errors.array() }) - - const { - category, - title, - description, - province, - city, - neighbourhood, - address, - lat, - lng, - services, - features, - contactInfo, - mostDiscountPercentage, - showDiscount, - type - } = req.body - - if (!title || !category || !province || !city) { - return res.status(422).json({ error: true, message: 'اطلاعات ارسالی اشتباه است' }) - } - - const provinceFind = await ProvinceModel.findOne({ id: province }, { _id: 0 }) - const cityFind = await CityModel.findOne({ id: city }) - - // ✅ مدیریت خدمات و تصاویرشان - let parsedServices = [] - try { - parsedServices = services ? JSON.parse(services) : [] - } catch (err) { - return res.status(422).json({ error: true, message: 'فرمت خدمات اشتباه است' }) - } - - const servicesWithImages = [] - for (const service of parsedServices) { - const serviceImages = [] - const serviceId = service.id - const serviceFiles = req.files?.serviceImages?.[serviceId] - const imageFiles = Array.isArray(serviceFiles) ? serviceFiles : serviceFiles ? [serviceFiles] : [] - - for (const file of imageFiles) { - const imageUrl = await saveFile(file, 'services', user.user_name) - serviceImages.push(imageUrl) - service.image = imageUrl - } - servicesWithImages.push({ ...service, images: serviceImages }) - } - - // ✅ مدیریت تصاویر تبلیغ - const imageFiles = Array.isArray(req.files?.images) ? req.files.images : req.files?.images ? [req.files.images] : [] - const images = [] - for (const file of imageFiles) { - const imageUrl = await saveFile(file, 'advertising', user.user_name) - images.push(imageUrl) - } - - // ✅ مدیریت ویژگی‌ها - let parsedFeatures = [] - try { - parsedFeatures = features ? JSON.parse(features) : [] - } catch (err) { - return res.status(422).json({ error: true, message: 'فرمت ویژگی‌ها اشتباه است' }) - } - - // ✅ ایجاد رکورد جدید - const newAd = new AdvertisingModel({ - title, - category, - description, - province: provinceFind, - city: cityFind, - neighbourhood, - address, - lat, - lng, - images, - services: servicesWithImages, - features: parsedFeatures, - contactInfo, - creator_id: user._id, - mostDiscountPercentage, - showDiscount, - type - }) - - await newAd.save() - - // ✅ ذخیره اطلاعات تماس برای استفاده بعدی - if (contactInfo?.saveInfoForNextAds) { - let advertisingProfile = await AdvertisingProfileModel.findOne({ user: user._id }) - if (advertisingProfile) { - advertisingProfile.contactInfo = contactInfo - await advertisingProfile.save() - } else { - advertisingProfile = new AdvertisingProfileModel({ user: user._id, contactInfo }) - await advertisingProfile.save() - } - } - - return res.status(201).json({ - success: true, - message: 'ویترین با موفقیت ایجاد شد', - data: { id: newAd._id } - }) - } catch (error) { - next(error) - } -} -// const getAdvertisings = async (req, res, next) => { -// let previousPage = 0 // تعریف متغیر سراسری برای نگهداری شماره صفحه قبلی - -// try { -// const token = req.header('Authorization').split(' ')[1] -// if (!token) return res.status(401).send('Access Denied') -// const decodedToken = jwt.verify(token, process.env.APP_SECRET) - -// const { page = 1, limit = 10, province, city, category, search } = req.query -// const currentPage = parseInt(page) // شماره صفحه جاری - -// const filter = { -// payment_status: 'done', -// status: 'accepted' -// } -// if (province) { -// const provinceFind = await ProvinceModel.findOne({ id: province }, { _id: 0 }) -// filter.province = provinceFind -// } -// if (city) { -// const cityFind = await CityModel.findOne({ id: city }) -// filter.city = cityFind -// } -// if (category) { -// filter.category = category -// } -// if (search) { -// filter.$or = [ -// { title: { $regex: search, $options: 'i' } }, -// { category: { $regex: search, $options: 'i' } } -// ] -// } -// const options = { -// page: parseInt(page), -// limit: parseInt(limit), -// sort: { acceptedAt: -1, createdAt: -1 } // مرتب‌سازی بر اساس acceptedAt و سپس createdAt -// } -// const advertisings = await AdvertisingModel.paginate(filter, options) - -// // اگر شماره صفحه تغییر کرده بود، تعداد بازدیدها را به روز رسانی کنید -// if (currentPage !== previousPage) { -// await AdvertisingModel.updateMany( -// { _id: { $in: advertisings.docs.map(ad => ad._id) } }, -// { $inc: { viewCount: 1 } } -// ) -// previousPage = currentPage // به‌روزرسانی شماره صفحه قبلی -// } -// // دریافت لیست لایک هر ویترین و اضافه کردن آن به اطلاعات تبلیغات -// const advertisingIds = advertisings.docs.map(ad => ad._id) -// const advertisingLikes = await AdvertisingLikeModel.find({ advertisingId: { $in: advertisingIds } }) - -// const creatorIds = advertisings.docs.map(ad => ad.creator_id) -// const creators = await AdvertisingProfileModel.find({ user: { $in: creatorIds } }) -// const newAds = advertisings.docs.map(ad => { -// const creator = creators.find(user => user.user.toString() === ad.creator_id.toString()) -// const likedByUser = advertisingLikes.some(like => like.advertisingId.toString() === ad._id.toString() && like.userId.toString() === decodedToken.id) -// return { -// // فیلدهای مشخص‌شده از ad._doc -// _id: ad._doc._id, -// category: ad._doc.category, -// title: ad._doc.title, -// province: ad._doc.province, -// city: ad._doc.city, -// neighbourhood: ad._doc.neighbourhood, -// type: ad._doc.type, -// mostDiscountPercentage: ad._doc.mostDiscountPercentage, -// images: ad._doc.images, -// likedByUser, -// likesCount: ad._doc.likesCount, -// commentsCount: ad._doc.commentsCount, -// showDiscount: ad._doc.showDiscount, -// viewCount: ad._doc.viewCount, -// rate: { -// adTotalRatings: creator?.adTotalRatings, -// adAverageRating: creator?.adAverageRating -// } -// } -// }) -// res.status(200).json({ -// advertisings: newAds, -// totalPages: advertisings.totalPages, -// totalItems: advertisings.totalDocs -// }) -// } catch (error) { -// next(error) -// } -// } -const getAdvertisings = async (req, res, next) => { - let previousPage = 0 // تعریف متغیر سراسری برای نگهداری شماره صفحه قبلی - - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - - const { page = 1, limit = 10, province, city, category, search, sort } = req.query - const currentPage = parseInt(page) // شماره صفحه جاری - - const filter = { - payment_status: 'done', - status: 'accepted' - } - if (province) { - const provinceFind = await ProvinceModel.findOne({ id: province }, { _id: 0 }) - filter.province = provinceFind - } - if (city) { - const cityFind = await CityModel.findOne({ id: city }) - filter.city = cityFind - } - if (category) { - filter.category = category - } - if (search) { - filter.$or = [ - { title: { $regex: search, $options: 'i' } }, - { category: { $regex: search, $options: 'i' } } - ] - } - - // مرتب‌سازی بر اساس پارامتر sort - let sortOptions = { acceptedAt: -1, createdAt: -1 } // مرتب‌سازی پیش‌فرض - if (sort) { - const sortFields = sort.split(',') - sortFields.forEach(field => { - if (field === 'mostDiscount') { - sortOptions = { mostDiscountPercentage: -1 } - } else if (field === 'highestRating') { - sortOptions = { 'rate.adAverageRating': -1 } - } - }) - } - - const options = { - page: parseInt(page), - limit: parseInt(limit), - sort: sortOptions // استفاده از مرتب‌سازی تنظیم‌شده - } - const advertisings = await AdvertisingModel.paginate(filter, options) - - // اگر شماره صفحه تغییر کرده بود، تعداد بازدیدها را به روز رسانی کنید - if (currentPage !== previousPage) { - await AdvertisingModel.updateMany( - { _id: { $in: advertisings.docs.map(ad => ad._id) } }, - { $inc: { viewCount: 1 } } - ) - previousPage = currentPage // به‌روزرسانی شماره صفحه قبلی - } - // دریافت لیست لایک هر ویترین و اضافه کردن آن به اطلاعات تبلیغات - const advertisingIds = advertisings.docs.map(ad => ad._id) - const advertisingLikes = await AdvertisingLikeModel.find({ advertisingId: { $in: advertisingIds } }) - - const creatorIds = advertisings.docs.map(ad => ad.creator_id) - const creators = await AdvertisingProfileModel.find({ user: { $in: creatorIds } }) - const newAds = advertisings.docs.map(ad => { - const creator = creators.find(user => user.user.toString() === ad.creator_id.toString()) - const likedByUser = advertisingLikes.some(like => like.advertisingId.toString() === ad._id.toString() && like.userId.toString() === decodedToken.id) - return { - // فیلدهای مشخص‌شده از ad._doc - _id: ad._doc._id, - category: ad._doc.category, - title: ad._doc.title, - province: ad._doc.province, - city: ad._doc.city, - neighbourhood: ad._doc.neighbourhood, - type: ad._doc.type, - mostDiscountPercentage: ad._doc.mostDiscountPercentage, - images: ad._doc.images, - likedByUser, - likesCount: ad._doc.likesCount, - commentsCount: ad._doc.commentsCount, - showDiscount: ad._doc.showDiscount, - viewCount: ad._doc.viewCount, - rate: { - adTotalRatings: creator?.adTotalRatings, - adAverageRating: creator?.adAverageRating - } - } - }) - res.status(200).json({ - advertisings: newAds, - totalPages: advertisings.totalPages, - totalItems: advertisings.totalDocs - }) - } catch (error) { - next(error) - } -} - -const getAdvertisingsWeb = async (req, res, next) => { - let previousPage = 0 - let userId = null - - try { - const token = req.header('Authorization') - if (token) { - try { - const decodedToken = jwt.verify(token.split(' ')[1], process.env.APP_SECRET) - userId = decodedToken.id - } catch (err) { - console.warn('Invalid token:', err.message) - } - } - - const { page = 1, limit = 10, province, city, category, search, sort } = req.query - const currentPage = parseInt(page) - - const filter = { - // payment_status: 'done', - status: 'accepted' - } - if (province) { - const provinceFind = await ProvinceModel.findOne({ id: province }, { _id: 0 }) - filter.province = provinceFind - } - if (city) { - const cityFind = await CityModel.findOne({ id: city }) - filter.city = cityFind - } - if (category) { - filter.category = category - } - if (search) { - filter.$or = [ - { title: { $regex: search, $options: 'i' } }, - { category: { $regex: search, $options: 'i' } } - ] - } - - let sortOptions = { acceptedAt: -1, createdAt: -1 } - if (sort) { - const sortFields = sort.split(',') - sortFields.forEach(field => { - if (field === 'mostDiscount') { - sortOptions = { mostDiscountPercentage: -1 } - } else if (field === 'highestRating') { - sortOptions = { 'rate.adAverageRating': -1 } - } - }) - } - - const options = { - page: parseInt(page), - limit: parseInt(limit), - sort: sortOptions - } - const advertisings = await AdvertisingModel.paginate(filter, options) - - if (currentPage !== previousPage) { - await AdvertisingModel.updateMany( - { _id: { $in: advertisings.docs.map(ad => ad._id) } }, - { $inc: { viewCount: 1 } } - ) - previousPage = currentPage - } - - const advertisingIds = advertisings.docs.map(ad => ad._id) - const creatorIds = advertisings.docs.map(ad => ad.creator_id) - const creators = await AdvertisingProfileModel.find({ user: { $in: creatorIds } }) - - let advertisingLikes = [] - if (userId) { - advertisingLikes = await AdvertisingLikeModel.find({ advertisingId: { $in: advertisingIds }, userId }) - } - - const newAds = advertisings.docs.map(ad => { - const creator = creators.find(user => user.user.toString() === ad.creator_id.toString()) - const likedByUser = userId ? advertisingLikes.some(like => like.advertisingId.toString() === ad._id.toString()) : false - - return { - _id: ad._doc._id, - category: ad._doc.category, - title: ad._doc.title, - province: ad._doc.province, - city: ad._doc.city, - neighbourhood: ad._doc.neighbourhood, - type: ad._doc.type, - mostDiscountPercentage: ad._doc.mostDiscountPercentage, - images: ad._doc.images, - likedByUser, - likesCount: ad._doc.likesCount, - commentsCount: ad._doc.commentsCount, - showDiscount: ad._doc.showDiscount, - viewCount: ad._doc.viewCount, - rate: { - adTotalRatings: creator?.adTotalRatings, - adAverageRating: creator?.adAverageRating - } - } - }) - - res.status(200).json({ - advertisings: newAds, - totalPages: advertisings.totalPages, - totalItems: advertisings.totalDocs - }) - } catch (error) { - next(error) - } -} - -const getSingleAdvertising = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - - const advertisingId = req.params.advertisingId - const advertising = await AdvertisingModel.findById(advertisingId) - .populate('creator_id', '_id user_name first_name last_name') - - if (!advertising) { - return res.status(404).json({ message: 'ویترین مورد نظر یافت نشد' }) - } - - // دریافت تعداد لایک‌ها و بررسی اینکه آیا کاربر ویترین را لایک کرده است یا خیر - const likesCount = await AdvertisingLikeModel.countDocuments({ advertisingId }) - const likedByUser = await AdvertisingLikeModel.findOne({ advertisingId, userId }) - - // دریافت تعداد کامنت‌ها - const commentsCount = await AdvertisingComment.countDocuments({ advertisingId, status: 'accepted' }) - const creator = await AdvertisingProfileModel.findOne({ user: advertising.creator_id._id }) - - // اضافه کردن تعداد لایک‌ها، تعداد کامنت‌ها و وضعیت لایک به تبلیغ - const advertisingData = { - ...advertising._doc, - likesCount, - likedByUser: !!likedByUser, - commentsCount, - creatorId: creator?._id - } - - res.status(200).json({ - advertising: advertisingData, - rate: { - adTotalRatings: creator?.adTotalRatings, - adAverageRating: creator?.adAverageRating - } - }) - } catch (error) { - next(error) - } -} -const getSingleAdvertisingWeb = async (req, res, next) => { - try { - let userId = null - let likedByUser = false - - // بررسی وجود توکن - const authHeader = req.header('Authorization') - if (authHeader) { - const tokenParts = authHeader.split(' ') - if (tokenParts.length === 2) { - try { - const decodedToken = jwt.verify(tokenParts[1], process.env.APP_SECRET) - userId = decodedToken.id - } catch (err) { - console.error('Invalid Token:', err.message) - } - } - } - - const advertisingId = req.params.advertisingId - const advertising = await AdvertisingModel.findById(advertisingId) - .populate('creator_id', '_id user_name first_name last_name') - - if (!advertising) { - return res.status(404).json({ message: 'ویترین مورد نظر یافت نشد' }) - } - - // دریافت تعداد لایک‌ها - const likesCount = await AdvertisingLikeModel.countDocuments({ advertisingId }) - - // دریافت تعداد کامنت‌ها - const commentsCount = await AdvertisingComment.countDocuments({ advertisingId, status: 'accepted' }) - - // دریافت اطلاعات سازنده تبلیغ - const creator = await AdvertisingProfileModel.findOne({ user: advertising.creator_id._id }) - - // اگر کاربر احراز هویت شده باشد، وضعیت لایک‌شدن توسط او بررسی می‌شود - if (userId) { - likedByUser = !!(await AdvertisingLikeModel.findOne({ advertisingId, userId })) - } - - // آماده‌سازی داده‌های تبلیغ - const advertisingData = { - ...advertising._doc, - likesCount, - likedByUser, - commentsCount, - creatorId: creator?._id - } - - res.status(200).json({ - advertising: advertisingData, - rate: { - adTotalRatings: creator?.adTotalRatings, - adAverageRating: creator?.adAverageRating - } - }) - } catch (error) { - next(error) - } -} - -const getAdvertisingTypes = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - // const decodedToken = jwt.verify(token, process.env.APP_SECRET) - // const userId = decodedToken.id - - // const user = await UserModel.findById(userId) - // if (!user) { - // return res.status(422).json({ - // error: true, - // message: 'کاربر یافت نشد' - // }) - // } - // درخواست انواع تبلیغات از دیتابیس - // let projectTypes = await AdvertisingTypeModel.find({}, 'name price') - const advertisingTypes = await AdvertisingTypeModel.find({}, 'name price') - - // بررسی برای مواردی مانند پیدا نشدن انواع تبلیغات - if (!advertisingTypes) { - return res.status(404).json({ message: 'انواع تبلیغات یافت نشد.' }) - } - // اگر کاربر درخواست رایگان روزانه نداشته باشد، نوع تبلیغات رایگان را حذف کنید - // if (user.daily_free_request <= 0) { - // advertisingTypes = advertisingTypes.filter(projectType => projectType.name !== 'free') - // } - // ارسال انواع تبلیغات به کاربر - res.status(200).json({ advertisingTypes }) - } catch (error) { - // در صورت بروز خطا، ارسال پیام خطا به کاربر - console.error('Error in getAdvertisingTypes:', error) - res.status(500).json({ message: 'خطا در دریافت انواع تبلیغات.' }) - } -} -const getAdvertisingCategory = async (req, res, next) => { - try { - // const token = req.header('Authorization').split(' ')[1] - // if (!token) return res.status(401).send('Access Denied') - // const decodedToken = jwt.verify(token, process.env.APP_SECRET) - // const userId = decodedToken.id - - // const user = await UserModel.findById(userId) - // if (!user) { - // return res.status(422).json({ - // error: true, - // message: 'کاربر یافت نشد' - // }) - // } - // let projectTypes = await AdvertisingTypeModel.find({}, 'name price') - const categories = await AdvertisingCategoryModel.find({}) - - // بررسی برای مواردی مانند پیدا نشدن انواع پروژه - if (!categories) { - return res.status(404).json({ message: 'دسته بندی یافت نشد.' }) - } - // if (user.daily_free_request <= 0) { - // categories = categories.filter(projectType => projectType.name !== 'free') - // } - // ارسال انواع پروژه به کاربر - res.status(200).json({ categories }) - } catch (error) { - // در صورت بروز خطا، ارسال پیام خطا به کاربر - console.error('Error in getAdvertisingTypes:', error) - res.status(500).json({ message: 'خطا در دریافت انواع پروژه.' }) - } -} - -const getAdvertisingFeatures = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - // const decodedToken = jwt.verify(token, process.env.APP_SECRET) - // const userId = decodedToken.id - - // const user = await UserModel.findById(userId) - // if (!user) { - // return res.status(422).json({ - // error: true, - // message: 'کاربر یافت نشد' - // }) - // } - // let projectTypes = await AdvertisingTypeModel.find({}, 'name price') - const features = await AdvertisingFeaturesModel.find({}) - - // بررسی برای مواردی مانند پیدا نشدن امکانات - if (!features) { - return res.status(404).json({ message: 'امکانات یافت نشد.' }) - } - // if (user.daily_free_request <= 0) { - // features = features.filter(projectType => projectType.name !== 'free') - // } - // ارسال امکانات به کاربر - res.status(200).json({ features }) - } catch (error) { - // در صورت بروز خطا، ارسال پیام خطا به کاربر - console.error('Error in getAdvertisingTypes:', error) - res.status(500).json({ message: 'خطا در دریافت امکانات.' }) - } -} -const toggleLike = async (req, res, next) => { - try { - const { advertisingId } = req.body - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - // بررسی وجود تبلیغات با استفاده از advertisingId - const advertising = await AdvertisingModel.findById(advertisingId) - if (!advertising) { - return res.status(404).json({ message: 'ویترین مورد نظر یافت نشد' }) - } - // بررسی وضعیت لایک کردن توسط کاربر - const isLiked = await AdvertisingLikeModel.findOne({ advertisingId, userId }) - if (isLiked) { - // حذف لایک - await AdvertisingLikeModel.findOneAndDelete({ advertisingId, userId }) - // کاهش تعداد لایک‌ها در تبلیغات - advertising.likesCount -= 1 - await advertising.save() - return res.status(200).json({ message: 'لایک با موفقیت پاک شد' }) - } else { - // اضافه کردن لایک - await AdvertisingLikeModel.create({ advertisingId, userId }) - // افزایش تعداد لایک‌ها در تبلیغات - advertising.likesCount += 1 - await advertising.save() - return res.status(201).json({ message: 'ویترین با موفقیت لایک شد' }) - } - } catch (error) { - next(error) - } -} -const addComment = async (req, res, next) => { - try { - const { advertisingId, text } = req.body - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - // eslint-disable-next-line no-unused-vars - const user = await UserModel.findById(decodedToken.id) - // if (user.is_verified !== 'verified') { - // return res.status(422).json({ - // error: true, - // message: 'مدارک شما تایید نشده است' - // }) - // } - const newComment = new AdvertisingComment({ - advertisingId, - userId, - text - }) - - await newComment.save() - // افزایش تعداد کامنت‌های تبلیغ - // await AdvertisingModel.findByIdAndUpdate(advertisingId, { $inc: { commentsCount: 1 } }) - - res.status(201).json({ message: 'کامنت با موفقیت اضافه شد', comment: newComment }) - } catch (error) { - next(error) - } -} -const getComments = async (req, res, next) => { - try { - const { advertisingId, page = 1, limit = 10 } = req.query - const options = { - page: parseInt(page), - limit: parseInt(limit), - sort: { createdAt: -1 }, - populate: [{ path: 'userId', select: '_id profile_image user_type user_name first_name last_name is_verified' }] - } - - const comments = await AdvertisingComment.paginate({ advertisingId, status: 'accepted' }, options) - res.status(200).json({ - comments: comments.docs, - totalPages: comments.totalPages, - totalItems: comments.totalDocs - }) - } catch (error) { - next(error) - } -} -const rateAdvertising = async (req, res, next) => { - try { - const { advertisingId, rating } = req.body - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - - if (rating < 1 || rating > 5) { - return res.status(400).json({ message: 'امتیاز باید بین 1 تا 5 باشد' }) - } - - const advertising = await AdvertisingModel.findById(advertisingId) - if (!advertising) { - return res.status(404).json({ message: 'ویترین مورد نظر یافت نشد' }) - } - - const existingRating = await AdvertisingRatingModel.findOne({ advertisingId, userId }) - if (existingRating) { - return res.status(400).json({ message: 'شما قبلا برای این ویترین امتیاز ثبت کرده‌اید' }) - } else { - const newRating = new AdvertisingRatingModel({ - advertisingId, - userId, - rating - }) - await newRating.save() - } - - // به‌روزرسانی امتیازات کلی کاربر - const advertisingProfile = await AdvertisingProfileModel.findOne({ user: advertising.creator_id }) - if (advertisingProfile) { - const totalUserRatings = await AdvertisingRatingModel.aggregate([ - { - $lookup: { - from: 'advertisings', - localField: 'advertisingId', - foreignField: '_id', - as: 'advertising' - } - }, - { $unwind: '$advertising' }, - { $match: { 'advertising.creator_id': advertising.creator_id } }, - { $group: { _id: null, total: { $sum: '$rating' }, count: { $sum: 1 } } } - ]) - - if (totalUserRatings.length > 0) { - const { total, count } = totalUserRatings[0] - advertisingProfile.adTotalRatings = total - advertisingProfile.adRatingsCount = count - advertisingProfile.adAverageRating = (total / count).toFixed(1) - } else { - advertisingProfile.adTotalRatings = 0 - advertisingProfile.adRatingsCount = 0 - advertisingProfile.adAverageRating = 0 - } - - await advertisingProfile.save() - } else { - // ایجاد پروفایل تبلیغاتی جدید در صورت عدم وجود - const newAdvertisingProfile = new AdvertisingProfileModel({ - user: advertising.creator_id, - adTotalRatings: rating, - adRatingsCount: 1, - adAverageRating: rating.toFixed(1) - }) - await newAdvertisingProfile.save() - } - - res.status(200).json({ message: 'امتیاز با موفقیت ثبت شد' }) - } catch (error) { - next(error) - } -} -const getUserAdvertisings = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - - const { page = 1, limit = 10, status, search } = req.query - - const filter = { - creator_id: userId - } - - if (status) { - filter.status = status - } - if (search) { - filter.$or = [ - { title: { $regex: search, $options: 'i' } }, - { category: { $regex: search, $options: 'i' } } - ] - } - - const options = { - page: parseInt(page), - limit: parseInt(limit), - sort: { updatedAt: -1 } - } - - const advertisings = await AdvertisingModel.paginate(filter, options) - - // دریافت لیست لایک هر ویترین و اضافه کردن آن به اطلاعات تبلیغات - const advertisingIds = advertisings.docs.map(ad => ad._id) - const advertisingLikes = await AdvertisingLikeModel.find({ advertisingId: { $in: advertisingIds } }) - const creator = await AdvertisingProfileModel.findOne({ user: userId }) - - const newAds = advertisings.docs.map(ad => { - const likedByUser = advertisingLikes.some(like => like.advertisingId.toString() === ad._id.toString() && like.userId.toString() === decodedToken.id) - let remainingTime = null - if (ad.status === 'accepted' && ad.acceptedAt) { - const expirationDate = new Date(ad.acceptedAt) - expirationDate.setDate(expirationDate.getDate() + 15) - const currentDate = new Date() - const diffMilliseconds = expirationDate - currentDate - const diffDays = Math.floor(diffMilliseconds / (1000 * 60 * 60 * 24)) - const diffHours = Math.floor((diffMilliseconds % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)) - remainingTime = `${diffDays} روز و ${diffHours} ساعت` - } - return { - _id: ad._doc._id, - category: ad._doc.category, - title: ad._doc.title, - province: ad._doc.province, - city: ad._doc.city, - neighbourhood: ad._doc.neighbourhood, - type: ad._doc.type, - mostDiscountPercentage: ad._doc.mostDiscountPercentage, - images: ad._doc.images, - likedByUser, - likesCount: ad._doc.likesCount, - commentsCount: ad._doc.commentsCount, - status: ad._doc.status, - viewCount: ad._doc.viewCount, - remainingTime, - rate: { - adTotalRatings: creator?.adTotalRatings, - adAverageRating: creator?.adAverageRating - } - } - }) - - res.status(200).json({ - advertisings: newAds, - totalPages: advertisings.totalPages, - totalItems: advertisings.totalDocs - }) - } catch (error) { - next(error) - } -} -const getUserSingleAdvertising = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - const user = await UserModel.findById(userId) - if (!user) { - return res.status(422).json({ - error: true, - message: 'شما دسترسی به این بخش ندارید' - }) - } - const advertisingId = req.params.advertisingId - const advertising = await AdvertisingModel.findById(advertisingId) - .populate('creator_id', '_id user_name first_name last_name') - - if (!advertising) { - return res.status(404).json({ message: 'ویترین مورد نظر یافت نشد' }) - } - - // دریافت تعداد لایک‌ها و بررسی اینکه آیا کاربر ویترین را لایک کرده است یا خیر - const likesCount = await AdvertisingLikeModel.countDocuments({ advertisingId }) - const likedByUser = await AdvertisingLikeModel.findOne({ advertisingId, userId }) - - // دریافت تعداد کامنت‌ها - const commentsCount = await AdvertisingComment.countDocuments({ advertisingId, status: 'accepted' }) - const creator = await AdvertisingProfileModel.findOne({ user: advertising.creator_id._id }) - - // اضافه کردن تعداد لایک‌ها، تعداد کامنت‌ها و وضعیت لایک به تبلیغ - const advertisingData = { - ...advertising._doc, - likesCount, - likedByUser: !!likedByUser, - commentsCount, - creatorId: creator?._id - - } - - res.status(200).json({ - advertising: advertisingData, - rate: { - adTotalRatings: creator?.adTotalRatings, - adAverageRating: creator?.adAverageRating - } - }) - } catch (error) { - next(error) - } -} -const editAdvertising = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const user = await UserModel.findById(decodedToken.id) - if (!user) { - return res.status(422).json({ - error: true, - message: 'شما دسترسی به این بخش ندارید' - }) - } - // if (user.is_verified !== 'verified') { - // return res.status(422).json({ - // error: true, - // message: 'مدارک شما تایید نشده است' - // }) - // } - - const errors = validationResult(req) - if (!errors.isEmpty()) { - return res.status(422).json({ errors: errors.array() }) - } - - const { id } = req.params - const { - category, - title, - description, - province, - city, - neighbourhood, - address, - lat, - lng, - services, - features, - contactInfo, - mostDiscountPercentage, - showDiscount, - type - } = req.body - - if (!title || !category || !province || !city) { - return res.status(422).json({ - error: true, - message: 'اطلاعات ارسالی اشتباه است' - }) - } - - const advertising = await AdvertisingModel.findOne({ - _id: id, - creator_id: user._id, - status: { $in: ['pre_payment', 'paid', 'rejected', 'expired'] } - }) - - if (!advertising) { - return res.status(404).json({ - error: true, - message: 'تبلیغ مورد نظر یافت نشد یا شما اجازه ویرایش آن را ندارید' - }) - } - - const provinceFind = await ProvinceModel.findOne({ id: province }, { _id: 0 }) - const cityFind = await CityModel.findOne({ id: city }) - - // مدیریت تصاویر برای خدمات - const servicesWithImages = [] - const parsedServices = JSON.parse(services) - if (parsedServices && parsedServices.length > 0) { - for (const service of parsedServices) { - if (typeof service.image === 'string' && service.image.startsWith('/services/')) { - servicesWithImages.push(service) - } else { - const serviceImages = [] - const serviceId = service.id - if (req.files && req.files.serviceImages && req.files.serviceImages[serviceId]) { - const imageFiles = Array.isArray(req.files.serviceImages[serviceId]) ? req.files.serviceImages[serviceId] : [req.files.serviceImages[serviceId]] - const uploadDir = path.join(__dirname, '../../../../storage/services') - if (!fs.existsSync(uploadDir)) { - fs.mkdirSync(uploadDir, { recursive: true }) - } - for (const imageFile of imageFiles) { - const uniqueFileName = `${user.user_name}-${Date.now()}${Math.random().toString().slice(2, 11)}${path.extname(imageFile.name)}` - const filePath = path.join(uploadDir, uniqueFileName) - await fs.move(imageFile.path, filePath) - const imageUrl = `/services/${uniqueFileName}` - serviceImages.push(imageUrl) - service.image = imageUrl - } - } - servicesWithImages.push({ ...service, image: serviceImages[0] }) - } - } - } - // مدیریت تصاویر - const images = [] - - // اضافه کردن تصاویر موجود - if (Array.isArray(req.body.existingImages)) { - req.body.existingImages.forEach(image => { - if (typeof image === 'string' && image.startsWith('/advertising/')) { - images.push(image) - } - }) - } - - // اضافه کردن تصاویر جدید - if (req.files && req.files.images) { - const imageFiles = Array.isArray(req.files.images) ? req.files.images : [req.files.images] - const uploadDir = path.join(__dirname, '../../../../storage/advertising') - if (!fs.existsSync(uploadDir)) { - fs.mkdirSync(uploadDir, { recursive: true }) - } - for (const imageFile of imageFiles) { - // بررسی فرمت تصویر - if (imageFile && typeof imageFile === 'object' && imageFile.path) { - const uniqueFileName = `${user.user_name}-${Date.now()}${Math.random().toString().slice(2, 11)}${path.extname(imageFile.name)}` - const filePath = path.join(uploadDir, uniqueFileName) - await fs.move(imageFile.path, filePath) - const imageUrl = `/advertising/${uniqueFileName}` - images.push(imageUrl) - } - } - } - const parsedFeatures = JSON.parse(features) - - advertising.title = title - advertising.category = category - advertising.description = description - advertising.province = provinceFind - advertising.city = cityFind - advertising.neighbourhood = neighbourhood - advertising.address = address - advertising.lat = lat - advertising.lng = lng - advertising.images = images - advertising.services = servicesWithImages - advertising.features = parsedFeatures - advertising.contactInfo = contactInfo - advertising.mostDiscountPercentage = mostDiscountPercentage - advertising.showDiscount = showDiscount - advertising.type = type - - await advertising.save() - - if (contactInfo && contactInfo.saveInfoForNextAds) { - user.contactInfo = contactInfo - await user.save() - } - res.status(200).json({ - message: 'ویترین با موفقیت ویرایش شد', - id: advertising._id - }) - } catch (error) { - next(error) - } -} -const getUserAdvertisingProfile = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const vitrineId = req.query.vitrineId - - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const user = await UserModel.findById(decodedToken.id) - if (!user) { - return res.status(422).json({ - error: true, - message: 'شما دسترسی به این بخش ندارید' - }) - } - // if (user.is_verified !== 'verified') { - // return res.status(422).json({ - // error: true, - // message: 'مدارک شما تایید نشده است' - // }) - // } - - // دریافت اطلاعات پروفایل تبلیغاتی کاربر - const advertisingProfile = await AdvertisingProfileModel.findById(vitrineId) - if (!advertisingProfile) { - return res.status(404).json({ - error: true, - message: 'پروفایل تبلیغاتی یافت نشد' - }) - } - - // دریافت تبلیغات‌های کاربر - const userAds = await AdvertisingModel.find({ creator_id: advertisingProfile?.user }) - - // جمع‌آوری اطلاعات از تبلیغات‌ها - let allImages = [] - let allServices = [] - let allFeatures = [] - let totalCommentsCount = 0 - let totalLikesCount = 0 - - for (const ad of userAds) { - allImages = allImages.concat(ad.images) - allServices = allServices.concat(ad.services) - allFeatures = allFeatures.concat(ad.features) - totalCommentsCount += ad.commentsCount - totalLikesCount += ad.likesCount - } - - // حذف آیتم‌های null و تکراری از allFeatures - const uniqueFeatures = [] - const featureTitles = new Set() - for (const feature of allFeatures) { - if (feature && !featureTitles.has(feature.title)) { - uniqueFeatures.push(feature) - featureTitles.add(feature.title) - } - } - - // آماده‌سازی اطلاعات نهایی - const profileDetails = { - _id: advertisingProfile._id, - profile_image: advertisingProfile.profile_image, - vitrine_name: advertisingProfile.vitrine_name, - category: advertisingProfile.category, - about_us: advertisingProfile.about_us, - province: advertisingProfile.province, - city: advertisingProfile.city, - lat: advertisingProfile.lat, - lng: advertisingProfile.lng, - neighbourhood: advertisingProfile.neighbourhood, - adTotalRatings: advertisingProfile.adTotalRatings, - adRatingsCount: advertisingProfile.adRatingsCount, - adAverageRating: advertisingProfile.adAverageRating, - contactInfo: advertisingProfile.contactInfo, - address: advertisingProfile.address, - allImages: allImages?.reverse(), - allServices, - allFeatures: uniqueFeatures, - totalCommentsCount, - totalLikesCount, - is_self: !!(advertisingProfile && advertisingProfile?.user == decodedToken.id) - } - - // ارسال پاسخ به کاربر - res.status(200).json({ profileDetails }) - } catch (error) { - next(error) - } -} -const getUserAdvertisingProfileWeb = async (req, res, next) => { - try { - let userId = null - let isSelf = false - - // بررسی توکن (در صورت وجود) - const authHeader = req.header('Authorization') - if (authHeader) { - const tokenParts = authHeader.split(' ') - if (tokenParts.length === 2) { - try { - const decodedToken = jwt.verify(tokenParts[1], process.env.APP_SECRET) - userId = decodedToken.id - } catch (err) { - console.error('Invalid Token:', err.message) - } - } - } - - const vitrineId = req.query.vitrineId - console.log(vitrineId) - - // دریافت اطلاعات پروفایل تبلیغاتی کاربر - const advertisingProfile = await AdvertisingProfileModel.findById(vitrineId) - if (!advertisingProfile) { - return res.status(404).json({ - error: true, - message: 'پروفایل تبلیغاتی یافت نشد' - }) - } - - // دریافت تبلیغات‌های کاربر - const userAds = await AdvertisingModel.find({ creator_id: advertisingProfile?.user }) - - // جمع‌آوری اطلاعات از تبلیغات‌ها - let allImages = [] - let allServices = [] - let allFeatures = [] - let totalCommentsCount = 0 - let totalLikesCount = 0 - - for (const ad of userAds) { - allImages = allImages.concat(ad.images) - allServices = allServices.concat(ad.services) - allFeatures = allFeatures.concat(ad.features) - totalCommentsCount += ad.commentsCount - totalLikesCount += ad.likesCount - } - - // حذف آیتم‌های null و تکراری از allFeatures - const uniqueFeatures = [] - const featureTitles = new Set() - for (const feature of allFeatures) { - if (feature && !featureTitles.has(feature.title)) { - uniqueFeatures.push(feature) - featureTitles.add(feature.title) - } - } - - // بررسی اینکه کاربر خودش صاحب این ویترین است یا نه - if (userId) { - isSelf = advertisingProfile?.user == userId - } - - // آماده‌سازی اطلاعات نهایی - const profileDetails = { - _id: advertisingProfile._id, - profile_image: advertisingProfile.profile_image, - vitrine_name: advertisingProfile.vitrine_name, - category: advertisingProfile.category, - about_us: advertisingProfile.about_us, - province: advertisingProfile.province, - city: advertisingProfile.city, - lat: advertisingProfile.lat, - lng: advertisingProfile.lng, - neighbourhood: advertisingProfile.neighbourhood, - adTotalRatings: advertisingProfile.adTotalRatings, - adRatingsCount: advertisingProfile.adRatingsCount, - adAverageRating: advertisingProfile.adAverageRating, - contactInfo: advertisingProfile.contactInfo, - address: advertisingProfile.address, - allImages: allImages?.reverse(), - allServices, - allFeatures: uniqueFeatures, - totalCommentsCount, - totalLikesCount, - is_self: isSelf - } - - // ارسال پاسخ به کاربر - res.status(200).json({ profileDetails }) - } catch (error) { - next(error) - } -} - -const updateUserAdvertisingProfile = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const user = await UserModel.findById(decodedToken.id) - if (!user) { - return res.status(422).json({ - error: true, - message: 'شما دسترسی به این بخش ندارید' - }) - } - - const advertisingProfile = await AdvertisingProfileModel.findOne({ user: decodedToken.id }) - if (!advertisingProfile) { - return res.status(404).json({ - error: true, - message: 'پروفایل تبلیغاتی یافت نشد' - }) - } - - if (advertisingProfile.user.toString() !== decodedToken.id) { - return res.status(403).json({ - error: true, - message: 'شما اجازه ویرایش این پروفایل را ندارید' - }) - } - - const { profile_image } = req.files - const { - // profile_image, - vitrine_name, - category, - about_us, - province, - city, - lat, - lng, - address, - neighbourhood, - contactInfo - } = req.body - - const updateFields = {} - const provinceFind = await ProvinceModel.findOne({ id: province }, { _id: 0 }) - const cityFind = await CityModel.findOne({ id: city }) - // if (profile_image !== undefined && profile_image !== null && !profile_image.startsWith('/profiles/')) { - if (profile_image !== undefined && profile_image !== null) { - const uploadDir = path.join(__dirname, '../../../../storage/profiles') - if (!fs.existsSync(uploadDir)) { - fs.mkdirSync(uploadDir, { recursive: true }) - } - const uniqueFileName = `${advertisingProfile?.vitrine_name}-${Date.now()}${path.extname(profile_image.name)}` - const filePath = path.join(uploadDir, uniqueFileName) - await fs.move(profile_image.path, filePath) - updateFields.profile_image = `/profiles/${uniqueFileName}` - } - if (vitrine_name !== undefined) updateFields.vitrine_name = vitrine_name - if (category !== undefined) updateFields.category = category - if (about_us !== undefined) updateFields.about_us = about_us - if (province !== undefined) updateFields.province = provinceFind - if (city !== undefined) updateFields.city = cityFind - if (lat !== undefined) updateFields.lat = lat - if (lng !== undefined) updateFields.lng = lng - if (address !== undefined) updateFields.address = address - if (neighbourhood !== undefined) updateFields.neighbourhood = neighbourhood - if (contactInfo !== undefined) updateFields.contactInfo = contactInfo - - const updatedProfile = await AdvertisingProfileModel.findByIdAndUpdate( - advertisingProfile._id, - { $set: updateFields }, - { new: true } - ) - - res.status(200).json({ - success: true, - message: 'پروفایل با موفقیت به‌روزرسانی شد', - updatedProfile - }) - } catch (error) { - next(error) - } -} - -module.exports = { - createAdvertisingValidationRules, - createAdvertising, - getAdvertisingTypes, - getAdvertisingCategory, - getSingleAdvertising, - getAdvertisingFeatures, - getAdvertisings, - toggleLike, - addComment, - getComments, - rateAdvertising, - getUserAdvertisings, - editAdvertising, - getUserSingleAdvertising, - getUserAdvertisingProfile, - updateUserAdvertisingProfile, - getAdvertisingsWeb, - getSingleAdvertisingWeb, - getUserAdvertisingProfileWeb -} diff --git a/public/modstagram-back/controllers/application/citysController.js b/public/modstagram-back/controllers/application/citysController.js deleted file mode 100644 index 0e9e98d..0000000 --- a/public/modstagram-back/controllers/application/citysController.js +++ /dev/null @@ -1,16 +0,0 @@ -const { CityModel } = require('../../models/StateCity') -const getCities = async (req, res, next) => { - try { - const { id } = req.params - const cities = await CityModel.find({ province_id: id }) - - res.status(200).json({ - cities - }) - } catch (err) { - res.status(500).send('Internal Server Error') - } -} -module.exports = { - getCities -} diff --git a/public/modstagram-back/controllers/application/expertise/expertiseController.js b/public/modstagram-back/controllers/application/expertise/expertiseController.js deleted file mode 100644 index b4cf48d..0000000 --- a/public/modstagram-back/controllers/application/expertise/expertiseController.js +++ /dev/null @@ -1,13 +0,0 @@ -/* eslint-disable camelcase */ -const ExpertiseModel = require('../../../models/ExpertiseModel') -const getExpertise = async (req, res, next) => { - try { - const expertises = await ExpertiseModel.find().select('expertise sub_expertise') - res.json({ expertises }) - } catch (error) { - next(error) - } -} -module.exports = { - getExpertise -} diff --git a/public/modstagram-back/controllers/application/financial/financialController.js b/public/modstagram-back/controllers/application/financial/financialController.js deleted file mode 100644 index 4e60769..0000000 --- a/public/modstagram-back/controllers/application/financial/financialController.js +++ /dev/null @@ -1,65 +0,0 @@ -const jwt = require('jsonwebtoken') -const PaymentModel = require('../../../models/PaymentModel') -const ProjectModel = require('../../../models/ProjectModel') -const moment = require('moment-jalaali') - -const getFinancial = async (req, res) => { - try { - // Extract user ID from JWT token - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - const options = { - page: req.query.page || 1, // صفحه پیش‌فرض ۱ - limit: req.query.limit || 10, // حداکثر تعداد موارد برای هر صفحه - sort: { createdAt: -1 } - } - // Find all payments associated with the user - const financial = await PaymentModel.paginate( - { user_id: userId }, // فیلتر - options // گزینه‌های پیجینیشن - ) - // Prepare the data to be sent back - const userPayments = await Promise.all(financial.docs.map(async (payment) => { - // Find the project associated with the payment - const project = await ProjectModel.findById(payment.project_id) - - if (!project) { - return null - } - // استفاده از کتابخانه moment-jalaali برای تبدیل تاریخ و زمان به شمسی - const shamsiDate = moment(payment.createdAt).format('jYYYY-jMM-jDD') - const shamsiTime = moment(payment.createdAt).format('HH:mm') - - // Extract the required information - const userPayment = { - _id: payment._id, - project_title: project.title, - project_id: project._id, - payment_date: shamsiDate, // Format date as YYYY-MM-DD - payment_time: shamsiTime, - iban: project.creator_id ? project.creator_id.iban : null, // Check if creator_id exists before accessing iban - amount: payment.amount, - payment_status: payment.status - } - - return userPayment - })) - - // Filter out null values - const validUserPayments = userPayments.filter(payment => payment !== null) - - // Send the payments back to the client - res.status(200).json({ - financial: financial, - totalPages: financial.totalPages, // ارسال تعداد کل صفحات - totalItems: financial.totalDocs // ارسال تعداد کل آیتم‌ها - }) - } catch (error) { - console.error('Error occurred:', error) - res.status(500).json({ error: 'Internal server error' }) - } -} - -module.exports = { getFinancial } diff --git a/public/modstagram-back/controllers/application/login/changePasswordController.js b/public/modstagram-back/controllers/application/login/changePasswordController.js deleted file mode 100644 index 39faaaf..0000000 --- a/public/modstagram-back/controllers/application/login/changePasswordController.js +++ /dev/null @@ -1,77 +0,0 @@ -/* eslint-disable camelcase */ -const bcrypt = require('bcryptjs') -const { check, validationResult } = require('express-validator') - -const jwt = require('jsonwebtoken') -const UserModel = require('../../../models/UserModel') - -const changePasswordValidationRules = () => { - return [ - check('new_password') - .notEmpty().withMessage('رمز عبور نمی‌تواند خالی باشد') - .isLength({ min: 8, max: 25 }).withMessage('رمز عبور نباید کوتاه تر از 8 کاراکتر باشد') - .matches(/^(?=.*[a-zA-Zآ-ی])(?=.*\d).{8,}$/u).withMessage('رمز عبور باید شامل حروف و اعداد باشد') - ] -} -const changePasswordUser = async (req, res, next) => { - try { - const { new_password } = req.body - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - // اعتبارسنجی ورودی ها - const errors = validationResult(req) - if (!errors.isEmpty()) { - return res.status(422).json({ errors: errors.array() }) - } - - // یافتن کاربر با شماره موبایل - const user = await UserModel.findById(userId) - if (!user) { - return res.status(404).json({ - error: true, - message: 'کاربری با این شماره موبایل یافت نشد' - }) - } - // هش کردن پسورد جدید و ذخیره در دیتابیس - const hashedPassword = await bcrypt.hash(new_password, 10) - user.password = hashedPassword - await user.save() - - return res.json({ - message: 'کلمه عبور با موفقیت ذخیره شد' - }) - } catch (error) { - next(error) - } -} - -const editChangePasswordUser = async (req, res, next) => { - try { - const { mobile, new_password } = req.body - const user = await UserModel.findOne({ mobile }) - if (!user) { - return res.status(404).json({ - error: true, - message: 'کاربری با این شماره موبایل یافت نشد' - }) - } - - // هش کردن پسورد جدید و ذخیره در دیتابیس - const hashedPassword = await bcrypt.hash(new_password, 10) - user.password = hashedPassword - await user.save() - - return res.json({ - message: 'کلمه عبور با موفقیت تغییر یافت' - }) - } catch (error) { - next(error) - } -} - -module.exports = { - changePasswordUser, changePasswordValidationRules, editChangePasswordUser -} diff --git a/public/modstagram-back/controllers/application/login/loginController.js b/public/modstagram-back/controllers/application/login/loginController.js deleted file mode 100644 index 27ad62f..0000000 --- a/public/modstagram-back/controllers/application/login/loginController.js +++ /dev/null @@ -1,87 +0,0 @@ -const UserModel = require('../../../models/UserModel') -const { check, validationResult } = require('express-validator') -const { default: axios } = require('axios') -const loginValidationRules = () => { - return [ - check('mobile') - .notEmpty().withMessage('شماره موبایل نمی‌تواند خالی باشد') - .isLength({ min: 11, max: 11 }).withMessage('شماره موبایل باید دقیقاً 11 رقم باشد') - .matches(/^09[0-9]{9}$/).withMessage('فرمت شماره موبایل صحیح نیست') - ] -} - -const loginUser = async (req, res, next) => { - try { - const errors = validationResult(req) - if (!errors.isEmpty()) { - return res.status(422).json({ errors: errors.array() }) - } - - const { mobile } = req.body - if (!mobile) { - return res.status(422).json({ - error: true, - message: 'شماره موبایل نمی‌تواند خالی باشد' - }) - } - - // const existingUser = await UserModel.findOne({ mobile }) - // if (!existingUser) { - // return res.status(422).json({ error: true, message: 'کاربری با این شماره موبایل یافت نشد' }) - // } - function generateOTP () { - return Math.floor(100000 + Math.random() * 900000) - } - - const otp = generateOTP() - // eslint-disable-next-line no-unused-vars - const user = await UserModel.findOneAndUpdate( - { mobile }, - { $set: { mobile, otp } }, - { upsert: true, new: true, lean: true } - ) - // زمانبندی تنظیم مقدار otp به null پس از 10 دقیقه - setTimeout(() => { - UserModel.findOneAndUpdate({ mobile }, { $set: { otp: null } }, { new: true }) - .then(() => {}) - .catch(error => console.error('Error setting OTP to null:', error)) - }, 5 * 60 * 1000) - const data = JSON.stringify({ - mobile, - templateId: '930719', - parameters: [ - { name: 'CODE', value: otp.toString() } - ] - }) - - const config = { - method: 'post', - url: 'https://api.sms.ir/v1/send/verify', - headers: { - 'Content-Type': 'application/json', - Accept: 'text/plain', - 'x-api-key': '2JKxGbTzE64t0YTkjip6RYHnm9mq1haMlidF8WWwQunwubHFVW6iaMmfFQbMXEDt' - }, - data - } - - axios(config) - .then(function (response) { - }) - .catch(function (error) { - console.log(error) - }) - - res.status(200).json({ - success: true, - message: 'کد تایید ارسال شد' - }) - } catch (error) { - next(error) - } -} - -module.exports = { - loginValidationRules, - loginUser -} diff --git a/public/modstagram-back/controllers/application/login/loginWithUserName.js b/public/modstagram-back/controllers/application/login/loginWithUserName.js deleted file mode 100644 index d171c70..0000000 --- a/public/modstagram-back/controllers/application/login/loginWithUserName.js +++ /dev/null @@ -1,92 +0,0 @@ -/* eslint-disable camelcase */ -const UserModel = require('../../../models/UserModel') -const bcrypt = require('bcryptjs') -const TokenService = require('../../../services/TokenService') -// const jwt = require('jsonwebtoken') - -const loginWithUserName = async (req, res, next) => { - try { - // اعتبارسنجی ورودی ها - const { user_name, password } = req.body - if (!user_name || !password) { - return res.status(422).json({ - error: true, - message: 'اطلاعات ارسالی اشتباه است' - }) - } - // یافتن کاربر با نام کاربری - const userLow = user_name.toLowerCase() - const user = await UserModel.findOne({ user_name: userLow }) - - if (!user) { - return res.status(404).json({ - error: true, - message: 'کاربری با این نام کاربری یافت نشد' - }) - } - if (!user.password) { - return res.status(422).json({ - error: true, - message: 'رمز عبور برای این کاربر تنظیم نشده است' - }) - } - const isPasswordValid = await bcrypt.compare(password, user.password) - if (!isPasswordValid) { - return res.status(422).json({ - error: true, - message: 'نام کاربری یا رمز عبور اشتباه است' - }) - } - // اگر هم نام کاربری و هم رمز عبور درست بود، ارسال پیام موفقیت آمیز - const token = TokenService.sign({ id: user._id }) - // if (user.user_name === null) { - // return res.json({ - // message: 'ورود با موفقیت', - // page: 'username' - // }) - // } - - // if (!user.first_name && !user.last_name) { - // return res.json({ - // message: 'ورود با موفقیت', - // page: 'name' - // }) - // } - - // if (!user.user_type) { - // return res.json({ - // message: 'کد تایید صحیح بود', - // page: 'usertype' - // }) - // } - let step = '' - if (user.user_name === null) { step = 'user_name' } else if - (!user.password) { step = 'password' } else if - (!user.first_name) { step = 'first_name' } else if - (!user.user_type) { step = 'user_type' } - if (!user.user_type || user.user_name === null || !user.first_name || !user.last_name) { - return res.json({ - message: 'کد تایید صحیح بود', - token, - step, - user_type: null, - page: 'auth-page', - id: user._id - }) - } - return res.json({ - message: 'کد تایید صحیح بود', - token, - page: 'home', - step, - user_type: user.user_type, - id: user._id - }) - } catch (error) { - next(error) - } -} - -module.exports = { - loginWithUserName -} diff --git a/public/modstagram-back/controllers/application/login/verifyController.js b/public/modstagram-back/controllers/application/login/verifyController.js deleted file mode 100644 index 431441c..0000000 --- a/public/modstagram-back/controllers/application/login/verifyController.js +++ /dev/null @@ -1,89 +0,0 @@ -const UserModel = require('../../../models/UserModel') -const TokenService = require('../../../services/TokenService') -// const jwt = require('jsonwebtoken') - -const verifyUser = async (req, res, next) => { - try { - const { mobile, otp } = req.body - if (!mobile || !otp) { - return res.status(422).json({ - error: true, - message: 'اطلاعات ارسالی اشتباه است' - }) - } - - const user = await UserModel.findOne({ mobile }) - if (!user) { - return res.status(404).json({ - error: true, - message: 'کاربری با این شماره موبایل یافت نشد' - }) - } - const token = TokenService.sign({ id: user._id }) - if (user.otp === otp) { - // if (user.user_name === null) { - // return res.json({ - // message: 'کد تایید صحیح بود', - // page: 'username' - // }) - // } - - // if (!user.first_name && !user.last_name) { - // return res.json({ - // message: 'کد تایید صحیح بود', - // page: 'name' - // }) - // } - - // if (!user.user_type) { - // return res.json({ - // message: 'کد تایید صحیح بود', - // page: 'usertype' - // }) - // } - - // اگر همه فیلدها پر بودند - // return res.json({ - // message: 'کد تایید صحیح بود', - // token, - // user_type: user.user_type, - // page: 'home', - // id: user._id - // }) - let step = '' - if (user.user_name === null) { step = 'user_name' } else if - (!user.password) { step = 'password' } else if - (!user.first_name) { step = 'first_name' } else if - (!user.user_type) { step = 'user_type' } else { step = 'profile_image' } - if (!user.user_type || user.user_name === null || !user.first_name || !user.last_name) { - return res.json({ - message: 'کد تایید صحیح بود', - token, - step, - user_type: null, - page: 'auth-page', - id: user._id - }) - } - return res.json({ - message: 'کد تایید صحیح بود', - token, - user_type: user.user_type, - step, - page: 'home', - id: user._id - }) - } - - return res.status(422).json({ - error: true, - message: 'کد تایید اشتباه است' - }) - } catch (error) { - next(error) - } -} - -module.exports = { - verifyUser -} diff --git a/public/modstagram-back/controllers/application/messages/messageController.js b/public/modstagram-back/controllers/application/messages/messageController.js deleted file mode 100644 index 7147781..0000000 --- a/public/modstagram-back/controllers/application/messages/messageController.js +++ /dev/null @@ -1,127 +0,0 @@ -const MessageModel = require('../../../models/MessageModel') -const UserModel = require('../../../models/UserModel') -const jwt = require('jsonwebtoken') -const moment = require('moment-jalaali') -const getMessages = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - - const { search } = req.query - - // پیدا کردن تمام پیام‌هایی که کاربر مورد نظر آنها فرستنده یا گیرنده بوده است - const messageFilter = { - $or: [ - { senderId: userId }, - { receiverId: userId } - ] - } - - // پیدا کردن تمام پیام‌ها با فیلتر و سورت براساس جدیدترین پیام - const messages = await MessageModel.find(messageFilter).sort({ createdAt: -1 }) - - // استخراج شناسه‌های تمام کاربران مرتبط با این پیام‌ها (بدون تکرار) - const userIdToLastMessageDate = {} - messages.forEach(message => { - if (!userIdToLastMessageDate[message.senderId]) { - userIdToLastMessageDate[message.senderId] = message.createdAt - } - if (!userIdToLastMessageDate[message.receiverId]) { - userIdToLastMessageDate[message.receiverId] = message.createdAt - } - }) - - // تبدیل مجموعه شناسه‌های کاربر به آرایه - const userIdsArray = Object.keys(userIdToLastMessageDate) - - // ساخت فیلتر جستجو برای کاربران مرتبط - const userFilter = { _id: { $in: userIdsArray } } - - if (search) { - userFilter.$and = [ - { _id: { $in: userIdsArray } }, // فقط کاربران مرتبط - { - $or: [ - { first_name: { $regex: search, $options: 'i' } }, - { last_name: { $regex: search, $options: 'i' } }, - { user_name: { $regex: search, $options: 'i' } } - ] - } - ] - } - - // پیدا کردن اطلاعات کاربران مرتبط بر اساس فیلتر جستجو و شمارش تعداد پیام‌های خوانده نشده برای هر کاربر - const usersData = await UserModel.find(userFilter) - const usersWithUnreadCount = await Promise.all(usersData.map(async (user) => { - const unreadMessagesCount = await MessageModel.countDocuments({ receiverId: userId, senderId: user._id, readStatus: 0 }) - - let lastOnlineStatus - const now = moment() - const lastOnline = moment(user.last_online) - const diffMinutes = now.diff(lastOnline, 'minutes') - - if (diffMinutes < 1) { - lastOnlineStatus = 'آنلاین' - } else if (diffMinutes < 60) { - lastOnlineStatus = `${diffMinutes} دقیقه پیش` - } else if (diffMinutes < 1440) { - lastOnlineStatus = `${Math.floor(diffMinutes / 60)} ساعت پیش` - } else { - lastOnlineStatus = `${Math.floor(diffMinutes / 1440)} روز پیش` - } - - // بررسی آیا کاربر فعلی در لیست بلاک‌شده‌های این کاربر است یا خیر - const blockedByCurrentUser = user.blocked_by.includes(userId) - const blockedYou = user.blocked_users.includes(userId) - - return { - first_name: user.first_name, - last_name: user.last_name, - user_name: user.user_name, - is_verified: user.is_verified, - profile_image: user.profile_image, - last_online: lastOnlineStatus, - _id: user._id, - unread_messages_count: unreadMessagesCount, - is_blocked: blockedByCurrentUser, - blocked_you: blockedYou, - last_message_date: userIdToLastMessageDate[user._id] - } - })) - - // حذف کاربر فعلی از آرایه و سورت کردن کاربران براساس آخرین پیام - const filteredUsersData = usersWithUnreadCount - .filter(user => user._id.toString() !== userId) - .sort((a, b) => new Date(b.last_message_date) - new Date(a.last_message_date)) - - res.status(200).json({ - filteredUsersData, - totalMessages: messages.length - }) - } catch (error) { - next(error) - } -} - -const getUnreadMessages = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - - // پیدا کردن تمام پیام‌های کاربر که هنوز خوانده نشده‌اند - const unreadMessagesCount = await MessageModel.countDocuments({ receiverId: userId, readStatus: 0 }) - - res.status(200).json({ unread_messages_count: unreadMessagesCount }) - } catch (error) { - next(error) - } -} -module.exports = { - getMessages, getUnreadMessages -} diff --git a/public/modstagram-back/controllers/application/notification/notificationController.js b/public/modstagram-back/controllers/application/notification/notificationController.js deleted file mode 100644 index 3b44cad..0000000 --- a/public/modstagram-back/controllers/application/notification/notificationController.js +++ /dev/null @@ -1,68 +0,0 @@ -const jwt = require('jsonwebtoken') -const NotificationModel = require('../../../models/NotificationModel') -const jMoment = require('moment-jalaali') - -const getNotifications = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - const { page = 1, limit = 10, search } = req.query // افزودن پارامترهای صفحه‌بندی به درخواست - const filter = { user_id: userId } - if (search) { - filter.$or = [ - { title: { $regex: search, $options: 'i' } }, - { description: { $regex: search, $options: 'i' } } - ] - } - // استفاده از مدل پیجینیت شده برای دریافت نتایج صفحه‌بندی شده - const options = { - page: parseInt(page), // تبدیل صفحه به عدد صحیح - limit: parseInt(limit), // تبدیل محدودیت به عدد صحیح - sort: { createdAt: -1 } // بر اساس زمان ایجاد (createdAt) مرتب کنید (نزولی) - } - - // دریافت اعلان‌های مربوط به کاربر با استفاده از userId - let notifications = await NotificationModel.paginate(filter, options) - const totalPages = notifications.totalPages - const totalItems = notifications.totalDocs - notifications = notifications?.docs.map(notification => { - const jDate = jMoment(notification.createdAt).format('jYYYY-jMM-jDD HH:mm') - return { - ...notification._doc, - createdAt: jDate - } - }) - // تغییر وضعیت "read" اعلان‌ها به "true" - await NotificationModel.updateMany({ user_id: userId }, { read: true }) - res.json({ - notifications, - totalPages, // ارسال تعداد کل صفحات - totalItems // ارسال تعداد کل آیتم‌ها - }) - } catch (error) { - next(error) - } -} -const unreadNotifications = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - - // دریافت تعداد اعلان‌های جدید برای کاربر - const newNotificationsCount = await NotificationModel.countDocuments({ user_id: userId, read: false }).exec() - - res.json({ newNotificationsCount }) - } catch (error) { - next(error) - } -} - -module.exports = { - getNotifications, unreadNotifications -} diff --git a/public/modstagram-back/controllers/application/offer/offerController.js b/public/modstagram-back/controllers/application/offer/offerController.js deleted file mode 100644 index cfb9a40..0000000 --- a/public/modstagram-back/controllers/application/offer/offerController.js +++ /dev/null @@ -1,439 +0,0 @@ -/* eslint-disable camelcase */ -const jwt = require('jsonwebtoken') -const jMoment = require('moment-jalaali') -const OfferModel = require('../../../models/OfferModel') -const UserModel = require('../../../models/UserModel') -const OfferTypeModel = require('../../../models/OfferTypeModel') -const PaymentModel = require('../../../models/PaymentModel') -const NotificationModel = require('../../../models/NotificationModel') -const { default: axios } = require('axios') -const CommentModel = require('../../../models/CommentModel') - -const getOfferPriceFromDatabase = async (itemName) => { - const item = await OfferTypeModel.findOne({ name: itemName }) - if (!item) { - throw new Error('Item not found in database') - } - return item.price -} - -const getOfferTypes = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - - const user = await UserModel.findById(userId) - if (!user) { - return res.status(422).json({ - error: true, - message: 'کاربر یافت نشد' - }) - } - let offerTypes = await OfferTypeModel.find({}, 'name price') - - // بررسی برای مواردی مانند پیدا نشدن انواع پروژه - if (!offerTypes) { - return res.status(404).json({ message: 'انواع پروژه یافت نشد.' }) - } - // اگر کاربر درخواست ماهانه نداشته باشد، نوع پروژه ماهانه را حذف کنید - if (user.monthly_free_offer <= 0) { - offerTypes = offerTypes.filter(projectType => projectType.name !== 'free') - } - // ارسال انواع پروژه به کاربر - res.status(200).json({ offerTypes }) - } catch (error) { - // در صورت بروز خطا، ارسال پیام خطا به کاربر - console.error('Error in getOfferTypes:', error) - res.status(500).json({ message: 'خطا در دریافت انواع پروژه.' }) - } -} -const getUserOffers = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - const { page = 1, limit = 10, status_filter, id } = req.query // افزودن پارامترهای صفحه‌بندی به درخواست - let filter = {} - let filterbyid = {receiver: id} - let filterbyidsender = {sender: id} - if (status_filter === 'درخواست') { - filter = { sender: userId } - } else { - filter = { receiver: userId } - } - - // تنظیم گزینه‌های صفحه‌بندی - const options = { - page: parseInt(page), // تبدیل صفحه به عدد صحیح - limit: parseInt(limit), // تبدیل محدودیت به عدد صحیح - sort: { createdAt: -1 }, // بر اساس زمان ایجاد (createdAt) مرتب کنید (نزولی) - populate: [ - { - path: 'sender', - select: 'profile_image user_level first_name last_name user_name is_verified user_score rate' - }, - { - path: 'receiver', - select: 'profile_image user_level first_name last_name user_name is_verified user_score rate' - } - ] - } - - // دریافت آفرهای صفحه‌بندی شده - let offer = await OfferModel.paginate(filter, options) - let offerbyid = await OfferModel.paginate(filterbyid, options) - let offerbyidsender = await OfferModel.paginate(filterbyidsender, options) - - const totalPages = offer.totalPages - const totalItems = offer.totalDocs - - // فرمت کردن تاریخ و ارسال پاسخ - offer = offer?.docs.map(offer => { - const jDate = jMoment(offer.createdAt).format('jYYYY-jMM-jDD HH:mm') - return { - ...offer._doc, - createdAt: jDate - } - }) - res.json({ - offerbyidsender, - offerbyid, - offer, - totalPages, // ارسال تعداد کل صفحات - totalItems // ارسال تعداد کل آیتم‌ها - }) - } catch (error) { - next(error) - } -} - -const updateOfferStatus = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id // ID کاربری که درخواست را به‌روزرسانی می‌کند - const reciverUser = await UserModel.findById(userId) - - const { offerId, action } = req.body // آیدی آفر و اکشن (accept یا reject) - - // بررسی اعتبار ورودی‌ها - if (!offerId || !['accept', 'reject'].includes(action)) { - return res.status(400).json({ error: 'Invalid input' }) - } - - // یافتن آفر موردنظر - const offer = await OfferModel.findById(offerId) - const senderUser = await UserModel.findById(offer?.sender) - - if (!offer) { - return res.status(404).json({ error: 'Offer not found' }) - } - - // بررسی اینکه آیا کاربر گیرنده این آفر است یا خیر - if (offer.receiver.toString() !== userId) { - return res.status(403).json({ error: 'You are not authorized to update this offer' }) - } - - // بررسی اینکه آیا آفر قبلاً به‌روزرسانی شده یا نه - if (offer.status !== 'pending') { - return res.status(400).json({ error: 'Offer has already been updated', message: 'وضعیت این درخواست قبلا تغییر کرده است.' }) - } - - // به‌روزرسانی وضعیت آفر بر اساس اکشن - offer.status = action === 'accept' ? 'accepted' : 'rejected' - await offer.save() - - if (action === 'accept') { - const data = JSON.stringify({ - mobile: senderUser?.mobile, - templateId: '633448', - parameters: [ - { name: 'USER', value: reciverUser?.first_name + ' ' + reciverUser?.last_name }, - { name: 'EMPLOYER', value: senderUser?.first_name + ' ' + senderUser?.last_name } - ] - }) - - const config = { - method: 'post', - url: 'https://api.sms.ir/v1/send/verify', - headers: { - 'Content-Type': 'application/json', - Accept: 'text/plain', - 'x-api-key': '2JKxGbTzE64t0YTkjip6RYHnm9mq1haMlidF8WWwQunwubHFVW6iaMmfFQbMXEDt' - }, - data - } - axios(config) - .then(function (response) { - }) - .catch(function (error) { - console.log(error) - }) - } else { - const data = JSON.stringify({ - mobile: senderUser?.mobile, - templateId: '682678', - parameters: [ - { name: 'USER', value: reciverUser?.first_name + ' ' + reciverUser?.last_name }, - { name: 'EMPLOYER', value: senderUser?.first_name + ' ' + senderUser?.last_name } - ] - }) - - const config = { - method: 'post', - url: 'https://api.sms.ir/v1/send/verify', - headers: { - 'Content-Type': 'application/json', - Accept: 'text/plain', - 'x-api-key': '2JKxGbTzE64t0YTkjip6RYHnm9mq1haMlidF8WWwQunwubHFVW6iaMmfFQbMXEDt' - }, - data - } - axios(config) - .then(function (response) { - }) - .catch(function (error) { - console.log(error) - }) - } - res.status(200).json({ - message: `Offer has been ${offer.status} successfully`, - offerId: offer._id, - status: offer.status - }) - } catch (error) { - next(error) - } -} - -// Controller function for handling successful advertising payment -const handleSuccessfulOfferPayment = async (req, res) => { - try { - const { reciverId, offerType } = req.body - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - - // Check user's free offer eligibility - const user = await UserModel.findById(userId) - if (!user) return res.status(404).json({ error: 'User not found' }) - // Check user's free offer eligibility - const reciverUser = await UserModel.findById(reciverId) - if (!user) return res.status(404).json({ error: 'User not found' }) - - let price - if (user.monthly_free_offer > 0 && offerType === 'free') { - // Use free offer and decrement counter - price = 0 - user.monthly_free_offer -= 1 - await user.save() - } else { - // Retrieve offer price based on type - price = await getOfferPriceFromDatabase(offerType) - - // Create a new payment entry - const payment = new PaymentModel({ - amount: Number(price), - status: 'successful', - authority: '', // Add authority if available - user_id: userId, - type: 'offer', - installment_step: null - }) - await payment.save() - } - // Create a new payment entry - const payment = new PaymentModel({ - amount: Number(price), - status: 'successful', - authority: '', // Add authority if available - user_id: userId, - type: 'offer', - installment_step: null - }) - await payment.save() - - // Create a new offer - const offer = new OfferModel({ - sender: userId, - receiver: reciverId, - transaction_id: payment._id // Link the payment to the offer - }) - await offer.save() - console.log(reciverUser?.first_name) - - // Send notification to selected user - const notification = new NotificationModel({ - user_id: reciverId, - project_post_id: offer?._id, - type: 'new_offer', - title: 'درخواست همکاری جدید', - description: `${reciverUser?.first_name} عزیز یک درخواست همکاری برای شما در مجموعه مدستاگرام ثبت شد` - }) - await notification.save() - - // Send Sms - const data = JSON.stringify({ - mobile: reciverUser?.mobile, - templateId: '569006', - parameters: [ - { name: 'FIRSTNAME', value: reciverUser?.first_name }, - { name: 'LASTNAME', value: reciverUser?.last_name } - - ] - }) - - const config = { - method: 'post', - url: 'https://api.sms.ir/v1/send/verify', - headers: { - 'Content-Type': 'application/json', - Accept: 'text/plain', - 'x-api-key': '2JKxGbTzE64t0YTkjip6RYHnm9mq1haMlidF8WWwQunwubHFVW6iaMmfFQbMXEDt' - }, - data - } - axios(config) - .then(function (response) { - }) - .catch(function (error) { - console.log(error) - }) - - // Send event based on payment status - - // Emit a success event - if ('eventEmitter' in req.app) { - req.app.get('eventEmitter').emit('paymentSuccess', { - message: 'Payment and offer created successfully', - offerId: offer._id - }) - } else { - console.error('Error: eventEmitter is not defined or not properly configured.') - } - - res.status(200).json({ - message: 'Payment and offer recorded successfully', - offerId: offer._id, - price - }) - } catch (error) { - console.error('Error occurred:', error) - res.status(500).json({ error: 'Internal server error' }) - } -} -// Controller function for handling failed advertising payment -const handleFailedOfferPayment = async (req, res) => { - try { - const { offerType } = req.body - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - - const price = await getOfferPriceFromDatabase(offerType) - - // Create a new payment entry - const payment = new PaymentModel({ - amount: Number(price), - status: 'failed', - authority: '', // Add authority if available - user_id: userId, - type: 'offer', - installment_step: null - }) - await payment.save() - - // Emit a failure event - if ('eventEmitter' in req.app) { - req.app.get('eventEmitter').emit('paymentFailed', { message: 'Payment failed' }) - } else { - console.error('Error: eventEmitter is not defined or not properly configured.') - } - - res.status(200).json({ message: 'Payment failed', price }) - } catch (error) { - console.error('Error occurred:', error) - res.status(500).json({ error: 'Internal server error' }) - } -} - -const createOfferComment = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - - const { offerId, comment, rate, user_id } = req.body - if (!offerId || !comment || !rate || !user_id) { - return res.status(400).send({ message: 'All fields are required' }) - } - // بررسی اینکه آیا کاربر قبلاً برای این پیشنهاد نظر داده است - const existingComment = await CommentModel.findOne({ - offer: offerId, - creator: userId - }) - if (existingComment) { - return res.status(400).send({ message: 'شما قبلاً نظر خود را برای این درخواست ثبت کرده‌اید' }) - } - const newComment = new CommentModel({ - user: user_id, - offer: offerId, - creator: userId, - rating: rate, - comment, - comment_for: 'user', - status: 'pending' - }) - await newComment.save() - - const user = await UserModel.findById(user_id) - - // پیدا کردن کامنت‌ها و محاسبه‌ی امتیاز کل - const comments = await CommentModel.find({ user: user_id, comment_for: 'user' }) - const totalRating = Number(comments.reduce((acc, comment) => acc + comment.rating, 0)) - - let userLevel - if (user.expertise === 'مدل') { - if (totalRating <= 50) userLevel = 'تازه وارد' - else if (totalRating <= 100) userLevel = 'استاندارد' - else if (totalRating <= 300) userLevel = 'حرفه‌ای' - else userLevel = 'استاد' - } else if (['زیبایی', 'عکاس'].includes(user.expertise)) { - if (totalRating <= 50) userLevel = 'تازه وارد' - else if (totalRating <= 100) userLevel = 'استاندارد' - else if (totalRating <= 300) userLevel = 'حرفه‌ای' - else userLevel = 'استاد' - } - - user.user_score = totalRating - user.user_level = userLevel - - const totalComments = await CommentModel.countDocuments({ user: user_id, comment_for: 'user' }) - const averageRating = totalRating / totalComments - user.rate = averageRating.toFixed(1) - await user.save() - - res.status(200).json({ message: 'نظر شما با موفقیت ثبت شد' }) - } catch (error) { - next(error) - } -} - -module.exports = { - getUserOffers, - getOfferTypes, - handleSuccessfulOfferPayment, - handleFailedOfferPayment, - updateOfferStatus, - createOfferComment -} diff --git a/public/modstagram-back/controllers/application/payment/paymentController.js b/public/modstagram-back/controllers/application/payment/paymentController.js deleted file mode 100644 index eaca055..0000000 --- a/public/modstagram-back/controllers/application/payment/paymentController.js +++ /dev/null @@ -1,1185 +0,0 @@ -/* eslint-disable eqeqeq */ -const axios = require('axios') -const TypeAndPriceModel = require('../../../models/TypeAndPriceModel') -const ProjectModel = require('../../../models/ProjectModel') -const PaymentModel = require('../../../models/PaymentModel') -const jwt = require('jsonwebtoken') -const RequestModel = require('../../../models/RequestModel') -const NotificationModel = require('../../../models/NotificationModel') -const UserModel = require('../../../models/UserModel') -const AdvertisingTypeModel = require('../../../models/AdvertisingTypeModel') -const AdvertisingModel = require('../../../models/AdvertisingModel') - -const apiKey = process.env.MERCHENT_CODE // Replace with your ZarinPal API Key - -// Function to get price based on item name from database -const getPriceFromDatabase = async (itemName) => { - const item = await TypeAndPriceModel.findOne({ name: itemName }) - if (!item) { - throw new Error('Item not found in database') - } - return item.price -} -const getAdvertisingPriceFromDatabase = async (itemName) => { - const item = await AdvertisingTypeModel.findOne({ name: itemName }) - if (!item) { - throw new Error('Item not found in database') - } - return item.price -} - -// Controller function for initiating payment -const initiatePayment = async (req, res) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - // eslint-disable-next-line no-unused-vars - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - const itemName = req.body.item_name // Get item name from request body - const price = await getPriceFromDatabase(itemName) // Get price from database - const projectId = req.body.projectId // Get project ID from request body - // Save project ID for later use in callback URL - req.session.projectId = projectId - const item = await TypeAndPriceModel.findOne({ name: itemName }) - const user = await UserModel.findById(userId) - - if (item.name === 'free' && item.price === 0) { - if (user.daily_free_request > 0) { - user.daily_free_request -= 1 - await user.save() - const project = await ProjectModel.findById(projectId) - if (!project) { - res.status(404).send('Project not found') - return - } - project.payment_status = 'done' // Set project status to 'done' - project.status = 'paid' // Set project status to 'done' - await project.save() - res.status(200).json({ message: 'پروژه رایگان با موفقیت ایجاد شد', projectId, type: 'free' }) - } else { - res.status(403).json({ message: 'شما قبلاً از درخواست رایگان امروز استفاده کرده‌اید.' }) - } - } else { - const response = await axios.post('https://www.zarinpal.com/pg/rest/WebGate/PaymentRequest.json', { - MerchantID: apiKey, - Amount: Number(price), - Description: `پرداخت برای سفارش شماره ${projectId}`, - CallbackURL: `${process.env.APP_URL}/projects/payment?projectId=${projectId}&itemName=${itemName}&userId=${userId}` // Assuming your backend URL for handling payment callback - }) - - const data = response.data - if (data.Status === 100) { - // Payment request was successful - const authority = data.Authority // The payment authority (شناسه پرداخت) - res.status(200).json({ authority }) - } else { - // Payment request failed - console.error('Error occurred while initiating payment:', data) - res.status(500).json({ error: 'Error occurred while initiating payment' }) - } - } - } catch (error) { - // Error occurred while getting price from database or sending the request - console.error('Error occurred:', error) - res.status(500).json({ error: 'Internal server error' }) - } -} - -// Controller function for handling payment callback from ZarinPal -const handlePaymentCallback = async (req, res) => { - try { - // console.log(req.query) - // Extract payment status and authority from ZarinPal callback - const status = req.query.Status - const authority = req.query.Authority - const projectId = req.query.projectId // Get project ID from session - const itemName = req.query.itemName // Get project ID from session - const userId = req.query.userId // Get project ID from session - // Clear project ID from session - // Query ZarinPal API to verify payment status - const verificationUrl = 'https://www.zarinpal.com/pg/rest/WebGate/PaymentVerification.json' - const price = await getPriceFromDatabase(itemName) // Get price from database - const verificationResponse = await axios.post(verificationUrl, { - MerchantID: apiKey, - Authority: authority, - Amount: Number(price) - }) - - const verificationData = verificationResponse.data - if (verificationData.Status === 100) { - const payment = new PaymentModel({ - amount: Number(price), - status: 'successful', - authority, - user_id: userId, // فرضاً شما از نوع میان‌افزارهای مدیریت کاربر استفاده می‌کنید و اطلاعات کاربر را از طریق `req.user` در دسترس دارید - project_id: projectId, - type: 'create', - installment_step: null - // دیگر اطلاعات مورد نیاز برای ثبت پرداخت - }) - await payment.save() - - // Payment verification is successful - // Now, update project status to 'done' or desired status - const project = await ProjectModel.findById(projectId) - if (!project) { - res.status(404).send('Project not found') - return - } - project.payment_status = 'done' // Set project status to 'done' - project.status = 'paid' // Set project status to 'done' - await project.save() - - // Send event based on payment status - if ('eventEmitter' in req.app) { - if (status === 'OK') { - // Payment is successful - // Emit an event to be listened to in the frontend - // Example event name: 'paymentSuccess' - // Example data: { message: 'Payment successful' } - // You can customize the event name and data as needed - req.app.get('eventEmitter').emit('paymentSuccess', { message: 'Payment successful' }) - } else { - // Payment is canceled or failed - // Emit an event to be listened to in the frontend - // Example event name: 'paymentFailed' - // Example data: { message: 'Payment canceled or failed' } - // You can customize the event name and data as needed - req.app.get('eventEmitter').emit('paymentFailed', { message: 'Payment canceled or failed' }) - } - } else { - console.error('Error: eventEmitter is not defined or not properly configured.') - } - - // Redirect to the callback URL with the project ID - res.redirect(`modstagram://SuccessPay?projectId=${projectId}&price=${price}&type=create`) - } else { - // Payment verification failed - const payment = new PaymentModel({ - amount: Number(price), - status: 'failed', - authority, - user_id: userId, // فرضاً شما از نوع میان‌افزارهای مدیریت کاربر استفاده می‌کنید و اطلاعات کاربر را از طریق `req.user` در دسترس دارید - project_id: projectId, - type: 'create' - // دیگر اطلاعات مورد نیاز برای ثبت پرداخت - }) - await payment.save() - res.redirect(`modstagram://FailedPay?projectId=${projectId}&price=${price}&type=create`) - } - } catch (error) { - // Error occurred while verifying payment - console.error('Error occurred:', error) - res.status(500).send('Internal server error') - } -} - -// Bazaar -const handleSuccessfulPayment = async (req, res) => { - try { - const { projectId } = req.body - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - - const project = await ProjectModel.findById(projectId) - if (!project) { - res.status(404).send('Project not found') - return - } - - const price = await getPriceFromDatabase(project.project_type) - - // Create a new payment entry - const payment = new PaymentModel({ - amount: Number(price), - status: 'successful', - authority: '', // Add authority if available - user_id: userId, - project_id: projectId, - type: 'create', - installment_step: null - }) - await payment.save() - - // Update the project status to 'done' or 'paid' - project.payment_status = 'done' - project.status = 'paid' - await project.save() - - // Emit a success event - if ('eventEmitter' in req.app) { - req.app.get('eventEmitter').emit('paymentSuccess', { message: 'Payment successful' }) - } else { - console.error('Error: eventEmitter is not defined or not properly configured.') - } - - res.status(200).json({ message: 'Payment recorded successfully', projectId, price }) - } catch (error) { - console.error('Error occurred:', error) - res.status(500).json({ error: 'Internal server error' }) - } -} -// Controller function for handling failed payment -const handleFailedPayment = async (req, res) => { - try { - const { projectId } = req.body - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - - const project = await ProjectModel.findById(projectId) - if (!project) { - res.status(404).send('Project not found') - return - } - - const price = await getPriceFromDatabase(project.project_type) - - // Create a new payment entry - const payment = new PaymentModel({ - amount: Number(price), - status: 'failed', - authority: '', // Add authority if available - user_id: userId, - project_id: projectId, - type: 'create' - }) - await payment.save() - - // Emit a failure event - if ('eventEmitter' in req.app) { - req.app.get('eventEmitter').emit('paymentFailed', { message: 'Payment failed' }) - } else { - console.error('Error: eventEmitter is not defined or not properly configured.') - } - - res.status(200).json({ message: 'Payment failed', projectId, price }) - } catch (error) { - console.error('Error occurred:', error) - res.status(500).json({ error: 'Internal server error' }) - } -} - -const paymentRequestStepOne = async (req, res) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - const projectId = req.body.projectId - // Find the project - const project = await ProjectModel.findById(projectId) - if (!project) { - return res.status(404).json({ error: 'Project not found' }) - } - - // Get the final price from the request model - const requestId = req.body.requestId - const request = await RequestModel.findById(requestId) - if (!request) { - return res.status(404).json({ error: 'Request not found' }) - } - const halfAmount = request.price / 2 - - // Proceed with ZarinPal payment request - const response = await axios.post('https://www.zarinpal.com/pg/rest/WebGate/PaymentRequest.json', { - MerchantID: apiKey, - Amount: parseInt(halfAmount + halfAmount / 100 * 9), - Description: `پرداخت برای سفارش شماره ${projectId}`, - CallbackURL: `${process.env.APP_URL}/projects/payment-request-step-one-callback?projectId=${projectId}&requestId=${requestId}&userId=${userId}` // Callback URL including requestId - }) - - const data = response.data - if (data.Status === 100) { - // Payment request was successful - const authority = data.Authority // The payment authority - res.status(200).json({ authority }) - } else { - // Payment request failed - console.error('Error occurred while initiating payment:', data) - res.status(500).json({ error: 'Error occurred while initiating payment' }) - } - } catch (error) { - // Error occurred while getting price from database or sending the request - console.error('Error occurred:', error) - res.status(500).json({ error: 'Internal server error' }) - } -} -const paymentRequestStepTwo = async (req, res) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - const projectId = req.body.projectId - const installmentNumber = req.body.installmentNumber - // Find the project - const project = await ProjectModel.findById(projectId) - if (!project) { - return res.status(404).json({ error: 'Project not found' }) - } - - // Calculate the amount for the second installment (1/4 of the total price) - const totalAmount = project.final_price - const secondInstallmentAmount = totalAmount / 4 - // Proceed with ZarinPal payment request for the second installment - const response = await axios.post('https://www.zarinpal.com/pg/rest/WebGate/PaymentRequest.json', { - MerchantID: apiKey, - Amount: parseInt(secondInstallmentAmount + secondInstallmentAmount / 100 * 9), - Description: `پرداخت برای سفارش شماره ${projectId}`, - CallbackURL: `${process.env.APP_URL}/projects/payment-request-step-two-callback?projectId=${projectId}&userId=${userId}&installmentNumber=${installmentNumber}` // Callback URL - }) - - const data = response.data - if (data.Status === 100) { - // Payment request was successful - const authority = data.Authority // The payment authority - res.status(200).json({ authority }) - } else { - // Payment request failed - console.error('Error occurred while initiating payment:', data) - res.status(500).json({ error: 'Error occurred while initiating payment' }) - } - } catch (error) { - // Error occurred while getting price from database or sending the request - console.error('Error occurred:', error) - res.status(500).json({ error: 'Internal server error' }) - } -} -const paymentRequestStepAll = async (req, res) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - const projectId = req.body.projectId - - // Find the project - const project = await ProjectModel.findById(projectId) - if (!project) { - return res.status(404).json({ error: 'Project not found' }) - } - - // Calculate the amount for the second installment (1/4 of the total price) - const totalAmount = project.final_price - const secondInstallmentAmount = totalAmount / 2 - - // Proceed with ZarinPal payment request for the second installment - const response = await axios.post('https://www.zarinpal.com/pg/rest/WebGate/PaymentRequest.json', { - MerchantID: apiKey, - Amount: parseInt(secondInstallmentAmount + secondInstallmentAmount / 100 * 9), - Description: `پرداخت برای سفارش شماره ${projectId}`, - CallbackURL: `${process.env.APP_URL}/projects/payment-request-step-all-callback?projectId=${projectId}&userId=${userId}` // Callback URL - }) - - const data = response.data - if (data.Status === 100) { - // Payment request was successful - const authority = data.Authority // The payment authority - res.status(200).json({ authority }) - } else { - // Payment request failed - console.error('Error occurred while initiating payment:', data) - res.status(500).json({ error: 'Error occurred while initiating payment' }) - } - } catch (error) { - // Error occurred while getting price from database or sending the request - console.error('Error occurred:', error) - res.status(500).json({ error: 'Internal server error' }) - } -} -const paymentRequestStepOneCallback = async (req, res) => { - try { - const status = req.query.Status - const authority = req.query.Authority - const projectId = req.query.projectId - const requestId = req.query.requestId - const userId = req.query.userId - - // Verify payment status with ZarinPal - const verificationUrl = 'https://www.zarinpal.com/pg/rest/WebGate/PaymentVerification.json' - const request = await RequestModel.findById(requestId) - if (!request) { - return res.status(404).json({ error: 'Request not found' }) - } - const price = request.price / 2 - const verificationResponse = await axios.post(verificationUrl, { - MerchantID: apiKey, - Authority: authority, - Amount: parseInt(price + price / 100 * 9) - }) - - const verificationData = verificationResponse.data - if (verificationData.Status === 100) { - // Payment verification is successful - const payment = new PaymentModel({ - amount: price, - status: 'successful', - authority, - user_id: userId, - project_id: projectId, - type: 'installment', - installment_step: 1 - }) - await payment.save() - // Update project's installment details - - // Update project status - request.status = 'accepted' - await request.save() - const project = await ProjectModel.findById(projectId) - if (!project) { - return res.status(404).json({ error: 'Project not found' }) - } - project.selected_user = request.user - project.status = 'ongoing' - project.installments.push({ installment_number: 1, amount: price, due_date: new Date() }) - project.final_price = request.price - project.final_time = request.time - await project.save() - // Send notification to selected user - const notification = new NotificationModel({ - user_id: request.user, - project_post_id: projectId, - type: 'request_accepted', - title: 'انتخاب پیشنهاد', - description: `کارفرما پیشنهاد کاری شما برای پروژه ${project.title} را پذیرفت.` - }) - await notification.save() - - // Sms - - const userReciver = await UserModel.findById(request.user) - - const data = JSON.stringify({ - mobile: userReciver?.mobile, - templateId: '302876', - parameters: [ - { name: 'USER', value: userReciver?.first_name + ' ' + userReciver?.last_name }, - { name: 'PROJECT', value: project?.title } - ] - }) - - const config = { - method: 'post', - url: 'https://api.sms.ir/v1/send/verify', - headers: { - 'Content-Type': 'application/json', - Accept: 'text/plain', - 'x-api-key': '2JKxGbTzE64t0YTkjip6RYHnm9mq1haMlidF8WWwQunwubHFVW6iaMmfFQbMXEDt' - }, - data - } - axios(config) - .then(function (response) { - }) - .catch(function (error) { - console.log(error) - }) - - // End Sms - - // Send event based on payment status - if ('eventEmitter' in req.app) { - if (status === 'OK') { - // Payment is successful - req.app.get('eventEmitter').emit('paymentSuccess', { message: 'Payment successful' }) - } else { - // Payment is canceled or failed - req.app.get('eventEmitter').emit('paymentFailed', { message: 'Payment canceled or failed' }) - } - } else { - console.error('Error: eventEmitter is not defined or not properly configured.') - } - - // Redirect to the callback URL with the project ID - res.redirect(`modstagram://SuccessPay?projectId=${projectId}&price=${price}&type=steps&requestId=${requestId}`) - } else { - // Payment verification failed - const payment = new PaymentModel({ - amount: price, - status: 'failed', - authority, - user_id: userId, - project_id: projectId, - type: 'installment' - }) - await payment.save() - res.redirect(`modstagram://FailedPay?projectId=${projectId}&price=${price}&type=steps&requestId=${requestId}`) - } - } catch (error) { - console.error('Error occurred:', error) - res.status(500).send('Internal server error') - } -} - -const paymentRequestStepTwoCallback = async (req, res) => { - try { - const status = req.query.Status - const authority = req.query.Authority - const projectId = req.query.projectId - const userId = req.query.userId - const installmentNumber = req.query.installmentNumber - - // Verify payment status with ZarinPal - const verificationUrl = 'https://www.zarinpal.com/pg/rest/WebGate/PaymentVerification.json' - const project = await ProjectModel.findById(projectId) - if (!project) { - return res.status(404).json({ error: 'Project not found' }) - } - const totalAmount = project.final_price - const secondInstallmentAmount = totalAmount / 4 - const verificationResponse = await axios.post(verificationUrl, { - MerchantID: apiKey, - Authority: authority, - Amount: parseInt(secondInstallmentAmount + secondInstallmentAmount / 100 * 9) - }) - - const verificationData = verificationResponse.data - if (verificationData.Status === 100) { - // Payment verification is successful - const payment = new PaymentModel({ - amount: secondInstallmentAmount, - status: 'successful', - authority, - user_id: userId, - project_id: projectId, - type: 'installment', - installment_step: installmentNumber == 2 ? 2 : 3 - - }) - await payment.save() - - // Update project's installment details - project.installments.push({ installment_number: 2, amount: secondInstallmentAmount, due_date: new Date() }) - await project.save() - - // Send event based on payment status - if ('eventEmitter' in req.app) { - if (status === 'OK') { - // Payment is successful - req.app.get('eventEmitter').emit('paymentSuccess', { message: 'Payment successful' }) - } else { - // Payment is canceled or failed - req.app.get('eventEmitter').emit('paymentFailed', { message: 'Payment canceled or failed' }) - } - } else { - console.error('Error: eventEmitter is not defined or not properly configured.') - } - let description - // eslint-disable-next-line eqeqeq - if (installmentNumber == 2) { - description = 'پرداخت' - } else { - description = 'کارفرما کل مبلغ پروژه را پرداخت کرد.' - } - const notification = new NotificationModel({ - user_id: project.selected_user, - project_post_id: projectId, - type: 'payment_progress', - title: description, - description - }) - await notification.save() - // Redirect to the callback URL with the project ID - res.redirect(`modstagram://SuccessPay?projectId=${projectId}&price=${secondInstallmentAmount}&type=steps`) - } else { - // Payment verification failed - const payment = new PaymentModel({ - amount: secondInstallmentAmount, - status: 'failed', - authority, - user_id: userId, - project_id: projectId, - type: 'installment' - }) - await payment.save() - res.redirect(`modstagram://FailedPay?projectId=${projectId}&price=${secondInstallmentAmount}&type=steps`) - } - } catch (error) { - console.error('Error occurred:', error) - res.status(500).send('Internal server error') - } -} -const paymentRequestStepAllCallback = async (req, res) => { - try { - const status = req.query.Status - const authority = req.query.Authority - const projectId = req.query.projectId - const userId = req.query.userId - - // Verify payment status with ZarinPal - const verificationUrl = 'https://www.zarinpal.com/pg/rest/WebGate/PaymentVerification.json' - const project = await ProjectModel.findById(projectId) - if (!project) { - return res.status(404).json({ error: 'Project not found' }) - } - const totalAmount = project.final_price - const secondInstallmentAmount = totalAmount / 2 - const verificationResponse = await axios.post(verificationUrl, { - MerchantID: apiKey, - Authority: authority, - Amount: parseInt(secondInstallmentAmount + secondInstallmentAmount / 100 * 9) - }) - - const verificationData = verificationResponse.data - if (verificationData.Status === 100) { - // Payment verification is successful - const payment = new PaymentModel({ - amount: secondInstallmentAmount, - status: 'successful', - authority, - user_id: userId, - project_id: projectId, - type: 'installment', - installment_step: 'all' - - }) - await payment.save() - - // Update project's installment details - project.installments.push({ installment_number: 2, amount: secondInstallmentAmount, due_date: new Date() }) - await project.save() - const notification = new NotificationModel({ - user_id: project.selected_user, - project_post_id: projectId, - type: 'payment_progress', - title: 'پرداخت', - description: 'کارفرما کل مبلغ پروژه را پرداخت کرد.' - }) - await notification.save() - - // Send event based on payment status - if ('eventEmitter' in req.app) { - if (status === 'OK') { - // Payment is successful - req.app.get('eventEmitter').emit('paymentSuccess', { message: 'Payment successful' }) - } else { - // Payment is canceled or failed - req.app.get('eventEmitter').emit('paymentFailed', { message: 'Payment canceled or failed' }) - } - } else { - console.error('Error: eventEmitter is not defined or not properly configured.') - } - - // Redirect to the callback URL with the project ID - res.redirect(`modstagram://SuccessPay?projectId=${projectId}&price=${secondInstallmentAmount}&type=steps`) - } else { - // Payment verification failed - const payment = new PaymentModel({ - amount: secondInstallmentAmount, - status: 'failed', - authority, - user_id: userId, - project_id: projectId, - type: 'installment' - }) - await payment.save() - res.redirect(`modstagram://FailedPay?projectId=${projectId}&price=${secondInstallmentAmount}&type=steps`) - } - } catch (error) { - console.error('Error occurred:', error) - res.status(500).send('Internal server error') - } -} - -const initiateAdvertisingPayment = async (req, res) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - // eslint-disable-next-line no-unused-vars - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - const itemName = req.body.item_name // Get item name from request body - const price = await getAdvertisingPriceFromDatabase(itemName) // Get price from database - const advertisingId = req.body.advertisingId // Get project ID from request body - const showDiscount = req.body.showDiscount - - // Save project ID for later use in callback URL - req.session.advertisingId = advertisingId - const item = await AdvertisingTypeModel.findOne({ name: itemName }) - const user = await UserModel.findById(userId) - - if (item.name === 'free' && item.price === 0) { - if (user.daily_free_request > 0) { - user.daily_free_request -= 1 - await user.save() - const project = await ProjectModel.findById(advertisingId) - if (!project) { - res.status(404).send('Project not found') - return - } - project.payment_status = 'done' // Set project status to 'done' - project.status = 'paid' // Set project status to 'done' - await project.save() - res.status(200).json({ message: 'پروژه رایگان با موفقیت ایجاد شد', advertisingId, type: 'free' }) - } else { - res.status(403).json({ message: 'شما قبلاً از درخواست رایگان امروز استفاده کرده‌اید.' }) - } - } else { - const response = await axios.post('https://www.zarinpal.com/pg/rest/WebGate/PaymentRequest.json', { - MerchantID: apiKey, - Amount: showDiscount === true || showDiscount === 'true' ? Number(price + 20000) : Number(price), - Description: `پرداخت برای سفارش شماره ${advertisingId}`, - CallbackURL: `${process.env.APP_URL}/advertising/payment?advertisingId=${advertisingId}&itemName=${itemName}&userId=${userId}&showDiscount=${showDiscount}` // Assuming your backend URL for handling payment callback - }) - const data = response.data - if (data.Status === 100) { - // Payment request was successful - const authority = data.Authority // The payment authority (شناسه پرداخت) - res.status(200).json({ authority }) - } else { - // Payment request failed - console.error('Error occurred while initiating payment:', data) - res.status(500).json({ error: 'Error occurred while initiating payment' }) - } - } - } catch (error) { - // Error occurred while getting price from database or sending the request - console.error('Error occurred:', error) - res.status(500).json({ error: 'Internal server error' }) - } -} -const handleAdvertisingPaymentCallback = async (req, res) => { - try { - // console.log(req.query) - // Extract payment status and authority from ZarinPal callback - const status = req.query.Status - const authority = req.query.Authority - const advertisingId = req.query.advertisingId // Get project ID from session - const itemName = req.query.itemName // Get project ID from session - const userId = req.query.userId // Get project ID from session - const showDiscount = req.query.showDiscount // Get project ID from session - // Clear project ID from session - // Query ZarinPal API to verify payment status - - const verificationUrl = 'https://www.zarinpal.com/pg/rest/WebGate/PaymentVerification.json' - const price = await getAdvertisingPriceFromDatabase(itemName) // Get price from database - const verificationResponse = await axios.post(verificationUrl, { - MerchantID: apiKey, - Authority: authority, - Amount: showDiscount === true || showDiscount === 'true' ? Number(price + 20000) : Number(price) - }) - - const verificationData = verificationResponse.data - if (verificationData.Status === 100) { - const payment = new PaymentModel({ - amount: showDiscount === true || showDiscount === 'true' ? Number(price + 20000) : Number(price), - status: 'successful', - authority, - user_id: userId, // فرضاً شما از نوع میان‌افزارهای مدیریت کاربر استفاده می‌کنید و اطلاعات کاربر را از طریق `req.user` در دسترس دارید - advertising_id: advertisingId, - type: 'advertising', - installment_step: null - // دیگر اطلاعات مورد نیاز برای ثبت پرداخت - }) - await payment.save() - - // Payment verification is successful - // Now, update project status to 'done' or desired status - const advertising = await AdvertisingModel.findById(advertisingId) - if (!advertising) { - res.status(404).send('Advertising not found') - return - } - advertising.payment_status = 'done' // Set advertising status to 'done' - advertising.status = 'paid' // Set advertising status to 'done' - await advertising.save() - - // Send event based on payment status - if ('eventEmitter' in req.app) { - if (status === 'OK') { - // Payment is successful - // Emit an event to be listened to in the frontend - // Example event name: 'paymentSuccess' - // Example data: { message: 'Payment successful' } - // You can customize the event name and data as needed - req.app.get('eventEmitter').emit('paymentSuccess', { message: 'Payment successful' }) - } else { - // Payment is canceled or failed - // Emit an event to be listened to in the frontend - // Example event name: 'paymentFailed' - // Example data: { message: 'Payment canceled or failed' } - // You can customize the event name and data as needed - req.app.get('eventEmitter').emit('paymentFailed', { message: 'Payment canceled or failed' }) - } - } else { - console.error('Error: eventEmitter is not defined or not properly configured.') - } - - // Redirect to the callback URL with the advertising ID - res.redirect(`modstagram://SuccessPay?projectId=${advertisingId}&price=${showDiscount === true || showDiscount === 'true' ? Number(price + 20000) : Number(price)}&type=advertising&showDiscount=${showDiscount}`) - } else { - // Payment verification failed - const payment = new PaymentModel({ - amount: showDiscount ? Number(price + 20000) : Number(price), - status: 'failed', - authority, - user_id: userId, // فرضاً شما از نوع میان‌افزارهای مدیریت کاربر استفاده می‌کنید و اطلاعات کاربر را از طریق `req.user` در دسترس دارید - advertising_id: advertisingId, - type: 'advertising' - // دیگر اطلاعات مورد نیاز برای ثبت پرداخت - }) - await payment.save() - res.redirect(`modstagram://FailedPay?projectId=${advertisingId}&price=${showDiscount === true || showDiscount === 'true' ? Number(price + 20000) : Number(price)}&type=advertising&showDiscount=${showDiscount}`) - } - } catch (error) { - // Error occurred while verifying payment - console.error('Error occurred:', error) - res.status(500).send('Internal server error') - } -} - -// Controller function for handling successful advertising payment -const handleSuccessfulAdvertisingPayment = async (req, res) => { - try { - const { advertisingId } = req.body - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - const showDiscount = req.query.showDiscount // Get project ID from session - - const advertising = await AdvertisingModel.findById(advertisingId) - if (!advertising) { - res.status(404).send('Advertising not found') - return - } - - const price = await getAdvertisingPriceFromDatabase(advertising.type) - - // Create a new payment entry - const payment = new PaymentModel({ - amount: showDiscount === true || showDiscount === 'true' ? Number(price + 20000) : Number(price), - status: 'successful', - authority: '', // Add authority if available - user_id: userId, - advertising_id: advertisingId, - type: 'advertising', - installment_step: null - }) - await payment.save() - - // Update the advertising status to 'done' or 'paid' - advertising.payment_status = 'done' - advertising.status = 'paid' - await advertising.save() - - // Emit a success event - if ('eventEmitter' in req.app) { - req.app.get('eventEmitter').emit('paymentSuccess', { message: 'Payment successful' }) - } else { - console.error('Error: eventEmitter is not defined or not properly configured.') - } - - res.status(200).json({ message: 'Payment recorded successfully', advertisingId, price }) - } catch (error) { - console.error('Error occurred:', error) - res.status(500).json({ error: 'Internal server error' }) - } -} -// Controller function for handling failed advertising payment -const handleFailedAdvertisingPayment = async (req, res) => { - try { - const { advertisingId } = req.body - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - const showDiscount = req.query.showDiscount // Get project ID from session - const advertising = await AdvertisingModel.findById(advertisingId) - if (!advertising) { - res.status(404).send('Advertising not found') - return - } - - const price = await getAdvertisingPriceFromDatabase(advertising.type) - - // Create a new payment entry - const payment = new PaymentModel({ - amount: showDiscount === true || showDiscount === 'true' ? Number(price + 20000) : Number(price), - status: 'failed', - authority: '', // Add authority if available - user_id: userId, - advertising_id: advertisingId, - type: 'advertising' - }) - await payment.save() - - // Emit a failure event - if ('eventEmitter' in req.app) { - req.app.get('eventEmitter').emit('paymentFailed', { message: 'Payment failed' }) - } else { - console.error('Error: eventEmitter is not defined or not properly configured.') - } - - res.status(200).json({ message: 'Payment failed', advertisingId, price }) - } catch (error) { - console.error('Error occurred:', error) - res.status(500).json({ error: 'Internal server error' }) - } -} - -const republishAdvertisingPayment = async (req, res) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - // eslint-disable-next-line no-unused-vars - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - const itemName = req.body.item_name // Get item name from request body - const price = await getAdvertisingPriceFromDatabase(itemName) // Get price from database - const advertisingId = req.body.advertisingId // Get project ID from request body - const showDiscount = req.body.showDiscount - // Save project ID for later use in callback URL - req.session.advertisingId = advertisingId - const item = await AdvertisingTypeModel.findOne({ name: itemName }) - const user = await UserModel.findById(userId) - - if (item.name === 'free' && item.price === 0) { - if (user.daily_free_request > 0) { - user.daily_free_request -= 1 - await user.save() - const project = await ProjectModel.findById(advertisingId) - if (!project) { - res.status(404).send('Project not found') - return - } - project.payment_status = 'done' // Set project status to 'done' - project.status = 'paid' // Set project status to 'done' - await project.save() - res.status(200).json({ message: 'پروژه رایگان با موفقیت ایجاد شد', advertisingId, type: 'free' }) - } else { - res.status(403).json({ message: 'شما قبلاً از درخواست رایگان امروز استفاده کرده‌اید.' }) - } - } else { - const response = await axios.post('https://www.zarinpal.com/pg/rest/WebGate/PaymentRequest.json', { - MerchantID: apiKey, - Amount: showDiscount === true || showDiscount === 'true' ? Number(((price + 20000) * 70) / 100) : Number(((price) * 70) / 100), - Description: `پرداخت برای سفارش شماره ${advertisingId}`, - CallbackURL: `${process.env.APP_URL}/advertising/republish-verify-payment?advertisingId=${advertisingId}&itemName=${itemName}&userId=${userId}&showDiscount=${showDiscount}` // Assuming your backend URL for handling payment callback - }) - const data = response.data - if (data.Status === 100) { - // Payment request was successful - const authority = data.Authority // The payment authority (شناسه پرداخت) - res.status(200).json({ authority }) - } else { - // Payment request failed - console.error('Error occurred while initiating payment:', data) - res.status(500).json({ error: 'Error occurred while initiating payment' }) - } - } - } catch (error) { - // Error occurred while getting price from database or sending the request - console.error('Error occurred:', error) - res.status(500).json({ error: 'Internal server error' }) - } -} -const handleAdvertisingRepublishPaymentCallback = async (req, res) => { - try { - // console.log(req.query) - // Extract payment status and authority from ZarinPal callback - const status = req.query.Status - const authority = req.query.Authority - const advertisingId = req.query.advertisingId // Get project ID from session - const itemName = req.query.itemName // Get project ID from session - const userId = req.query.userId // Get project ID from session - const showDiscount = req.query.showDiscount // Get project ID from session - // Clear project ID from session - // Query ZarinPal API to verify payment status - const verificationUrl = 'https://www.zarinpal.com/pg/rest/WebGate/PaymentVerification.json' - const price = await getAdvertisingPriceFromDatabase(itemName) // Get price from database - const verificationResponse = await axios.post(verificationUrl, { - MerchantID: apiKey, - Authority: authority, - Amount: showDiscount === true || showDiscount === 'true' ? Number(((price + 20000) * 70) / 100) : Number(((price) * 70) / 100) - }) - - const verificationData = verificationResponse.data - if (verificationData.Status === 100) { - const payment = new PaymentModel({ - amount: showDiscount === true || showDiscount === 'true' ? Number(((price + 20000) * 70) / 100) : Number(((price) * 70) / 100), - status: 'successful', - authority, - user_id: userId, // فرضاً شما از نوع میان‌افزارهای مدیریت کاربر استفاده می‌کنید و اطلاعات کاربر را از طریق `req.user` در دسترس دارید - advertising_id: advertisingId, - type: 'advertising', - installment_step: null - // دیگر اطلاعات مورد نیاز برای ثبت پرداخت - }) - await payment.save() - - // Payment verification is successful - // Now, update project status to 'done' or desired status - const advertising = await AdvertisingModel.findById(advertisingId) - if (!advertising) { - res.status(404).send('Advertising not found') - return - } - advertising.payment_status = 'done' // Set advertising status to 'done' - advertising.status = 'accepted' // Set advertising status to 'done' - advertising.acceptedAt = new Date() - await advertising.save() - - // Send event based on payment status - if ('eventEmitter' in req.app) { - if (status === 'OK') { - // Payment is successful - // Emit an event to be listened to in the frontend - // Example event name: 'paymentSuccess' - // Example data: { message: 'Payment successful' } - // You can customize the event name and data as needed - req.app.get('eventEmitter').emit('paymentSuccess', { message: 'Payment successful' }) - } else { - // Payment is canceled or failed - // Emit an event to be listened to in the frontend - // Example event name: 'paymentFailed' - // Example data: { message: 'Payment canceled or failed' } - // You can customize the event name and data as needed - req.app.get('eventEmitter').emit('paymentFailed', { message: 'Payment canceled or failed' }) - } - } else { - console.error('Error: eventEmitter is not defined or not properly configured.') - } - - // Redirect to the callback URL with the advertising ID - res.redirect(`modstagram://SuccessPay?projectId=${advertisingId}&price=${showDiscount === true || showDiscount === 'true' ? Number(((price + 20000) * 70) / 100) : Number(((price) * 70) / 100)}&type=advertising-republish&showDiscount=${showDiscount}`) - } else { - // Payment verification failed - const payment = new PaymentModel({ - amount: showDiscount === true || showDiscount === 'true' ? Number(((price + 20000) * 70) / 100) : Number(((price) * 70) / 100), - status: 'failed', - authority, - user_id: userId, // فرضاً شما از نوع میان‌افزارهای مدیریت کاربر استفاده می‌کنید و اطلاعات کاربر را از طریق `req.user` در دسترس دارید - advertising_id: advertisingId, - type: 'advertising' - // دیگر اطلاعات مورد نیاز برای ثبت پرداخت - }) - await payment.save() - res.redirect(`modstagram://FailedPay?projectId=${advertisingId}&price=${showDiscount === true || showDiscount === 'true' ? Number(((price + 20000) * 70) / 100) : Number(((price) * 70) / 100)}&type=advertising-republish&showDiscount=${showDiscount}`) - } - } catch (error) { - // Error occurred while verifying payment - console.error('Error occurred:', error) - res.status(500).send('Internal server error') - } -} -// Controller function for handling successful republish advertising payment -const handleSuccessfulAdvertisingRepublishPayment = async (req, res) => { - try { - const { advertisingId } = req.body - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - const showDiscount = req.query.showDiscount - - const advertising = await AdvertisingModel.findById(advertisingId) - if (!advertising) { - res.status(404).send('Advertising not found') - return - } - - const price = await getAdvertisingPriceFromDatabase(advertising.type) - - // Create a new payment entry - const payment = new PaymentModel({ - amount: showDiscount === true || showDiscount === 'true' ? Number((price + 20000) * 0.7) : Number(price * 0.7), - status: 'successful', - authority: '', // Add authority if available - user_id: userId, - advertising_id: advertisingId, - type: 'advertising-republish', - installment_step: null - }) - await payment.save() - - // Update the advertising status to 'done' or 'accepted' - advertising.payment_status = 'done' - advertising.status = 'accepted' - advertising.acceptedAt = new Date() - await advertising.save() - - // Emit a success event - if ('eventEmitter' in req.app) { - req.app.get('eventEmitter').emit('paymentSuccess', { message: 'Republish payment successful' }) - } else { - console.error('Error: eventEmitter is not defined or not properly configured.') - } - - res.status(200).json({ message: 'Republish payment recorded successfully', advertisingId, price }) - } catch (error) { - console.error('Error occurred:', error) - res.status(500).json({ error: 'Internal server error' }) - } -} -// Controller function for handling failed republish advertising payment -const handleFailedAdvertisingRepublishPayment = async (req, res) => { - try { - const { advertisingId } = req.body - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - const showDiscount = req.query.showDiscount - - const advertising = await AdvertisingModel.findById(advertisingId) - if (!advertising) { - res.status(404).send('Advertising not found') - return - } - - const price = await getAdvertisingPriceFromDatabase(advertising.type) - - // Create a new payment entry - const payment = new PaymentModel({ - amount: showDiscount === true || showDiscount === 'true' ? Number((price + 20000) * 0.7) : Number(price * 0.7), - status: 'failed', - authority: '', // Add authority if available - user_id: userId, - advertising_id: advertisingId, - type: 'advertising-republish' - }) - await payment.save() - - // Emit a failure event - if ('eventEmitter' in req.app) { - req.app.get('eventEmitter').emit('paymentFailed', { message: 'Republish payment failed' }) - } else { - console.error('Error: eventEmitter is not defined or not properly configured.') - } - - res.status(200).json({ message: 'Republish payment failed', advertisingId, price }) - } catch (error) { - console.error('Error occurred:', error) - res.status(500).json({ error: 'Internal server error' }) - } -} - -module.exports = { - initiatePayment, - handlePaymentCallback, - paymentRequestStepOne, - paymentRequestStepTwo, - paymentRequestStepAll, - paymentRequestStepOneCallback, - paymentRequestStepTwoCallback, - paymentRequestStepAllCallback, - initiateAdvertisingPayment, - handleAdvertisingPaymentCallback, - republishAdvertisingPayment, - handleAdvertisingRepublishPaymentCallback, - handleSuccessfulPayment, - handleFailedPayment, - handleSuccessfulAdvertisingPayment, - handleFailedAdvertisingPayment, - handleSuccessfulAdvertisingRepublishPayment, - handleFailedAdvertisingRepublishPayment -} diff --git a/public/modstagram-back/controllers/application/payment/paymentControllerWeb.js b/public/modstagram-back/controllers/application/payment/paymentControllerWeb.js deleted file mode 100644 index d409670..0000000 --- a/public/modstagram-back/controllers/application/payment/paymentControllerWeb.js +++ /dev/null @@ -1,935 +0,0 @@ -/* eslint-disable eqeqeq */ - -const TypeAndPriceModel = require('../../../models/TypeAndPriceModel'); -const ProjectModel = require('../../../models/ProjectModel'); -const PaymentModel = require('../../../models/PaymentModel'); -const jwt = require('jsonwebtoken'); -const RequestModel = require('../../../models/RequestModel'); -const NotificationModel = require('../../../models/NotificationModel'); -const UserModel = require('../../../models/UserModel'); -const AdvertisingTypeModel = require('../../../models/AdvertisingTypeModel'); -const AdvertisingModel = require('../../../models/AdvertisingModel'); -const OfferTypeModel = require('../../../models/OfferTypeModel'); -const OfferModel = require('../../../models/OfferModel'); -const { default: axios } = require('axios'); - -const apiKey = "c7c41e8a-918f-4741-bcd5-58f3bc51db73"; // اصلاح نام متغیر محیطی - -// Function to get price based on item name from database -const getPriceFromDatabase = async (itemName) => { - const item = await TypeAndPriceModel.findOne({ name: itemName }); - if (!item) { - throw new Error(`Item "${itemName}" not found in TypeAndPriceModel`); - } - return item.price; -}; - -const getAdvertisingPriceFromDatabase = async (itemName) => { - const item = await AdvertisingTypeModel.findOne({ name: itemName }); - if (!item) { - throw new Error(`Item "${itemName}" not found in AdvertisingTypeModel`); - } - return item.price; -}; - -const getOfferPriceFromDatabase = async (offerType) => { - const item = await OfferTypeModel.findOne({ name: offerType }); - if (!item) { - throw new Error(`Offer type "${offerType}" not found in OfferTypeModel`); - } - return item.price; -}; -// Controller function for initiating payment -const initiatePaymentWeb = async (req, res) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - // eslint-disable-next-line no-unused-vars - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - const itemName = req.body.item_name // Get item name from request body - const price = await getPriceFromDatabase(itemName) // Get price from database - const projectId = req.body.projectId // Get project ID from request body - // Save project ID for later use in callback URL - req.session.projectId = projectId - const item = await TypeAndPriceModel.findOne({ name: itemName }) - const user = await UserModel.findById(userId) - - if (item.name === 'free' && item.price === 0) { - if (user.daily_free_request > 0) { - user.daily_free_request -= 1 - await user.save() - const project = await ProjectModel.findById(projectId) - if (!project) { - res.status(404).send('Project not found') - return - } - project.payment_status = 'done' // Set project status to 'done' - project.status = 'paid' // Set project status to 'done' - await project.save() - res.status(200).json({ message: 'پروژه رایگان با موفقیت ایجاد شد', projectId, type: 'free' }) - } else { - res.status(403).json({ message: 'شما قبلاً از درخواست رایگان امروز استفاده کرده‌اید.' }) - } - } else { - const response = await axios.post('https://www.zarinpal.com/pg/rest/WebGate/PaymentRequest.json', { - MerchantID: apiKey, - Amount: Number(price), - Description: `پرداخت برای سفارش شماره ${projectId}`, - CallbackURL: `${process.env.APP_URL}/projects/payment-web?projectId=${projectId}&itemName=${itemName}&userId=${userId}` // Assuming your backend URL for handling payment callback - }) - - const data = response.data - if (data.Status === 100) { - // Payment request was successful - const authority = data.Authority // The payment authority (شناسه پرداخت) - res.status(200).json({ authority }) - } else { - // Payment request failed - console.error('Error occurred while initiating payment:', data) - res.status(500).json({ error: 'Error occurred while initiating payment' }) - } - } - } catch (error) { - // Error occurred while getting price from database or sending the request - console.error('Error occurred:', error) - res.status(500).json({ error: 'Internal server error' }) - } -} -// Controller function for handling payment callback from ZarinPal -const handlePaymentCallbackWeb = async (req, res) => { - try { - // console.log(req.query) - // Extract payment status and authority from ZarinPal callback - const status = req.query.Status - const authority = req.query.Authority - const projectId = req.query.projectId // Get project ID from session - const itemName = req.query.itemName // Get project ID from session - const userId = req.query.userId // Get project ID from session - // Clear project ID from session - // Query ZarinPal API to verify payment status - const verificationUrl = 'https://www.zarinpal.com/pg/rest/WebGate/PaymentVerification.json' - const price = await getPriceFromDatabase(itemName) // Get price from database - const verificationResponse = await axios.post(verificationUrl, { - MerchantID: apiKey, - Authority: authority, - Amount: Number(price) - }) - - const verificationData = verificationResponse.data - if (verificationData.Status === 100) { - const payment = new PaymentModel({ - amount: Number(price), - status: 'successful', - authority, - user_id: userId, // فرضاً شما از نوع میان‌افزارهای مدیریت کاربر استفاده می‌کنید و اطلاعات کاربر را از طریق `req.user` در دسترس دارید - project_id: projectId, - type: 'create', - installment_step: null - // دیگر اطلاعات مورد نیاز برای ثبت پرداخت - }) - await payment.save() - - // Payment verification is successful - // Now, update project status to 'done' or desired status - const project = await ProjectModel.findById(projectId) - if (!project) { - res.status(404).send('Project not found') - return - } - project.payment_status = 'done' // Set project status to 'done' - project.status = 'paid' // Set project status to 'done' - await project.save() - - // Send event based on payment status - if ('eventEmitter' in req.app) { - if (status === 'OK') { - // Payment is successful - // Emit an event to be listened to in the frontend - // Example event name: 'paymentSuccess' - // Example data: { message: 'Payment successful' } - // You can customize the event name and data as needed - req.app.get('eventEmitter').emit('paymentSuccess', { message: 'Payment successful' }) - } else { - // Payment is canceled or failed - // Emit an event to be listened to in the frontend - // Example event name: 'paymentFailed' - // Example data: { message: 'Payment canceled or failed' } - // You can customize the event name and data as needed - req.app.get('eventEmitter').emit('paymentFailed', { message: 'Payment canceled or failed' }) - } - } else { - console.error('Error: eventEmitter is not defined or not properly configured.') - } - - // Redirect to the callback URL with the project ID - res.redirect(`https://modstagram.com/projects/payment/success?projectId=${projectId}&price=${price}&type=create`) - } else { - // Payment verification failed - const payment = new PaymentModel({ - amount: Number(price), - status: 'failed', - authority, - user_id: userId, // فرضاً شما از نوع میان‌افزارهای مدیریت کاربر استفاده می‌کنید و اطلاعات کاربر را از طریق `req.user` در دسترس دارید - project_id: projectId, - type: 'create' - // دیگر اطلاعات مورد نیاز برای ثبت پرداخت - }) - await payment.save() - res.redirect(`https://modstagram.com/projects/payment/failed?projectId=${projectId}&price=${price}&type=create`) - } - } catch (error) { - // Error occurred while verifying payment - console.error('Error occurred:', error) - res.status(500).send('Internal server error') - } -} - -const paymentRequestAcceptWeb = async (req, res) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - const projectId = req.body.projectId - // Find the project - const project = await ProjectModel.findById(projectId) - if (!project) { - return res.status(404).json({ error: 'Project not found' }) - } - if (project.status == 'ongoing') { - return res.status(400).json({ message: 'برای این پروژه از قبل کاربر انتخاب شده' }) - } - // eslint-disable-next-line eqeqeq - if (userId != project.creator_id.toString()) { - return res.status(422).json({ - error: true, - message: 'شما نمیتوانید این پروژه را ویرایش کنید' - }) - } - - // Get the final price from the request model - const requestId = req.body.requestId - const request = await RequestModel.findById(requestId) - if (!request) { - return res.status(404).json({ error: 'Request not found' }) - } - request.status = 'accepted' - await request.save() - - project.selected_user = request.user - project.status = 'ongoing' - project.final_price = request.price - project.final_time = request.time - await project.save() - // Send notification to selected user - const notification = new NotificationModel({ - user_id: request.user, - project_post_id: projectId, - type: 'request_accepted', - title: 'انتخاب پیشنهاد', - description: `کارفرما پیشنهاد کاری شما برای پروژه ${project.title} را پذیرفت.` - }) - await notification.save() - - // Sms - const userReciver = await UserModel.findById(request.user) - const data = JSON.stringify({ - mobile: userReciver?.mobile, - templateId: '302876', - parameters: [ - { name: 'USER', value: userReciver?.first_name + ' ' + userReciver?.last_name }, - { name: 'PROJECT', value: project?.title } - ] - }) - const config = { - method: 'post', - url: 'https://api.sms.ir/v1/send/verify', - headers: { - 'Content-Type': 'application/json', - Accept: 'text/plain', - 'x-api-key': '2JKxGbTzE64t0YTkjip6RYHnm9mq1haMlidF8WWwQunwubHFVW6iaMmfFQbMXEDt' - }, - data - } - axios(config) - .then(function (response) { - }) - .catch(function (error) { - console.log(error) - }) - res.status(200).json({ - message: 'درخواست با موفقیت تایید شد' - }) - } catch (error) { - // Error occurred while getting price from database or sending the request - console.error('Error occurred:', error) - res.status(500).json({ error: 'Internal server error' }) - } -} -const initiateAdvertisingPaymentWeb = async (req, res) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - // eslint-disable-next-line no-unused-vars - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - const itemName = req.body.item_name // Get item name from request body - const price = await getAdvertisingPriceFromDatabase(itemName) // Get price from database - const advertisingId = req.body.advertisingId // Get project ID from request body - const showDiscount = req.body.showDiscount - - // Save project ID for later use in callback URL - req.session.advertisingId = advertisingId - const item = await AdvertisingTypeModel.findOne({ name: itemName }) - const user = await UserModel.findById(userId) - - if (item.name === 'free' && item.price === 0) { - if (user.daily_free_request > 0) { - user.daily_free_request -= 1 - await user.save() - const project = await AdvertisingModel.findById(advertisingId) - if (!project) { - res.status(404).send('Advertising not found') - return - } - project.payment_status = 'done' // Set project status to 'done' - project.status = 'paid' // Set project status to 'done' - await project.save() - res.status(200).json({ message: 'بیلبورد رایگان با موفقیت ایجاد شد', advertisingId, type: 'free' }) - } else { - res.status(403).json({ message: 'شما قبلاً از بیلبورد رایگان این ماه استفاده کرده‌اید.' }) - } - } else { - const response = await axios.post('https://www.zarinpal.com/pg/rest/WebGate/PaymentRequest.json', { - MerchantID: process.env.ZARINPAL_MERCHANT_ID, - Amount: showDiscount === true || showDiscount === 'true' ? Number(price + 20000) : Number(price), - Description: `پرداخت برای سفارش شماره ${advertisingId}`, - CallbackURL: `${process.env.APP_SITE_CallBack}/advertising/payment-web?advertisingId=${advertisingId}&itemName=${itemName}&userId=${userId}&showDiscount=${showDiscount}` // Assuming your backend URL for handling payment callback - }) - const data = response.data - if (data.Status === 100) { - // Payment request was successful - const authority = data.Authority // The payment authority (شناسه پرداخت) - res.status(200).json({ authority }) - } else { - // Payment request failed - console.error('Error occurred while initiating payment:', data) - res.status(500).json({ error: 'Error occurred while initiating payment' }) - } - } - } catch (error) { - // Error occurred while getting price from database or sending the request - console.error('Error occurred:', error) - res.status(500).json({ error: 'Internal server error' }) - } -} -const handleAdvertisingPaymentCallbackWeb = async (req, res) => { - try { - // console.log(req.query) - // Extract payment status and authority from ZarinPal callback - const status = req.query.Status - const authority = req.query.Authority - const advertisingId = req.query.advertisingId // Get project ID from session - const itemName = req.query.itemName // Get project ID from session - const userId = req.query.userId // Get project ID from session - const showDiscount = req.query.showDiscount // Get project ID from session - // Clear project ID from session - // Query ZarinPal API to verify payment status - - const verificationUrl = 'https://www.zarinpal.com/pg/rest/WebGate/PaymentVerification.json' - const price = await getAdvertisingPriceFromDatabase(itemName) // Get price from database - const verificationResponse = await axios.post(verificationUrl, { - MerchantID: apiKey, - Authority: authority, - Amount: showDiscount === true || showDiscount === 'true' ? Number(price + 20000) : Number(price) - }) - - const verificationData = verificationResponse.data - if (verificationData.Status === 100) { - const payment = new PaymentModel({ - amount: showDiscount === true || showDiscount === 'true' ? Number(price + 20000) : Number(price), - status: 'successful', - authority, - user_id: userId, // فرضاً شما از نوع میان‌افزارهای مدیریت کاربر استفاده می‌کنید و اطلاعات کاربر را از طریق `req.user` در دسترس دارید - advertising_id: advertisingId, - type: 'advertising', - installment_step: null - // دیگر اطلاعات مورد نیاز برای ثبت پرداخت - }) - await payment.save() - - // Payment verification is successful - // Now, update project status to 'done' or desired status - const advertising = await AdvertisingModel.findById(advertisingId) - if (!advertising) { - res.status(404).send('Advertising not found') - return - } - advertising.payment_status = 'done' // Set advertising status to 'done' - advertising.status = 'paid' // Set advertising status to 'done' - await advertising.save() - - // Send event based on payment status - if ('eventEmitter' in req.app) { - if (status === 'OK') { - // Payment is successful - // Emit an event to be listened to in the frontend - // Example event name: 'paymentSuccess' - // Example data: { message: 'Payment successful' } - // You can customize the event name and data as needed - req.app.get('eventEmitter').emit('paymentSuccess', { message: 'Payment successful' }) - } else { - // Payment is canceled or failed - // Emit an event to be listened to in the frontend - // Example event name: 'paymentFailed' - // Example data: { message: 'Payment canceled or failed' } - // You can customize the event name and data as needed - req.app.get('eventEmitter').emit('paymentFailed', { message: 'Payment canceled or failed' }) - } - } else { - console.error('Error: eventEmitter is not defined or not properly configured.') - } - - // Redirect to the callback URL with the advertising ID - res.redirect(`https://modstagram.com/billboards/payment/success?projectId=${advertisingId}&price=${showDiscount === true || showDiscount === 'true' ? Number(price + 20000) : Number(price)}&type=advertising&showDiscount=${showDiscount}`) - } else { - // Payment verification failed - const payment = new PaymentModel({ - amount: showDiscount ? Number(price + 20000) : Number(price), - status: 'failed', - authority, - user_id: userId, // فرضاً شما از نوع میان‌افزارهای مدیریت کاربر استفاده می‌کنید و اطلاعات کاربر را از طریق `req.user` در دسترس دارید - advertising_id: advertisingId, - type: 'advertising' - // دیگر اطلاعات مورد نیاز برای ثبت پرداخت - }) - console.log('ss') - - await payment.save() - res.redirect(`https://modstagram.com/billboards/payment/failed?projectId=${advertisingId}&price=${showDiscount === true || showDiscount === 'true' ? Number(price + 20000) : Number(price)}&type=advertising&showDiscount=${showDiscount}`) - } - } catch (error) { - // Error occurred while verifying payment - console.error('Error occurred:', error) - res.status(500).send('Internal server error') - } -} - -const republishAdvertisingPaymentWeb = async (req, res) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - // eslint-disable-next-line no-unused-vars - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - const itemName = req.body.item_name // Get item name from request body - const price = await getAdvertisingPriceFromDatabase(itemName) // Get price from database - const advertisingId = req.body.advertisingId // Get project ID from request body - const showDiscount = req.body.showDiscount - // Save project ID for later use in callback URL - req.session.advertisingId = advertisingId - const item = await AdvertisingTypeModel.findOne({ name: itemName }) - const user = await UserModel.findById(userId) - - if (item.name === 'free' && item.price === 0) { - if (user.daily_free_request > 0) { - user.daily_free_request -= 1 - await user.save() - const project = await AdvertisingModel.findById(advertisingId) - if (!project) { - res.status(404).send('Project not found') - return - } - project.payment_status = 'done' // Set project status to 'done' - project.status = 'paid' // Set project status to 'done' - await project.save() - res.status(200).json({ message: 'پروژه رایگان با موفقیت ایجاد شد', advertisingId, type: 'free' }) - } else { - res.status(403).json({ message: 'شما قبلاً از درخواست رایگان امروز استفاده کرده‌اید.' }) - } - } else { - const response = await axios.post('https://www.zarinpal.com/pg/rest/WebGate/PaymentRequest.json', { - MerchantID: apiKey, - Amount: showDiscount === true || showDiscount === 'true' ? Number(((price + 20000) * 70) / 100) : Number(((price) * 70) / 100), - Description: `پرداخت برای سفارش شماره ${advertisingId}`, - CallbackURL: `${process.env.APP_URL}/advertising/republish-verify-payment-web?advertisingId=${advertisingId}&itemName=${itemName}&userId=${userId}&showDiscount=${showDiscount}` // Assuming your backend URL for handling payment callback - }) - const data = response.data - if (data.Status === 100) { - // Payment request was successful - const authority = data.Authority // The payment authority (شناسه پرداخت) - res.status(200).json({ authority }) - } else { - // Payment request failed - console.error('Error occurred while initiating payment:', data) - res.status(500).json({ error: 'Error occurred while initiating payment' }) - } - } - } catch (error) { - // Error occurred while getting price from database or sending the request - console.error('Error occurred:', error) - res.status(500).json({ error: 'Internal server error' }) - } -} -const handleAdvertisingRepublishPaymentCallbackWeb = async (req, res) => { - try { - // console.log(req.query) - // Extract payment status and authority from ZarinPal callback - const status = req.query.Status - const authority = req.query.Authority - const advertisingId = req.query.advertisingId // Get project ID from session - const itemName = req.query.itemName // Get project ID from session - const userId = req.query.userId // Get project ID from session - const showDiscount = req.query.showDiscount // Get project ID from session - // Clear project ID from session - // Query ZarinPal API to verify payment status - const verificationUrl = 'https://www.zarinpal.com/pg/rest/WebGate/PaymentVerification.json' - const price = await getAdvertisingPriceFromDatabase(itemName) // Get price from database - const verificationResponse = await axios.post(verificationUrl, { - MerchantID: apiKey, - Authority: authority, - Amount: showDiscount === true || showDiscount === 'true' ? Number(((price + 20000) * 70) / 100) : Number(((price) * 70) / 100) - }) - - const verificationData = verificationResponse.data - if (verificationData.Status === 100) { - const payment = new PaymentModel({ - amount: showDiscount === true || showDiscount === 'true' ? Number(((price + 20000) * 70) / 100) : Number(((price) * 70) / 100), - status: 'successful', - authority, - user_id: userId, // فرضاً شما از نوع میان‌افزارهای مدیریت کاربر استفاده می‌کنید و اطلاعات کاربر را از طریق `req.user` در دسترس دارید - advertising_id: advertisingId, - type: 'advertising', - installment_step: null - // دیگر اطلاعات مورد نیاز برای ثبت پرداخت - }) - await payment.save() - - // Payment verification is successful - // Now, update project status to 'done' or desired status - const advertising = await AdvertisingModel.findById(advertisingId) - if (!advertising) { - res.status(404).send('Advertising not found') - return - } - advertising.payment_status = 'done' // Set advertising status to 'done' - advertising.status = 'accepted' // Set advertising status to 'done' - advertising.acceptedAt = new Date() - await advertising.save() - - // Send event based on payment status - if ('eventEmitter' in req.app) { - if (status === 'OK') { - // Payment is successful - // Emit an event to be listened to in the frontend - // Example event name: 'paymentSuccess' - // Example data: { message: 'Payment successful' } - // You can customize the event name and data as needed - req.app.get('eventEmitter').emit('paymentSuccess', { message: 'Payment successful' }) - } else { - // Payment is canceled or failed - // Emit an event to be listened to in the frontend - // Example event name: 'paymentFailed' - // Example data: { message: 'Payment canceled or failed' } - // You can customize the event name and data as needed - req.app.get('eventEmitter').emit('paymentFailed', { message: 'Payment canceled or failed' }) - } - } else { - console.error('Error: eventEmitter is not defined or not properly configured.') - } - - // Redirect to the callback URL with the advertising ID - res.redirect(`https://modstagram.com/billboards/payment/success?projectId=${advertisingId}&price=${showDiscount === true || showDiscount === 'true' ? Number(((price + 20000) * 70) / 100) : Number(((price) * 70) / 100)}&type=advertising-republish&showDiscount=${showDiscount}`) - } else { - // Payment verification failed - const payment = new PaymentModel({ - amount: showDiscount === true || showDiscount === 'true' ? Number(((price + 20000) * 70) / 100) : Number(((price) * 70) / 100), - status: 'failed', - authority, - user_id: userId, // فرضاً شما از نوع میان‌افزارهای مدیریت کاربر استفاده می‌کنید و اطلاعات کاربر را از طریق `req.user` در دسترس دارید - advertising_id: advertisingId, - type: 'advertising' - // دیگر اطلاعات مورد نیاز برای ثبت پرداخت - }) - await payment.save() - res.redirect(`https://modstagram.com/billboards/payment/failed?projectId=${advertisingId}&price=${showDiscount === true || showDiscount === 'true' ? Number(((price + 20000) * 70) / 100) : Number(((price) * 70) / 100)}&type=advertising-republish&showDiscount=${showDiscount}`) - } - } catch (error) { - // Error occurred while verifying payment - console.error('Error occurred:', error) - res.status(500).send('Internal server error') - } -} -// const initiateOfferPaymentWeb = async (req, res) => { -// try { -// const token = req.header('Authorization')?.split(' ')[1]; -// if (!token) { -// return res.status(401).json({ error: 'Access Denied: No token provided' }); -// } - -// let decodedToken; -// try { -// decodedToken = jwt.verify(token, process.env.APP_SECRET); -// } catch (err) { -// return res.status(401).json({ error: 'Invalid token' }); -// } - -// const userId = decodedToken.id; -// const { receiverId, offerType } = req.body; - -// // اعتبارسنجی ورودی‌ها -// if (!receiverId || !offerType) { -// return res.status(400).json({ error: 'receiverId and offerType are required' }); -// } - -// const user = await UserModel.findById(userId); -// if (!user) { -// return res.status(404).json({ error: 'User not found' }); -// } - -// const receiverUser = await UserModel.findById(receiverId); -// if (!receiverUser) { -// return res.status(404).json({ error: 'Receiver not found' }); -// } - -// let price; -// if (user.monthly_free_offer > 0 && offerType === 'free') { -// price = 0; -// user.monthly_free_offer -= 1; -// await user.save(); -// } else { -// price = await getOfferPriceFromDatabase(offerType); -// } - -// if (price === 0) { -// const offer = new OfferModel({ -// sender: userId, -// receiver: receiverId, -// transaction_id: null, -// }); -// await offer.save(); -// return res.status(200).json({ message: 'آفر رایگان با موفقیت ثبت شد', offerId: offer._id, type: 'free' }); -// } -// console.log('🔹 Initiating ZarinPal Payment'); -// console.log('MerchantID:', apiKey); -// console.log('Amount:', Number(price * 10)); -// console.log('Description:', `پرداخت برای ارسال آفر به ${receiverUser.first_name}`); -// console.log('CallbackURL:', `${process.env.APP_URL}/offers/payment-web?receiverId=${receiverId}&offerType=${offerType}&userId=${userId}`); - -// const ZARINPAL_URL = 'https://api.zarinpal.com/pg/v4/payment/request.json'; -// // -// const response = await axios.post(ZARINPAL_URL, { -// merchant_id: process.env.ZARINPAL_MERCHANT_ID, // ❌ MerchantID نیست! -// amount: Number(price), // ✅ به ریال -// description: `پرداخت برای ارسال آفر به ${receiverUser.first_name}`, -// callback_url: `${process.env.APP_SITE_CallBack}/offer/payment-web?receiverId=${receiverId}&offerType=${offerType}&userId=${userId}`, -// }, { headers: { 'Content-Type': 'application/json' } }); - -// const result = response.data.data; // ✅ data.data - -// if (result.code === 100) { // ✅ code === 100 -// return res.status(200).json({ -// authority: result.authority, -// paymentUrl: `https://www.zarinpal.com/pg/StartPay/${result.authority}` -// }); -// } else { -// console.error('ZarinPal error:', data); -// return res.status(500).json({ error: `Failed to initiate payment: ZarinPal Status ${data.Status}` }); -// } -// } catch (error) { -// console.error('❌ Error in initiateOfferPaymentWeb:', error.message, error.stack); -// return res.status(500).json({ error: error.message || 'Internal server error' }); -// } -// } -const initiateOfferPaymentWeb = async (req, res) => { - try { - const token = req.header('Authorization')?.split(' ')[1]; - if (!token) return res.status(401).json({ error: 'No token' }); - - const decoded = jwt.verify(token, process.env.APP_SECRET); - const userId = decoded.id; - - const { receiverId, offerType } = req.body; - if (!receiverId || !offerType) - return res.status(400).json({ error: 'Invalid data' }); - - const user = await UserModel.findById(userId); - const receiver = await UserModel.findById(receiverId); - if (!user || !receiver) - return res.status(404).json({ error: 'User not found' }); - - let price = await getOfferPriceFromDatabase(offerType); // ✅ ریال - - // 🎁 free offer - if (offerType === 'free' && user.monthly_free_offer > 0) { - const offer = await OfferModel.create({ - sender: userId, - receiver: receiverId, - transaction_id: null, - }); - - user.monthly_free_offer -= 1; - await user.save(); - - return res.json({ - type: 'free', - offerId: offer._id, - }); - } - - const amount = Number(price) * 10; // ✅ ریال – بدون ×10 - const callbackUrl = `https://api.modstagram.com/api/v1/offers/payment-web?receiverId=${receiverId}&offerType=${offerType}&userId=${userId}`; - - const zarinpalRes = await axios.post( - 'https://api.zarinpal.com/pg/v4/payment/request.json', - { - merchant_id:"c7c41e8a-918f-4741-bcd5-58f3bc51db73", - amount, - description: `ارسال آفر به ${receiver.first_name}`, - callback_url: callbackUrl - - // callback_url: `${process.env.APP_SITE_CallBack}/offers/payment-web?receiverId=${receiverId}&offerType=${offerType}&userId=${userId}`, - }, - { headers: { 'Content-Type': 'application/json' } } - ); - - // console.log(`${process.env.APP_SITE_CallBack}/offers/payment-web?receiverId=${receiverId}&offerType=${offerType}&userId=${userId}`); - - - const result = zarinpalRes.data.data; - console.log(result); - console.log("ZarinPal Callback URL:", callbackUrl); - console.log("Initiate payment request:", { userId, receiverId, offerType, price }); - - - - - - if (result.code === 100) { - return res.json({ - authority: result.authority, - paymentUrl: `https://www.zarinpal.com/pg/StartPay/${result.authority}`, - }); - } - - return res.status(500).json({ error: 'ZarinPal error' }); - } catch (err) { - console.error(err); - return res.status(500).json({ error: 'Server error' }); - } -}; - - - -// try { -// const { receiverId, offerType, userId, Authority, Status } = req.query; - -// // ❗ چک اولیه -// if (Status !== 'OK' || !Authority) { -// return res.status(400).json({ -// success: false, -// message: 'پرداخت ناموفق یا لغو شد' -// }); -// } - -// if (!receiverId || !offerType || !userId) { -// return res.status(400).json({ -// success: false, -// message: 'پارامترهای ناقص' -// }); -// } - -// // پیدا کردن کاربرها -// const user = await UserModel.findById(userId); -// const receiverUser = await UserModel.findById(receiverId); - -// if (!user || !receiverUser) { -// return res.status(404).json({ -// success: false, -// message: 'کاربر یافت نشد' -// }); -// } - -// const price = await getOfferPriceFromDatabase(offerType); - -// const verifyResponse = await axios.post( -// 'https://api.zarinpal.com/pg/v4/payment/verify.json', -// { -// merchant_id: process.env.ZARINPAL_MERCHANT_ID, // یا MERCHENT_CODE -// authority: Authority, -// amount: price, // به ریال -// }, -// { headers: { 'Content-Type': 'application/json' } } -// ); - -// const verifyData = verifyResponse.data.data; - -// if (verifyData.code === 100) { -// // ✅ پرداخت موفق -// const payment = new PaymentModel({ -// amount: Number(price), -// status: 'successful', -// authority: Authority, -// ref_id: verifyData.ref_id, -// user_id: userId, -// type: 'offer', -// }); -// await payment.save(); - -// const offer = new OfferModel({ -// sender: userId, -// receiver: receiverId, -// transaction_id: payment._id, -// }); -// await offer.save(); - -// // نوتیفیکیشن و SMS (همون کد قبلی) -// const notification = new NotificationModel({ -// user_id: receiverId, -// project_post_id: offer._id, -// type: 'new_offer', -// title: 'درخواست همکاری جدید', -// description: `${user.first_name} یک درخواست همکاری برای شما ارسال کرده است`, -// }); -// await notification.save(); - -// const data = JSON.stringify({ -// mobile: receiverUser?.mobile, -// templateId: '569006', -// parameters: [ -// { name: 'FIRSTNAME', value: receiverUser?.first_name }, -// { name: 'LASTNAME', value: receiverUser?.last_name }, -// ], -// }); - -// const config = { -// method: 'post', -// url: 'https://api.sms.ir/v1/send/verify', -// headers: { -// 'Content-Type': 'application/json', -// Accept: 'text/plain', -// 'x-api-key': process.env.SMS_VERIFY_KEY, -// }, -// data, -// }; - -// await axios(config).catch((error) => { -// console.error('SMS error:', error.message); -// }); - -// if ('eventEmitter' in req.app && status === 'OK') { -// req.app.get('eventEmitter').emit('paymentSuccess', { message: 'Payment successful' }); -// } else { -// req.app.get('eventEmitter')?.emit('paymentFailed', { message: 'Payment canceled or failed' }); -// } - -// res.redirect(`https://modstagram.com/offer/payment/success?userId=${userId}`); - -// return res.status(200).json({ -// success: true, -// message: 'پرداخت و آفر با موفقیت ثبت شد', -// ref_id: verifyData.ref_id, -// offerId: offer._id -// }); -// } else { -// // پرداخت ناموفق -// const payment = new PaymentModel({ -// amount: Number(price), -// status: 'failed', -// authority: Authority, -// user_id: userId, -// type: 'offer', -// }); -// await payment.save(); -// res.redirect(`https://modstagram.com/offer/payment/failed?userId=${userId}`); -// return res.status(400).json({ -// success: false, -// message: `خطا در تأیید پرداخت: ${verifyData.code}` -// }); - -// } -// } catch (error) { -// console.error('❌ Callback Error:', error.message); -// return res.status(500).json({ -// success: false, -// message: 'خطای سرور' -// }); -// } -// }; - -const handleOfferPaymentCallback = async (req, res) => { - - res.setHeader('Access-Control-Allow-Origin', '*'); - res.setHeader('Access-Control-Allow-Methods', 'GET,POST,OPTIONS'); - res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); - - console.log('🔔 CALLBACK QUERY:', req.query); - - try { - const { Authority, Status, receiverId, offerType, userId } = req.query; - - if (Status !== 'OK') - return res.redirect(`${process.env.APP_SITE}/offer/payment/failed`); - - const price = await getOfferPriceFromDatabase(offerType); // ریال - const amount = Number(price) * 10; - - const verify = await axios.post( - 'https://api.zarinpal.com/pg/v4/payment/verify.json', - { - merchant_id: "c7c41e8a-918f-4741-bcd5-58f3bc51db73", - authority: Authority, - amount, - }, - { headers: { 'Content-Type': 'application/json' } } - ); - - const data = verify.data.data; - console.log('🔔payment:', data.code); - if (data.code === 100) { - const payment = await PaymentModel.create({ - amount : (amount / 10), - status: 'successful', - authority: Authority, - ref_id: data.ref_id, - user_id: userId, - type: 'offer', - }); - - console.log('🔔payment:', payment); - - const offer = await OfferModel.create({ - sender: userId, - receiver: receiverId, - transaction_id: payment._id, - }); - - return res.redirect( - `${process.env.APP_SITE}/offer/payment/success?offerId=${offer._id}` - ); - } - - return res.redirect(`${process.env.APP_SITE}/offer/payment/failed`); - } catch (err) { - console.error(err); - return res.redirect(`${process.env.APP_SITE}/offer/payment/failed`); - } -}; - - - - - - -module.exports = { - initiatePaymentWeb, - handlePaymentCallbackWeb, - paymentRequestAcceptWeb, - initiateAdvertisingPaymentWeb, - handleAdvertisingPaymentCallbackWeb, - republishAdvertisingPaymentWeb, - handleAdvertisingRepublishPaymentCallbackWeb, - initiateOfferPaymentWeb, - handleOfferPaymentCallback, -}; diff --git a/public/modstagram-back/controllers/application/posts/likeController.js b/public/modstagram-back/controllers/application/posts/likeController.js deleted file mode 100644 index a223cd0..0000000 --- a/public/modstagram-back/controllers/application/posts/likeController.js +++ /dev/null @@ -1,64 +0,0 @@ -/* eslint-disable camelcase */ -const PostModel = require('../../../models/PostModel'); -const jwt = require('jsonwebtoken'); -const UserModel = require('../../../models/UserModel'); -const LikeModel = require('../../../models/LikeModel'); - -const toggleLike = async (req, res, next) => { - try { - const { postId } = req.body; - const token = req.header('Authorization')?.split(' ')[1]; - - if (!token) { - return res.status(401).json({ message: 'توکن ارائه نشده است' }); - } - - let userId; - try { - const decodedToken = jwt.verify(token, process.env.APP_SECRET); - userId = decodedToken.id; - } catch (err) { - return res.status(401).json({ message: 'توکن نامعتبر است' }); - } - - if (!postId) { - return res.status(400).json({ message: 'شناسه پست الزامی است' }); - } - - const post = await PostModel.findById(postId); - if (!post) { - return res.status(404).json({ message: 'پست مورد نظر یافت نشد' }); - } - - const isLiked = post.likes.includes(userId); - if (isLiked) { - // unlike - post.likes.pull(userId); - await post.save(); - await LikeModel.findOneAndDelete({ postId, userId }); - - return res.status(200).json({ - message: 'لایک با موفقیت حذف شد', - is_liked: false, - likesCount: post.likes.length, - }); - } else { - // like - post.likes.push(userId); - await post.save(); - await LikeModel.create({ postId, userId }); - - return res.status(200).json({ - message: 'پست با موفقیت لایک شد', - is_liked: true, - likesCount: post.likes.length, - }); - } - } catch (error) { - console.error('خطا در toggleLike:', error); - res.status(500).json({ message: 'خطا در سرور' }); - next(error); - } -}; - -module.exports = { toggleLike }; \ No newline at end of file diff --git a/public/modstagram-back/controllers/application/posts/postController.js b/public/modstagram-back/controllers/application/posts/postController.js deleted file mode 100644 index 57721b6..0000000 --- a/public/modstagram-back/controllers/application/posts/postController.js +++ /dev/null @@ -1,182 +0,0 @@ -/* eslint-disable camelcase */ -const PostModel = require('../../../models/PostModel'); -const UserModel = require('../../../models/UserModel'); -const { check, validationResult } = require('express-validator'); -const jwt = require('jsonwebtoken'); -const path = require('path'); -const { default: mongoose } = require('mongoose'); - -const createPostValidationRules = () => { - console.log(4); - return [ - check('caption') - .notEmpty().withMessage('توضیحات نمی‌تواند خالی باشد'), - ]; -}; - -const createPost = async (req, res) => { - try { - console.log('DEBUG: createPost called'); - console.log('DEBUG: req.files:', req.files); - console.log('DEBUG: req.body:', req.body); - - const { caption } = req.body; - const files = req.files || []; - const userId = req.user.id; // از میدل‌ویر auth - - if (!files || files.length === 0) { - console.log('DEBUG: No files provided'); - return res.status(400).json({ error: true, message: 'هیچ فایلی آپلود نشده است' }); - } - - if (!caption) { - console.log('DEBUG: No caption provided'); - return res.status(400).json({ error: true, message: 'کپشن الزامی است' }); - } - - const filePaths = files.map((file) => ({ - path: file.path, - type: file.mimetype.startsWith('video/') ? 'video' : 'image', - })); - - console.log('DEBUG: Saving post to MongoDB, filePaths:', filePaths); - const post = new PostModel({ - user_id: userId, - caption, - files: filePaths, - type: files[0].mimetype.startsWith('video/') ? 'video' : 'image', // اضافه کردن فیلد type - createdAt: new Date(), - }); - - await post.save(); - console.log('DEBUG: Post saved:', post._id); - res.status(201).json({ message: 'پست با موفقیت ایجاد شد', postId: post._id }); - } catch (err) { - console.error('DEBUG: createPost error:', err.message); - res.status(500).json({ error: true, message: `خطا در سرور: ${err.message}` }); - } -}; - - - - - - - -const getUserPosts = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const user_id = req.query.user_id - // eslint-disable-next-line no-unused-vars - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userReqId = decodedToken.id - - if (!mongoose.Types.ObjectId.isValid(user_id)) { - return res.status(400).json({ message: 'شناسه کاربر معتبر نیست' }) - } - const user = await UserModel.findById(user_id) - - if (!user) { - return res.status(404).json({ message: 'کاربر مورد نظر یافت نشد' }) - } - const response = {} - const options = { - page: req.query.page || 1, // صفحه پیش‌فرض ۱ - limit: req.query.limit || 10, // حداکثر تعداد موارد برای هر صفحه - sort: { createdAt: -1 } - } - if (user_id.toString() === userReqId.toString()) { - // کاربر خودش است، همه پست‌هایش را بررسی می‌کند - const posts = await PostModel.paginate( - { user_id: user._id, status: { $in: ['pending', 'accept'] } }, // فیلتر - options // گزینه‌های پیجینیشن - ) - response.posts = posts.docs - response.postsCount = posts.totalDocs - response.totalPages = posts.totalPages // ارسال تعداد کل صفحات - response.totalItems = posts.totalDocs - } else { - // دیگران، فقط پست‌هایی که وضعیتشان "accept" است را ببینند - const posts = await PostModel.paginate( - { user_id: user._id, status: 'accept' }, // فیلتر - options // گزینه‌های پیجینیشن - ) - response.posts = posts.docs - response.postsCount = posts.totalDocs - response.totalPages = posts.totalPages // ارسال تعداد کل صفحات - response.totalItems = posts.totalDocs - } - return res.status(200).json({ data: response }) - } catch (error) { - next(error) - } -} -const getUserPostsWeb = async (req, res, next) => { - try { - let userReqId = null - - // دریافت توکن و بررسی معتبر بودنش (اگر وجود داشت) - const authHeader = req.header('Authorization') - if (authHeader) { - const token = authHeader.split(' ')[1] - try { - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - userReqId = decodedToken.id - } catch (err) { - console.warn('توکن نامعتبر است، ادامه بدون احراز هویت') // فقط هشدار، نه ارور - } - } - - const user_id = req.query.user_id - - if (!mongoose.Types.ObjectId.isValid(user_id)) { - return res.status(400).json({ message: 'شناسه کاربر معتبر نیست' }) - } - - const user = await UserModel.findById(user_id) - if (!user) { - return res.status(404).json({ message: 'کاربر مورد نظر یافت نشد' }) - } - - const data = {} - const options = { - page: req.query.page || 1, - limit: req.query.limit || 10, - sort: { createdAt: -1 } - } - - if (userReqId && user_id.toString() === userReqId.toString()) { - // اگر کاربر لاگین کرده و درخواست برای خودش است، همه پست‌هایش را ببیند - const posts = await PostModel.paginate( - { user_id: user._id, status: { $in: ['pending', 'accept'] } }, - options - ) - data.posts = posts.docs - data.postsCount = posts.totalDocs - data.totalPages = posts.totalPages - data.totalItems = posts.totalDocs - } else { - // برای بقیه، فقط پست‌هایی که وضعیتشان "accept" است نمایش داده شود - const posts = await PostModel.paginate( - { user_id: user._id, status: 'accept' }, - options - ) - data.posts = posts.docs - data.postsCount = posts.totalDocs - data.totalPages = posts.totalPages - data.totalItems = posts.totalDocs - } - - return res.status(200).json(data) - } catch (error) { - next(error) - } -} - -module.exports = { - createPostValidationRules, - createPost, - getUserPosts, - getUserPostsWeb -} diff --git a/public/modstagram-back/controllers/application/profile/profileController.js b/public/modstagram-back/controllers/application/profile/profileController.js deleted file mode 100644 index c127f5c..0000000 --- a/public/modstagram-back/controllers/application/profile/profileController.js +++ /dev/null @@ -1,139 +0,0 @@ -const UserModel = require('../../../models/UserModel') -const jwt = require('jsonwebtoken') - - -// GET user by ID from URL -const getUserById = async (req, res, next) => { - try { - const userId = req.params.id; // گرفتن آیدی از پارامتر URL - const service = req.query.services; - - const user = await UserModel.findById(userId); - if (!user) { - return res.status(404).json({ message: "کاربر مورد نظر یافت نشد" }); - } - - let isRegister = true; - // if ( - // !user.user_name || - // !user.first_name || - // !user.last_name || - // !user.user_type || - // !user.national_card_image || - // !user.password || - // !user.national_code - // ) { - // isRegister = false; - // } - - const response = { - _id: user._id, - user_type: user.user_type, - user_level: user.user_level, - first_name: user.first_name, - last_name: user.last_name, - user_name: user.user_name, - show_location: user.show_location, - is_verified: user.is_verified, - user_score: user.user_score, - rate: user.rate, - bio: user.bio, - height: user.height, - weight: user.weight, - size: user.size, - eye_color: user.eye_color, - hair_color: user.hair_color, - profile_image: user.profile_image, - lat: user.lat, - lng: user.lng, - address: user.address, - province: user.province, - city: user.city, - shaba: user.shaba, - national_code: user.national_code, - mobile: user.mobile, - cooperation_abroad: user.cooperation_abroad, - cooperation_type: user.cooperation_type, - conversation_projects: user.conversation_projects, - expertise: user.expertise, - sub_expertise: user.sub_expertise, - isRegister, - user, - services: service === "1" ? user.services : null - }; - - return res.status(200).json({ user: response }); - } catch (error) { - next(error); - } -}; - -const getProfile = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const service = req.query.services - - // eslint-disable-next-line no-unused-vars - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - const user = await UserModel.findById(userId) - let isRegister = true - if (!user.user_name || - !user.first_name || - !user.last_name || - !user.user_type || - !user.national_card_image || - !user.password || - !user.national_code - ) { - isRegister = false - } - if (!user) { - return res.status(404).json({ message: 'کاربر مورد نظر یافت نشد' }) - } - const response = { - _id: user._id, - user_type: user.user_type, - user_level: user.user_level, - first_name: user.first_name, - last_name: user.last_name, - user_name: user.user_name, - show_location: user.show_location, - is_verified: user.is_verified, - is_Register: user.is_Register, - user_score: user.user_score, - rate: user.rate, - bio: user.bio, - height: user.height, - weight: user.weight, - size: user.size, - eye_color: user.eye_color, - hair_color: user.hair_color, - profile_image: user.profile_image, - lat: user.lat, - lng: user.lng, - address: user.address, - province: user.province, - city: user.city, - shaba: user.shaba, - national_code: user.national_code, - mobile: user.mobile, - cooperation_abroad: user.cooperation_abroad, - cooperation_type: user.cooperation_type, - conversation_projects: user.conversation_projects, - expertise: user.expertise, - sub_expertise: user.sub_expertise, - isRegister, - services: service === '1' ? user.services : null - } - return res.status(200).json({ user: response }) - } catch (error) { - next(error) - } -} - -module.exports = { - getProfile, - getUserById -}; diff --git a/public/modstagram-back/controllers/application/projects/createProjectController.js b/public/modstagram-back/controllers/application/projects/createProjectController.js deleted file mode 100644 index c77c4a1..0000000 --- a/public/modstagram-back/controllers/application/projects/createProjectController.js +++ /dev/null @@ -1,220 +0,0 @@ -/* eslint-disable camelcase */ -const { ProvinceModel, CityModel } = require('../../../models/StateCity') -const ProjectModel = require('../../../models/ProjectModel') -const UserModel = require('../../../models/UserModel') -const { check, validationResult } = require('express-validator') -const jwt = require('jsonwebtoken') -const createProjectValidationRules = () => { - return [ - check('title').notEmpty().withMessage('عنوان نمی‌تواند خالی باشد'), - - check('expertise').notEmpty().withMessage('تخصص نمی‌تواند خالی باشد'), - - check('gender') - .isIn(['male', 'female']) - .withMessage('جنسیت باید male یا female باشد'), - - check('age').notEmpty().withMessage('سن نمی‌تواند خالی باشد'), - - check('conversation_projects') - .notEmpty() - .withMessage('پروژه‌های مکالمه نمی‌تواند خالی باشد') - .isBoolean() - .withMessage('مقدار پروژه‌های مکالمه باید یک مقدار boolean باشد'), - - check('province').notEmpty().withMessage('استان نمی‌تواند خالی باشد'), - - check('city').notEmpty().withMessage('شهر نمی‌تواند خالی باشد'), - - check('offer_time') - .notEmpty() - .withMessage('زمان پروژه نمی‌تواند خالی باشد'), - - check('offer_price') - .notEmpty() - .withMessage('قیمت پیشنهادی نمی‌تواند خالی باشد'), - - check('description') - .notEmpty() - .withMessage('توضیحات نمی‌تواند خالی باشد'), - - check('project_type') - .notEmpty() - .withMessage('نوع پروژه نمی‌تواند خالی باشد') - .isIn(['free', 'normal', 'force', 'highlight']) - .withMessage('نوع پروژه باید normal یا force یا highlight باشد') - ] -} - -const createProject = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const user = await UserModel.findById(decodedToken.id) - if (!user) { - return res.status(422).json({ - error: true, - message: 'شما دسترسی به این بخش ندارید' - }) - } - if (user.is_verified !== 'verified') { - return res.status(422).json({ - error: true, - message: 'مدارک شما تایید نشده است' - }) - } - // اعتبارسنجی درخواست - const errors = validationResult(req) - if (!errors.isEmpty()) { - return res.status(422).json({ errors: errors.array() }) - } - const { - title, - expertise, - sub_expertise, - gender, - age, - conversation_projects, - province, - city, - offer_time, - offer_price, - description, - project_type, - public_status, - created_for_user, - number_of_person - } = req.body - if ( - !title || - !expertise || - !age || - conversation_projects === null || - !province || - !city || - !offer_time || - !offer_price || - !description || - !project_type - ) { - return res.status(422).json({ - error: true, - message: 'اطلاعات ارسالی اشتباه است' - }) - } - - const provinceFind = await ProvinceModel.findOne( - { id: province }, - { _id: 0 } - ) - const cityFind = await CityModel.findOne({ id: city }) - // اگر پروژه برای یک کاربر خاص باید ساخته شود - if (public_status && public_status === 'private' && created_for_user) { - const createdUser = await UserModel.findById(created_for_user) - if (!createdUser) { - return res.status(422).json({ - error: true, message: 'کاربر مورد نظر برای ساخت پروژه یافت نشد' - }) - } - // ایجاد شیء پروژه - const projectData = { - title, - expertise, - sub_expertise, - gender, - age, - conversation_projects, - province, - city, - offer_time, - offer_price, - description, - project_type, - creator_id: user._id, // ارتباط با کاربر - public_status, - created_for_user - } - - // ساخت شیء پروژه - const project = new ProjectModel(projectData) - - // ذخیره کردن رکورد در پایگاه داده - await project.save() - - res.status(201).json({ message: 'پروژه با موفقیت ساخته شد', id: project._id } - ) - } else { - if (number_of_person > 1) { - for (let i = 1; i <= number_of_person; i++) { - let currentProjectType - - if (project_type === 'free' && i === 1) { - currentProjectType = 'free' - } else if (project_type === 'highlight' || project_type === 'force') { - currentProjectType = project_type - } else { - currentProjectType = 'normal' - } - - const newProject = new ProjectModel({ - title: `${title}_${i}`, - expertise, - sub_expertise, - gender, - age, - conversation_projects, - province: provinceFind, - city: cityFind, - offer_time, - offer_price, - description, - creator_id: user._id, // ارتباط با کاربر - project_type: currentProjectType, - public_status, - created_for_user - }) - - // ذخیره کردن رکورد در پایگاه داده - await newProject.save() - } - - res.status(201).json({ - message: 'پروژه‌ها با موفقیت ساخته شدند' - }) - } else { - const project = new ProjectModel({ - title, - expertise, - sub_expertise, - gender, - age, - conversation_projects, - province: provinceFind, - city: cityFind, - offer_time, - offer_price, - description, - creator_id: user._id, // ارتباط با کاربر - project_type - }) - - // ذخیره کردن رکورد در پایگاه داده - await project.save() - - res.status(201).json({ - message: 'پروژه با موفقیت ساخته شد', - id: project._id - }) - } - } - } catch (error) { - next(error) - } -} - -module.exports = { - createProjectValidationRules, - createProject -} diff --git a/public/modstagram-back/controllers/application/projects/getProjectController.js b/public/modstagram-back/controllers/application/projects/getProjectController.js deleted file mode 100644 index b302743..0000000 --- a/public/modstagram-back/controllers/application/projects/getProjectController.js +++ /dev/null @@ -1,406 +0,0 @@ -/* eslint-disable camelcase */ -const { default: mongoose } = require('mongoose') -const ProjectModel = require('../../../models/ProjectModel') -const RequestModel = require('../../../models/RequestModel') -const UserModel = require('../../../models/UserModel') -const jwt = require('jsonwebtoken') -const calculateRemainingTime = (milliseconds) => { - const days = Math.floor(milliseconds / (1000 * 60 * 60 * 24)) - const hours = Math.floor((milliseconds % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)) - - return `${days} روز و ${hours} ساعت` -} -const getProjects = async (req, res, next) => { - try { - // eslint-disable-next-line no-unused-vars - const { expertise, page = 1, limit = 10, most_price, most_requests, age, gender } = req.query - // ساخت فیلتر برای استفاده در جستجوی MongoDB - const filter = { - payment_status: 'done', - status: 'accepted', - public_status: 'public', - $or: [ - { isExpired: false }, // پروژه‌هایی که isExpired برابر با false است - { isExpired: { $exists: false } } // پروژه‌هایی که فیلد isExpired وجود ندارد - ] - } - if (expertise) { - filter.expertise = expertise - } - if (age) { - filter.age = age - } - if (gender) { - filter.gender = gender - } - // استفاده از مدل پیجینیت شده برای دریافت نتایج صفحه‌بندی شده - - if (most_price || most_requests) { - // دریافت لیست پروژه‌ها با استفاده از فیلتر و گزینه‌های صفحه‌بندی - const options = { - page: parseInt(page), // تبدیل صفحه به عدد صحیح - limit: parseInt(limit), // تبدیل محدودیت به عدد صحیح - sort: most_price === 'true' ? { offer_price: -1 } : { requested_users: 'desc' } - } - const projects = await ProjectModel.paginate(filter, options) - - const newProj = projects.docs - res.status(200).json({ - projects: newProj, - totalPages: projects.totalPages, // ارسال تعداد کل صفحات - totalItems: projects.totalDocs // ارسال تعداد کل آیتم‌ها - }) - } else { - // دریافت لیست پروژه‌ها با استفاده از فیلتر و گزینه‌های صفحه‌بندی - const options = { - page: parseInt(page), // تبدیل صفحه به عدد صحیح - limit: parseInt(limit), // تبدیل محدودیت به عدد صحیح - sort: { acceptedAt: -1, createdAt: -1 } // مرتب‌سازی بر اساس acceptedAt و سپس createdAt - } - const projects = await ProjectModel.paginate(filter, options) - const newProj = projects.docs - res.status(200).json({ - projects: newProj, - totalPages: projects.totalPages, // ارسال تعداد کل صفحات - totalItems: projects.totalDocs // ارسال تعداد کل آیتم‌ها - }) - } - } catch (error) { - next(error) - } - // try { - // const token = req.header('Authorization').split(' ')[1] - // if (!token) return res.status(401).send('Access Denied') - - // // eslint-disable-next-line no-unused-vars - // const decodedToken = jwt.verify(token, process.env.APP_SECRET) - - // const { expertise, page = 1, limit = 10 } = req.query // افزودن پارامترهای صفحه‌بندی به درخواست - - // // ساخت فیلتر برای استفاده در جستجوی MongoDB - // const filter = { - // payment_status: 'done', - // status: 'accepted', - // public_status: 'public' - // } // افزودن شرط‌های دیگر برای فیلتر - - // if (expertise) { - // filter.expertise = expertise - // } - - // // استفاده از مدل پیجینیت شده برای دریافت نتایج صفحه‌بندی شده - // const options = { - // page: parseInt(page), // تبدیل صفحه به عدد صحیح - // limit: parseInt(limit) // تبدیل محدودیت به عدد صحیح - // } - - // // دریافت لیست پروژه‌ها با استفاده از فیلتر و گزینه‌های صفحه‌بندی - // const projects = await ProjectModel.paginate(filter, options) - - // // تبدیل نتایج به فرمت مورد نیاز - // const projectsWithUserInfo = await Promise.all(projects.docs.map(async project => { - // const creator = await UserModel.findById(project.creator_id).select('first_name last_name user_name user_type is_verified profile_image gender province city rate') - // const projectWithUserInfo = { - // ...project.toJSON(), // تبدیل آبجکت پروژه به JSON - // creator // اضافه کردن اطلاعات کاربر به آبجکت پروژه - // } - - // // محاسبه مدت زمان باقی‌مانده برای هر پروژه - // const currentTime = new Date() - // const projectCreatedAt = new Date(project.createdAt) - // const timeDiff = project.offer_time * 24 * 60 * 60 * 1000 - (currentTime - projectCreatedAt) - // const remainingTime = calculateRemainingTime(timeDiff) - // projectWithUserInfo.remainingTime = remainingTime - - // return projectWithUserInfo - // })) - - // res.status(200).json({ - // projects: projectsWithUserInfo, - // totalPages: projects.totalPages, // ارسال تعداد کل صفحات - // totalItems: projects.totalDocs // ارسال تعداد کل آیتم‌ها - // }) - // } catch (error) { - // next(error) - // } -} -const getUserProjects = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const user_id = req.query.user_id - // eslint-disable-next-line no-unused-vars - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - // const userReqId = decodedToken.id - - if (!mongoose.Types.ObjectId.isValid(user_id)) { - return res.status(400).json({ message: 'شناسه کاربر معتبر نیست' }) - } - const user = await UserModel.findById(user_id) - - if (!user) { - return res.status(404).json({ message: 'کاربر مورد نظر یافت نشد' }) - } - const response = {} - if (user.user_type === 'user') { - const options = { - page: req.query.page || 1, // صفحه پیش‌فرض ۱ - limit: req.query.limit || 10, // حداکثر تعداد موارد برای هر صفحه - sort: { createdAt: -1 } - } - - // پیجینیشن بر روی لیست پروژه‌های کاربر اعمال می‌شود - const projects = await ProjectModel.paginate( - { selected_user: user._id, status: 'done' }, // فیلتر - options // گزینه‌های پیجینیشن - ) - response.projects = projects.docs - response.totalPages = projects.totalPages // ارسال تعداد کل صفحات - response.totalItems = projects.totalDocs // ارسال تعداد کل آیتم‌ها - response.allProjectsCount = await ProjectModel.countDocuments({ selected_user: user._id }) - const completedProjects = await Promise.all([ - ProjectModel.countDocuments({ selected_user: user._id, status: 'done' }) - ]) - response.successfulProjects = completedProjects - } else { - const options = { - page: req.query.page || 1, // صفحه پیش‌فرض ۱ - limit: req.query.limit || 10, // حداکثر تعداد موارد برای هر صفحه - sort: { createdAt: -1 } - } - - // پیجینیشن بر روی لیست پروژه‌های کاربر اعمال می‌شود - const projects = await ProjectModel.paginate( - { creator_id: user._id, status: { $in: ['done', 'accepted'] } }, // فیلتر - options // گزینه‌های پیجینیشن - ) - response.projects = projects.docs - response.totalPages = projects.totalPages // ارسال تعداد کل صفحات - response.totalItems = projects.totalDocs - response.allProjectsCount = await ProjectModel.countDocuments({ creator_id: user._id, payment_status: 'done' }) - // تعداد پروژه‌های موفق را به دست آورید - const successfulProjects = await ProjectModel.countDocuments({ creator_id: user._id, status: 'done' }) - response.successfulProjects = successfulProjects - } - return res.status(200).json({ data: response }) - } catch (error) { - next(error) - } -} -const getUserProjectsWeb = async (req, res, next) => { - try { - const user_id = req.query.user_id - // eslint-disable-next-line no-unused-vars - - if (!mongoose.Types.ObjectId.isValid(user_id)) { - return res.status(400).json({ message: 'شناسه کاربر معتبر نیست' }) - } - const user = await UserModel.findById(user_id) - - if (!user) { - return res.status(404).json({ message: 'کاربر مورد نظر یافت نشد' }) - } - const data = {} - if (user.user_type === 'user') { - const options = { - page: req.query.page || 1, // صفحه پیش‌فرض ۱ - limit: req.query.limit || 10, // حداکثر تعداد موارد برای هر صفحه - sort: { createdAt: -1 } - } - - // پیجینیشن بر روی لیست پروژه‌های کاربر اعمال می‌شود - const projects = await ProjectModel.paginate( - { selected_user: user._id, status: 'done' }, // فیلتر - options // گزینه‌های پیجینیشن - ) - data.projects = projects.docs - data.totalPages = projects.totalPages // ارسال تعداد کل صفحات - data.totalItems = projects.totalDocs // ارسال تعداد کل آیتم‌ها - data.allProjectsCount = await ProjectModel.countDocuments({ selected_user: user._id }) - const completedProjects = await Promise.all([ - ProjectModel.countDocuments({ selected_user: user._id, status: 'done' }) - ]) - data.successfulProjects = completedProjects - } else { - const options = { - page: req.query.page || 1, // صفحه پیش‌فرض ۱ - limit: req.query.limit || 10, // حداکثر تعداد موارد برای هر صفحه - sort: { createdAt: -1 } - } - - // پیجینیشن بر روی لیست پروژه‌های کاربر اعمال می‌شود - const projects = await ProjectModel.paginate( - { creator_id: user._id, status: { $in: ['done', 'accepted'] } }, // فیلتر - options // گزینه‌های پیجینیشن - ) - data.projects = projects.docs - data.totalPages = projects.totalPages // ارسال تعداد کل صفحات - data.totalItems = projects.totalDocs - data.allProjectsCount = await ProjectModel.countDocuments({ creator_id: user._id, payment_status: 'done' }) - // تعداد پروژه‌های موفق را به دست آورید - const successfulProjects = await ProjectModel.countDocuments({ creator_id: user._id, status: 'done' }) - data.successfulProjects = successfulProjects - } - return res.status(200).json(data) - } catch (error) { - next(error) - } -} -const getSingleProjects = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - const projectId = req.params.projectId - const projectRequests = await RequestModel.find({ project: projectId }) - .populate('user', 'price time user_level first_name last_name user_name is_verified user_score rate profile_image') - .sort({ status: 1 }) - .lean() - const modifiedRequests = projectRequests.map(request => ({ - ...request, - time: request.user._id.toString() === userId ? request.time : null, - price: request.user._id.toString() === userId ? request.price : null - })) - const project = await ProjectModel.findById(projectId) - if (!project) { - return res.status(404).json({ message: 'پروژه مورد نظر یافت نشد' }) - } - // محاسبه مبلغ باقیمانده و مجموع مبلغ پرداخت شده - // تابع محاسبه مبلغ پرداخت شده - const getTotalPaidAmount = (installments) => { - let totalPaidAmount = 0 - installments.forEach(installment => { - totalPaidAmount += installment.amount - }) - return totalPaidAmount - } - - // تابع محاسبه مبلغ باقیمانده - const getRemainingAmount = (project) => { - const totalPaidAmount = getTotalPaidAmount(project.installments) - const remainingAmount = project.final_price - totalPaidAmount - return remainingAmount - } - - const totalPaidAmount = getTotalPaidAmount(project.installments) - const remainingAmount = getRemainingAmount(project) - // اطلاعات کاربر سازنده را نیز دریافت کنید و به آبجکت پروژه اضافه کنید - const creator = await UserModel.findById(project.creator_id).select('first_name last_name user_name user_type is_verified profile_image gender province city rate') - - const projectWithUserInfo = { - ...project._doc, - creator // اضافه کردن اطلاعات کاربر به آبجکت پروژه - } - const selectedUser = await UserModel.findById(project.selected_user).select('_id user_name first_name last_name user_type is_verified profile_image expertise sub_expertise province city rate user_level user_score') - projectWithUserInfo.selected_user = selectedUser - // محاسبه مدت زمان باقی‌مانده برای پروژه - const currentTime = new Date() - const projectCreatedAt = new Date(project.createdAt) - const timeDiff = project.offer_time * 24 * 60 * 60 * 1000 - (currentTime - projectCreatedAt) - const remainingTime = calculateRemainingTime(timeDiff) - projectWithUserInfo.remainingTime = remainingTime - let projectDetails = projectWithUserInfo - if ((project.selected_user && project.selected_user.toString()) === userId || project.creator_id.toString() === userId) { - projectDetails = { - ...projectWithUserInfo, - total_paid_amount: totalPaidAmount, - remaining_amount: remainingAmount - } - } else { - projectDetails = - projectWithUserInfo - } - // } - res.status(200).json({ project: projectDetails, projectRequests: modifiedRequests }) - } catch (error) { - next(error) - } -} -const getSingleProjectsWeb = async (req, res, next) => { - try { - let userId = null - let token = req.header('Authorization') - - if (token) { - try { - token = token.split(' ')[1] - if (token) { - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - userId = decodedToken.id - } - } catch (err) { - console.warn('Invalid token:', err.message) - } - } - - const projectId = req.params.projectId - const projectRequests = await RequestModel.find({ project: projectId }) - .populate('user', 'price time user_level first_name last_name user_name is_verified user_score rate profile_image') - .sort({ status: 1 }) - .lean() - - // اگر کاربر لاگین کرده باشد، زمان و قیمت را نشان بده، در غیر این صورت حذف کن - const modifiedRequests = projectRequests.map(request => ({ - ...request, - time: userId && request.user._id.toString() === userId ? request.time : null, - price: userId && request.user._id.toString() === userId ? request.price : null - })) - - const project = await ProjectModel.findById(projectId) - if (!project) { - return res.status(404).json({ message: 'پروژه مورد نظر یافت نشد' }) - } - - // محاسبه مبلغ باقیمانده و مجموع مبلغ پرداخت شده - const getTotalPaidAmount = (installments) => { - return installments.reduce((total, installment) => total + installment.amount, 0) - } - - const getRemainingAmount = (project) => { - return project.final_price - getTotalPaidAmount(project.installments) - } - - const totalPaidAmount = getTotalPaidAmount(project.installments) - const remainingAmount = getRemainingAmount(project) - - // دریافت اطلاعات سازنده پروژه - const creator = await UserModel.findById(project.creator_id).select('first_name last_name user_name user_type is_verified profile_image gender province city rate') - - const projectWithUserInfo = { - ...project._doc, - creator - } - - // دریافت اطلاعات کاربر منتخب در صورت وجود - const selectedUser = await UserModel.findById(project.selected_user).select('_id user_name first_name last_name user_type is_verified profile_image expertise sub_expertise province city rate user_level user_score') - projectWithUserInfo.selected_user = selectedUser - - // محاسبه زمان باقی‌مانده برای پیشنهادات پروژه - const currentTime = new Date() - const projectCreatedAt = new Date(project.createdAt) - const timeDiff = project.offer_time * 24 * 60 * 60 * 1000 - (currentTime - projectCreatedAt) - projectWithUserInfo.remainingTime = calculateRemainingTime(timeDiff) - - let projectDetails = projectWithUserInfo - - // فقط اگر کاربر احراز هویت شده باشد و سازنده یا برنده پروژه باشد، اطلاعات مالی را برگردان - if (userId && (project.selected_user?.toString() === userId || project.creator_id.toString() === userId)) { - projectDetails = { - ...projectWithUserInfo, - total_paid_amount: totalPaidAmount, - remaining_amount: remainingAmount - } - } - - res.status(200).json({ project: projectDetails, projectRequests: modifiedRequests }) - } catch (error) { - next(error) - } -} - -// const projectDetails = await ProjectModel.findById(projectId).populate('requested_users', 'price time user_level first_name last_name user_name is_verified user_score rate profile_image') // جزییات درخواست‌های کاربران - -module.exports = { - getProjects, getSingleProjects, getUserProjects, getUserProjectsWeb, getSingleProjectsWeb -} diff --git a/public/modstagram-back/controllers/application/projects/projectTypesController.js b/public/modstagram-back/controllers/application/projects/projectTypesController.js deleted file mode 100644 index 14d9b05..0000000 --- a/public/modstagram-back/controllers/application/projects/projectTypesController.js +++ /dev/null @@ -1,41 +0,0 @@ -const TypeAndPriceModel = require('../../../models/TypeAndPriceModel') -const jwt = require('jsonwebtoken') -const UserModel = require('../../../models/UserModel') - -const getProjectTypes = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - - const user = await UserModel.findById(userId) - if (!user) { - return res.status(422).json({ - error: true, - message: 'کاربر یافت نشد' - }) - } - // درخواست انواع پروژه از دیتابیس - let projectTypes = await TypeAndPriceModel.find({}, 'name price') - - // بررسی برای مواردی مانند پیدا نشدن انواع پروژه - if (!projectTypes) { - return res.status(404).json({ message: 'انواع پروژه یافت نشد.' }) - } - // اگر کاربر درخواست رایگان روزانه نداشته باشد، نوع پروژه رایگان را حذف کنید - if (user.daily_free_request <= 0) { - projectTypes = projectTypes.filter(projectType => projectType.name !== 'free') - } - // ارسال انواع پروژه به کاربر - res.status(200).json({ projectTypes }) - } catch (error) { - // در صورت بروز خطا، ارسال پیام خطا به کاربر - console.error('Error in getProjectTypes:', error) - res.status(500).json({ message: 'خطا در دریافت انواع پروژه.' }) - } -} - -module.exports = { - getProjectTypes -} diff --git a/public/modstagram-back/controllers/application/projects/requestProjectController.js b/public/modstagram-back/controllers/application/projects/requestProjectController.js deleted file mode 100644 index 2c08a5a..0000000 --- a/public/modstagram-back/controllers/application/projects/requestProjectController.js +++ /dev/null @@ -1,195 +0,0 @@ -/* eslint-disable camelcase */ -const { default: axios } = require('axios') -const NotificationModel = require('../../../models/NotificationModel') -const ProjectModel = require('../../../models/ProjectModel') -const RequestModel = require('../../../models/RequestModel') -const UserModel = require('../../../models/UserModel') -const { check, validationResult } = require('express-validator') -const jwt = require('jsonwebtoken') -const requestProjectValidationRules = () => { - return [ - check('project_id') - .notEmpty().withMessage('آیدی پروژه نمی‌تواند خالی باشد'), - check('request_time') - .notEmpty().withMessage('زمان پروژه نمی‌تواند خالی باشد'), - - check('offer_price') - .notEmpty().withMessage('قیمت پیشنهادی نمی‌تواند خالی باشد') - ] -} - -const requestProject = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const user = await UserModel.findById(decodedToken.id) - if (!user || user.user_type !== 'user') { - return res.status(422).json({ - error: true, message: 'شما دسترسی به این بخش ندارید' - }) - } - if (user.is_verified !== 'verified') { - return res.status(422).json({ - error: true, message: 'مدارک شما تایید نشده است' - }) - } - // اعتبارسنجی درخواست - const errors = validationResult(req) - if (!errors.isEmpty()) { - return res.status(422).json({ errors: errors.array() }) - } - const { request_time, offer_price, project_id } = req.body - if (!project_id || !offer_price || !request_time - ) { - return res.status(422).json({ - error: true, - message: 'اطلاعات ارسالی اشتباه است' - }) - } - // چک کردن برای وجود درخواست قبلی - const existingRequest = await RequestModel.findOne({ project: project_id, user: user._id }) - if (existingRequest) { - return res.status(422).json({ - error: true, - message: 'شما قبلاً برای این پروژه درخواست داده‌اید' - }) - } - // ایجاد یک درخواست جدید - const request = new RequestModel({ - project: project_id, - user: user._id, - time: request_time, - price: offer_price - }) - await request.save() - - // ثبت اعلان برای سازنده پروژه - const project = await ProjectModel.findById(project_id) - const creatorId = project.creator_id - - const notification = new NotificationModel({ - user_id: creatorId, - project_post_id: project_id, - type: 'request', - title: 'پیشنهاد جدید', - description: `کاربر ${user.user_name} یک پیشنهاد جدید برای پروژه شما ارسال کرده است.` - }) - await notification.save() - - const userReciver = await UserModel.findById(project.creator_id) - - const data = JSON.stringify({ - mobile: userReciver?.mobile, - templateId: '876533', - parameters: [ - { name: 'EMPLOYER', value: userReciver?.first_name + ' ' + userReciver?.last_name }, - { name: 'PROJECT', value: project?.title } - ] - }) - - const config = { - method: 'post', - url: 'https://api.sms.ir/v1/send/verify', - headers: { - 'Content-Type': 'application/json', - Accept: 'text/plain', - 'x-api-key': '2JKxGbTzE64t0YTkjip6RYHnm9mq1haMlidF8WWwQunwubHFVW6iaMmfFQbMXEDt' - }, - data - } - axios(config) - .then(function (response) { - }) - .catch(function (error) { - console.log(error) - }) - - // به روز رسانی پروژه با افزودن کاربر به لیست کاربران درخواست دهنده - const updatedProject = await ProjectModel.findOneAndUpdate( - { _id: project_id }, - { $push: { requested_users: user._id } }, - { new: true } - ) - - if (!updatedProject) { - console.error('Error adding requested user: Project not found') - return res.status(404).json({ error: true, message: 'پروژه پیدا نشد' }) - } - - res.status(201).json({ message: 'درخواست با موفقیت شد', id: project_id } - ) - } catch (error) { - next(error) - } -} - -const editRequestProject = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const user = await UserModel.findById(decodedToken.id) - if (!user || user.user_type !== 'user') { - return res.status(422).json({ - error: true, message: 'شما دسترسی به این بخش ندارید' - }) - } - if (user.is_verified !== 'verified') { - return res.status(422).json({ - error: true, message: 'مدارک شما تایید نشده است' - }) - } - // اعتبارسنجی درخواست - const errors = validationResult(req) - if (!errors.isEmpty()) { - return res.status(422).json({ errors: errors.array() }) - } - const { request_time, offer_price, project_id } = req.body - if (!project_id || !offer_price || !request_time - ) { - return res.status(422).json({ - error: true, - message: 'اطلاعات ارسالی اشتباه است' - }) - } - // چک کردن برای وجود درخواست قبلی - const existingRequest = await RequestModel.findOne({ project: project_id, user: user._id }) - if (!existingRequest) { - return res.status(422).json({ - error: true, - message: 'شما قبلاً برای این پروژه درخواست نداده‌اید' - }) - } - // اکنون می‌توانید اطلاعات درخواست را ویرایش کنید - existingRequest.time = request_time - existingRequest.price = offer_price - await existingRequest.save() - - // ثبت اعلان برای سازنده پروژه - const project = await ProjectModel.findById(project_id) - const creatorId = project.creator_id - - const notification = new NotificationModel({ - user_id: creatorId, - project_post_id: project_id, - type: 'request', - title: 'ویرایش پیشنهاد', - description: `کاربر ${user.user_name} پیشنهاد خود را ویرایش کرد.` - }) - await notification.save() - res.status(200).json({ - message: 'درخواست با موفقیت ویرایش شد', - id: project_id - }) - } catch (error) { - next(error) - } -} -const acceptProject = async (req, res, next) => { } -module.exports = { - requestProjectValidationRules, - requestProject, - acceptProject, - editRequestProject -} diff --git a/public/modstagram-back/controllers/application/projects/updateProjectController.js b/public/modstagram-back/controllers/application/projects/updateProjectController.js deleted file mode 100644 index 0caa0c6..0000000 --- a/public/modstagram-back/controllers/application/projects/updateProjectController.js +++ /dev/null @@ -1,381 +0,0 @@ -/* eslint-disable camelcase */ -const ProjectModel = require('../../../models/ProjectModel') -const jwt = require('jsonwebtoken') -const UserModel = require('../../../models/UserModel') -const { check, validationResult } = require('express-validator') -const { ProvinceModel, CityModel } = require('../../../models/StateCity') -const NotificationModel = require('../../../models/NotificationModel') -const CommentModel = require('../../../models/CommentModel') - -const doneProject = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - - const { project_id, comment, rate, user_id } = req.body - if (!project_id || !comment || !rate || !user_id) { - return res.status(400).send({ message: 'All fields are required' }) - } - - const project = await ProjectModel.findOne({ _id: project_id, creator_id: userId }) - if (!project) { - return res.status(403).send({ message: 'Access denied: You are not the creator of this project.' }) - } - - const getTotalPaidAmount = (installments) => { - return installments.reduce((total, installment) => total + installment.amount, 0) - } - - const getRemainingAmount = (project) => { - const totalPaidAmount = getTotalPaidAmount(project.installments) - return project.final_price - totalPaidAmount - } - - const remainingAmount = getRemainingAmount(project) - if (remainingAmount !== 0) { - return res.status(422).send({ message: 'مبلغ کامل پرداخت نشده است' }) - } - - project.status = 'done' - await project.save() - - const newComment = new CommentModel({ - user: user_id, - project: project_id, - creator: userId, - rating: rate, - comment, - comment_for: 'user', - status: 'pending' - }) - await newComment.save() - - const user = await UserModel.findById(user_id) - - // پیدا کردن کامنت‌ها و محاسبه‌ی امتیاز کل - const comments = await CommentModel.find({ user: user_id, comment_for: 'user' }) - const totalRating = Number(comments.reduce((acc, comment) => acc + comment.rating, 0)) - - let userLevel - if (user.expertise === 'مدل') { - if (totalRating <= 50) userLevel = 'تازه وارد' - else if (totalRating <= 100) userLevel = 'استاندارد' - else if (totalRating <= 300) userLevel = 'حرفه‌ای' - else userLevel = 'استاد' - } else if (['زیبایی', 'عکاس'].includes(user.expertise)) { - if (totalRating <= 50) userLevel = 'تازه وارد' - else if (totalRating <= 100) userLevel = 'استاندارد' - else if (totalRating <= 300) userLevel = 'حرفه‌ای' - else userLevel = 'استاد' - } - - user.user_score = totalRating - user.user_level = userLevel - - const totalComments = await CommentModel.countDocuments({ user: user_id, comment_for: 'user' }) - const averageRating = totalRating / totalComments - user.rate = averageRating.toFixed(1) - await user.save() - - const notification = new NotificationModel({ - user_id: user._id, - project_post_id: project_id, - type: 'end_project', - title: 'اتمام پروژه', - description: `کارفرما پروژه ${project?.title} را به وضعیت انجام شده تغییر داد و برای شما نظر ثبت کرد(برای ثبت نظر لمس کنید) -نظر کارفرما : ${comment} - ` - }) - await notification.save() - - res.status(200).json({ message: 'پروژه با موفقیت تغییر یافت شد' }) - } catch (error) { - next(error) - } -} -const doneProjectWeb = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - - const { project_id, comment, rate, user_id } = req.body - if (!project_id || !comment || !rate || !user_id) { - return res.status(400).send({ message: 'All fields are required' }) - } - - const project = await ProjectModel.findOne({ _id: project_id, creator_id: userId }) - if (!project) { - return res.status(403).send({ message: 'Access denied: You are not the creator of this project.' }) - } - - project.status = 'done' - await project.save() - - const newComment = new CommentModel({ - user: user_id, - project: project_id, - creator: userId, - rating: rate, - comment, - comment_for: 'user', - status: 'pending' - }) - await newComment.save() - - const user = await UserModel.findById(user_id) - - // پیدا کردن کامنت‌ها و محاسبه‌ی امتیاز کل - const comments = await CommentModel.find({ user: user_id, comment_for: 'user' }) - const totalRating = Number(comments.reduce((acc, comment) => acc + comment.rating, 0)) - - let userLevel - if (user.expertise === 'مدل') { - if (totalRating <= 50) userLevel = 'تازه وارد' - else if (totalRating <= 100) userLevel = 'استاندارد' - else if (totalRating <= 300) userLevel = 'حرفه‌ای' - else userLevel = 'استاد' - } else if (['زیبایی', 'عکاس'].includes(user.expertise)) { - if (totalRating <= 50) userLevel = 'تازه وارد' - else if (totalRating <= 100) userLevel = 'استاندارد' - else if (totalRating <= 300) userLevel = 'حرفه‌ای' - else userLevel = 'استاد' - } - - user.user_score = totalRating - user.user_level = userLevel - - const totalComments = await CommentModel.countDocuments({ user: user_id, comment_for: 'user' }) - const averageRating = totalRating / totalComments - user.rate = averageRating.toFixed(1) - await user.save() - - const notification = new NotificationModel({ - user_id: user._id, - project_post_id: project_id, - type: 'end_project', - title: 'اتمام پروژه', - description: `کارفرما پروژه ${project?.title} را به وضعیت انجام شده تغییر داد و برای شما نظر ثبت کرد(برای ثبت نظر لمس کنید) -نظر کارفرما : ${comment} - ` - }) - await notification.save() - - res.status(200).json({ message: 'پروژه با موفقیت تغییر یافت شد' }) - } catch (error) { - next(error) - } -} - -const cancleProject = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - - const { project_id, comment, rate, user_id } = req.body - - if (!project_id || !comment || !rate || !user_id) { - return res.status(400).send({ message: 'All fields are required' }) - } - - const project = await ProjectModel.findOne({ _id: project_id, creator_id: userId }) - if (!project) { - return res.status(403).send({ message: 'Access denied: You are not the creator of this project.' }) - } - - project.status = 'cancled' - await project.save() - - const newComment = new CommentModel({ - user: user_id, - project: project_id, - creator: userId, - rating: rate, - comment, - comment_for: 'project', - status: 'pending' - }) - await newComment.save() - - res.status(200).json({ message: 'پروژه با موفقیت تغییر یافت شد' }) - } catch (error) { - next(error) - } -} - -const editProjectValidationRules = () => { - return [ - check('title').notEmpty().withMessage('عنوان نمی‌تواند خالی باشد'), - - check('expertise').notEmpty().withMessage('تخصص نمی‌تواند خالی باشد'), - - check('gender') - .isIn(['male', 'female']) - .withMessage('جنسیت باید male یا female باشد'), - - check('age').notEmpty().withMessage('سن نمی‌تواند خالی باشد'), - - check('conversation_projects') - .notEmpty() - .withMessage('پروژه‌های مکالمه نمی‌تواند خالی باشد') - .isBoolean() - .withMessage('مقدار پروژه‌های مکالمه باید یک مقدار boolean باشد'), - - check('province').notEmpty().withMessage('استان نمی‌تواند خالی باشد'), - - check('city').notEmpty().withMessage('شهر نمی‌تواند خالی باشد'), - - check('offer_time') - .notEmpty() - .withMessage('زمان پروژه نمی‌تواند خالی باشد'), - - check('offer_price') - .notEmpty() - .withMessage('قیمت پیشنهادی نمی‌تواند خالی باشد'), - - check('description') - .notEmpty() - .withMessage('توضیحات نمی‌تواند خالی باشد') - ] -} - -const editProject = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const user = await UserModel.findById(decodedToken.id) - if (!user) { - return res.status(422).json({ - error: true, - message: 'شما دسترسی به این بخش ندارید' - }) - } - if (user.is_verified !== 'verified') { - return res.status(422).json({ - error: true, - message: 'مدارک شما تایید نشده است' - }) - } - - const errors = validationResult(req) - if (!errors.isEmpty()) { - return res.status(422).json({ errors: errors.array() }) - } - - const { - title, - expertise, - sub_expertise, - gender, - age, - conversation_projects, - province, - city, - offer_time, - offer_price, - description, - projectId - } = req.body - - const project = await ProjectModel.findById(projectId) - if (!project) { - return res.status(404).json({ - error: true, - message: 'پروژه مورد نظر یافت نشد' - }) - } - // eslint-disable-next-line eqeqeq - if (user._id.toString() != project.creator_id.toString()) { - return res.status(422).json({ - error: true, - message: 'شما نمیتوانید این پروژه را ویرایش کنید' - }) - } - if (project.status !== 'paid' && project.status !== 'pre_payment') { - return res.status(422).json({ - error: true, - message: 'شما نمیتوانید این پروژه را ویرایش کنید' - }) - } - // اعتبارسنجی اطلاعات ویرایش شده - if ( - !title || - !expertise || - !age || - conversation_projects === null || - !province || - !city || - !offer_time || - !offer_price || - !description - ) { - return res.status(422).json({ - error: true, - message: 'اطلاعات ارسالی اشتباه است' - }) - } - const provinceFind = await ProvinceModel.findOne( - { id: province }, - { _id: 0 } - ) - const cityFind = await CityModel.findOne({ id: city }) - // ویرایش یک نسخه از پروژه - project.title = title - project.expertise = expertise - project.sub_expertise = sub_expertise - project.gender = gender - project.age = age - project.conversation_projects = conversation_projects - project.province = provinceFind - project.city = cityFind - project.offer_time = offer_time - project.offer_price = offer_price - project.description = description - // ذخیره کردن تغییرات در پایگاه داده - await project.save() - res.status(200).json({ - message: 'پروژه با موفقیت ویرایش شد', - id: project._id - }) - } catch (error) { - next(error) - } -} -const setRateProject = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - - const { project_id, comment, rate } = req.body - const project = await ProjectModel.findOne({ _id: project_id, selected_user: userId }) - if (!project) { - return res.status(403).send({ message: 'Access denied: You are not the creator of this project.' }) - } - project.ratings.push({ - project_id, - rating: rate, - comment, - creator_id: userId - }) - await project.save() - - res.status(200).json({ message: 'نظر شما با موفقیت ثبت شد.' }) - } catch (error) { - next(error) - } -} -module.exports = { - doneProject, cancleProject, editProject, editProjectValidationRules, setRateProject, doneProjectWeb -} diff --git a/public/modstagram-back/controllers/application/provincesController.js b/public/modstagram-back/controllers/application/provincesController.js deleted file mode 100644 index 11ab4a3..0000000 --- a/public/modstagram-back/controllers/application/provincesController.js +++ /dev/null @@ -1,15 +0,0 @@ -const { ProvinceModel } = require('../../models/StateCity') - -const getProvinces = async (req, res, next) => { - try { - const provinces = await ProvinceModel.find({}) - res.status(200).json({ - provinces - }) - } catch (err) { - res.status(500).send('Internal Server Error') - } -} -module.exports = { - getProvinces -} diff --git a/public/modstagram-back/controllers/application/register/registerController.js b/public/modstagram-back/controllers/application/register/registerController.js deleted file mode 100644 index fbb2ce6..0000000 --- a/public/modstagram-back/controllers/application/register/registerController.js +++ /dev/null @@ -1,89 +0,0 @@ -const { default: axios } = require('axios') -const UserModel = require('../../../models/UserModel') -const { check, validationResult } = require('express-validator') -// const { Token, VerificationCode } = require('sms-ir') - -const registerValidationRules = () => { - return [ - check('mobile') - .notEmpty().withMessage('شماره موبایل نمی‌تواند خالی باشد') - .isLength({ min: 11, max: 11 }).withMessage('شماره موبایل باید دقیقاً 11 رقم باشد') - .matches(/^09[0-9]{9}$/).withMessage('فرمت شماره موبایل صحیح نیست') - ] -} - -const registerUser = async (req, res, next) => { - try { - const errors = validationResult(req) - if (!errors.isEmpty()) { - return res.status(422).json({ errors: errors.array() }) - } - - const { mobile } = req.body - if (!mobile) { - return res.status(422).json({ - error: true, - message: 'شماره موبایل نمی‌تواند خالی باشد' - }) - } - - const existingUser = await UserModel.findOne({ mobile }) - if (existingUser && existingUser.national_code !== null) { - return res.status(422).json({ error: true, message: 'شماره موبایل تکراری است' }) - } - function generateOTP () { - return Math.floor(100000 + Math.random() * 900000) - } - - const otp = generateOTP() - // eslint-disable-next-line no-unused-vars - const user = await UserModel.findOneAndUpdate( - { mobile }, - { $set: { mobile, otp } }, - { upsert: true, new: true, lean: true } - ) - setTimeout(() => { - UserModel.findOneAndUpdate({ mobile }, { $set: { otp: null } }, { new: true }) - .then(() => {}) - .catch(error => console.error('Error setting OTP to null:', error)) - }, 5 * 60 * 1000) - const data = JSON.stringify({ - mobile, - templateId: '930719', - parameters: [ - { name: 'CODE', value: otp.toString() } - ] - }) - - const config = { - method: 'post', - url: 'https://api.sms.ir/v1/send/verify', - headers: { - 'Content-Type': 'application/json', - Accept: 'text/plain', - 'x-api-key': '2JKxGbTzE64t0YTkjip6RYHnm9mq1haMlidF8WWwQunwubHFVW6iaMmfFQbMXEDt' - }, - data - } - - axios(config) - .then(function (response) { - // console.log(JSON.stringify(response.data)) - }) - .catch(function (error) { - console.log(error) - }) - - res.status(200).json({ - success: true, - message: 'کد تایید ارسال شد' - }) - } catch (error) { - next(error) - } -} - -module.exports = { - registerValidationRules, - registerUser -} diff --git a/public/modstagram-back/controllers/application/register/userFullNameController.js b/public/modstagram-back/controllers/application/register/userFullNameController.js deleted file mode 100644 index 7f5b22e..0000000 --- a/public/modstagram-back/controllers/application/register/userFullNameController.js +++ /dev/null @@ -1,51 +0,0 @@ -/* eslint-disable camelcase */ -const UserModel = require('../../../models/UserModel') -const { check, validationResult } = require('express-validator') -const jwt = require('jsonwebtoken') - -const setUserFullNameValidationRules = () => { - return [ - check('first_name') - .notEmpty().withMessage('نام نمی‌تواند خالی باشد'), - check('last_name') - .notEmpty().withMessage('نام خانوادگی نمی‌تواند خالی باشد') - ] -} - -const setUserFullName = async (req, res, next) => { - try { - const { first_name, last_name } = req.body - - // اعتبارسنجی داده‌های ورودی - const errors = validationResult(req) - if (!errors.isEmpty()) { - return res.status(422).json({ errors: errors.array() }) - } - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const user = await UserModel.findById(decodedToken.id) - if (!user) { - return res.status(404).json({ - error: true, - message: 'کاربری با این شماره موبایل یافت نشد' - }) - } - - // آپدیت نام کاربری به صورت lowercase - user.first_name = first_name.toLowerCase() - user.last_name = last_name.toLowerCase() - await user.save() - - return res.json({ - message: 'نام و نام خانوادگی با موفقیت به‌روزرسانی شد' - }) - } catch (error) { - next(error) - } -} - -module.exports = { - setUserFullName, setUserFullNameValidationRules -} diff --git a/public/modstagram-back/controllers/application/register/userTypeController.js b/public/modstagram-back/controllers/application/register/userTypeController.js deleted file mode 100644 index 50cdaf5..0000000 --- a/public/modstagram-back/controllers/application/register/userTypeController.js +++ /dev/null @@ -1,44 +0,0 @@ -/* eslint-disable camelcase */ -const UserModel = require('../../../models/UserModel') -const jwt = require('jsonwebtoken') - -const setUserType = async (req, res, next) => { - try { - const { user_type } = req.body - if (!user_type || !['user', 'employer'].includes(user_type)) { - return res.status(422).json({ - error: true, - message: 'نوع یوزر معتبر نیست' - }) - } - - // جستجوی کاربر با شماره موبایل ارسالی - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const user = await UserModel.findById(decodedToken.id) - - if (!user) { - return res.status(404).json({ - error: true, - message: 'کاربری با این شماره موبایل یافت نشد' - }) - } - - // آپدیت نوع یوزر - user.user_type = user_type.toLowerCase() - await user.save() - - return res.json({ - message: 'نوع کاربر با موفقیت به‌روزرسانی شد', - id: user._id - }) - } catch (error) { - next(error) - } -} - -module.exports = { - setUserType -} diff --git a/public/modstagram-back/controllers/application/register/usernameController.js b/public/modstagram-back/controllers/application/register/usernameController.js deleted file mode 100644 index 23ead69..0000000 --- a/public/modstagram-back/controllers/application/register/usernameController.js +++ /dev/null @@ -1,95 +0,0 @@ -/* eslint-disable camelcase */ -const UserModel = require('../../../models/UserModel') -const jwt = require('jsonwebtoken') - -const setUserName = async (req, res, next) => { - try { - const { mobile, user_name } = req.body - if (!mobile || !user_name) { - return res.status(422).json({ - error: true, - message: 'اطلاعات ارسالی اشتباه است' - }) - } - - // جستجوی کاربر با شماره موبایل ارسالی - const user = await UserModel.findOne({ mobile }) - if (!user) { - return res.status(404).json({ - error: true, - message: 'کاربری با این شماره موبایل یافت نشد' - }) - } - // بررسی حداقل طول نام کاربری - if (user_name.length < 5) { - return res.status(422).json({ - error: true, - message: 'نام کاربری باید حداقل 5 کاراکتر باشد' - }) - } - // بررسی محدودیت‌های مجاز در نام کاربری - // const usernameRegex = /^[a-zA-Z0-9_]+$/ - // if (!usernameRegex.test(user_name)) { - // return res.status(422).json({ - // error: true, - // message: 'نام کاربری فقط می‌تواند شامل حروف الفبای انگلیسی، اعداد و کاراکتر _ باشد' - // }) - // } - // بررسی تکراری بودن user_name - const existingUser = await UserModel.findOne({ user_name: { $regex: new RegExp('^' + user_name + '$', 'i') } }) - if (existingUser && existingUser._id.toString() !== user._id.toString()) { - return res.status(422).json({ - error: true, - message: 'نام کاربری تکراری است' - }) - } - - // آپدیت نام کاربری به صورت lowercase - user.user_name = user_name.toLowerCase() - await user.save() - - return res.json({ - message: 'نام کاربری با موفقیت به‌روزرسانی شد' - }) - } catch (error) { - next(error) - } -} - -const updateUserName = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - - const { user_name } = req.body - - if (!user_name) { - return res.status(422).json({ - error: true, - message: 'اطلاعات ارسالی اشتباه است' - }) - } - - const user = await UserModel.findByIdAndUpdate(userId, { user_name }, { new: true }) - - if (!user) { - return res.status(404).json({ - error: true, - message: 'کاربری با این شناسه یافت نشد' - }) - } - - return res.json({ - message: 'نام کاربری با موفقیت به‌روزرسانی شد' - }) - } catch (error) { - next(error) - } -} - -module.exports = { - setUserName, updateUserName -} diff --git a/public/modstagram-back/controllers/application/register/verifyController.js b/public/modstagram-back/controllers/application/register/verifyController.js deleted file mode 100644 index 95989cc..0000000 --- a/public/modstagram-back/controllers/application/register/verifyController.js +++ /dev/null @@ -1,47 +0,0 @@ -const UserModel = require('../../../models/UserModel') -const TokenService = require('../../../services/TokenService') -// const jwt = require('jsonwebtoken') - -const verifyUser = async (req, res, next) => { - try { - const { mobile, otp } = req.body - if (!mobile || !otp) { - return res.status(422).json({ - error: true, - message: 'اطلاعات ارسالی اشتباه است' - }) - } - - const user = await UserModel.findOne({ mobile }) - if (!user) { - return res.status(404).json({ - error: true, - message: 'کاربری با این شماره موبایل یافت نشد' - }) - } - const token = TokenService.sign({ id: user._id }) - let step = '' - if (user.user_name === null) { step = 'user_name' } else if - (!user.password) { step = 'password' } else if - (!user.first_name) { step = 'first_name' } else if - (!user.user_type) { step = 'user_type' } else { step = 'profile_image' } - if (user.otp === otp) { - return res.json({ - message: 'کد تایید صحیح بود', - token, - step - }) - } - - return res.status(422).json({ - error: true, - message: 'کد تایید اشتباه است' - }) - } catch (error) { - next(error) - } -} - -module.exports = { - verifyUser -} diff --git a/public/modstagram-back/controllers/application/search-web/searchController.js b/public/modstagram-back/controllers/application/search-web/searchController.js deleted file mode 100644 index 5790ba1..0000000 --- a/public/modstagram-back/controllers/application/search-web/searchController.js +++ /dev/null @@ -1,52 +0,0 @@ -const ProjectModel = require('../../../models/ProjectModel') -const UserModel = require('../../../models/UserModel') -const getSearch = async (req, res, next) => { - try { - const { search, type, page = 1, limit = 10 } = req.query - let result - const selectedFields = '_id user_name first_name last_name user_type is_verified profile_image expertise rate user_level user_score' - let filter - let totalPages - let totalItems - if (search) { - if (!type) { - res.status(422).json({ success: false, message: 'نوع جستجو را مشخص کنید' }) - } else if (type === 'project') { - // جستجو در مدل Project با فیلتر کردن برای user_type === "employer" - - filter = { $or: [{ title: new RegExp(search, 'i'), status: 'accepted' }, { description: new RegExp(search, 'i'), status: 'accepted' }] } - result = await ProjectModel.paginate(filter, { page: parseInt(page), limit: parseInt(limit), sort: { createdAt: -1 } }) - totalPages = result?.totalPages - totalItems = result?.totalDocs - } else if (type === 'user') { - // جستجو در مدل User با فیلتر کردن برای user_type === "user" - filter = { user_type: 'user', $or: [{ user_name: new RegExp(search, 'i') }, { first_name: new RegExp(search, 'i') }, { last_name: new RegExp(search, 'i') }] } - result = await UserModel.paginate(filter, { page: parseInt(page), limit: parseInt(limit), select: selectedFields }) - totalPages = result?.totalPages - totalItems = result?.totalDocs - } else if (type === 'employer') { - // جستجو در مدل User با فیلتر کردن برای user_type === "employer" - filter = { user_type: 'employer', $or: [{ user_name: new RegExp(search, 'i') }, { first_name: new RegExp(search, 'i') }, { last_name: new RegExp(search, 'i') }] } - result = await UserModel.paginate(filter, { page: parseInt(page), limit: parseInt(limit), select: selectedFields }) - totalPages = result?.totalPages - totalItems = result?.totalDocs - } - - res.status(200).json({ - success: true, - result: result?.docs, - type, - totalPages, - totalItems - }) - } else { - res.status(422).json({ success: false, message: 'چیزی تایپ کنید' }) - } - } catch (error) { - next(error) - } -} - -module.exports = { - getSearch -} diff --git a/public/modstagram-back/controllers/application/search/searchController.js b/public/modstagram-back/controllers/application/search/searchController.js deleted file mode 100644 index b099c3f..0000000 --- a/public/modstagram-back/controllers/application/search/searchController.js +++ /dev/null @@ -1,51 +0,0 @@ -const ProjectModel = require('../../../models/ProjectModel') -const UserModel = require('../../../models/UserModel') -const getSearch = async (req, res, next) => { - try { - const { search, type, page = 1, limit = 10 } = req.query - let result - const selectedFields = '_id user_name first_name last_name user_type is_verified profile_image expertise rate user_level user_score' - let filter - let totalPages - let totalItems - if (search) { - if (!type) { - res.status(422).json({ success: false, message: 'نوع جستجو را مشخص کنید' }) - } else if (type === 'project') { - // جستجو در مدل Project با فیلتر کردن برای user_type === "employer" - - filter = { $or: [{ title: new RegExp(search, 'i'), status: 'accepted' }, { description: new RegExp(search, 'i'), status: 'accepted' }] } - result = await ProjectModel.paginate(filter, { page: parseInt(page), limit: parseInt(limit), sort: { createdAt: -1 } }) - totalPages = result?.totalPages - totalItems = result?.totalDocs - } else if (type === 'user') { - // جستجو در مدل User با فیلتر کردن برای user_type === "user" - filter = { user_type: 'user', $or: [{ user_name: new RegExp(search, 'i') }, { first_name: new RegExp(search, 'i') }, { last_name: new RegExp(search, 'i') }] } - result = await UserModel.paginate(filter, { page: parseInt(page), limit: parseInt(limit), select: selectedFields }) - totalPages = result?.totalPages - totalItems = result?.totalDocs - } else if (type === 'employer') { - // جستجو در مدل User با فیلتر کردن برای user_type === "employer" - filter = { user_type: 'employer', $or: [{ user_name: new RegExp(search, 'i') }, { first_name: new RegExp(search, 'i') }, { last_name: new RegExp(search, 'i') }] } - result = await UserModel.paginate(filter, { page: parseInt(page), limit: parseInt(limit), select: selectedFields }) - totalPages = result?.totalPages - totalItems = result?.totalDocs - } - res.status(200).json({ - success: true, - result: result?.docs, - type, - totalPages, - totalItems - }) - } else { - res.status(422).json({ success: false, message: 'چیزی تایپ کنید' }) - } - } catch (error) { - next(error) - } -} - -module.exports = { - getSearch -} diff --git a/public/modstagram-back/controllers/application/settings/settingsController.js b/public/modstagram-back/controllers/application/settings/settingsController.js deleted file mode 100644 index bd76195..0000000 --- a/public/modstagram-back/controllers/application/settings/settingsController.js +++ /dev/null @@ -1,19 +0,0 @@ -// controllers/settingController.js - -const SettingModel = require('../../../models/SettingsModel') - -// متد برای دریافت تنظیمات بر اساس key -const getSetting = async (req, res, next) => { - try { - const { key } = req.params - const setting = await SettingModel.findOne({ key }) - if (!setting) { - return res.status(404).json({ message: 'تنظیمات مورد نظر یافت نشد' }) - } - res.status(200).json(setting) - } catch (error) { - next(error) - } -} - -module.exports = { getSetting } diff --git a/public/modstagram-back/controllers/application/tickets/ticketsController.js b/public/modstagram-back/controllers/application/tickets/ticketsController.js deleted file mode 100644 index bc67d3b..0000000 --- a/public/modstagram-back/controllers/application/tickets/ticketsController.js +++ /dev/null @@ -1,147 +0,0 @@ -const jwt = require('jsonwebtoken') -const TicketModel = require('../../../models/TicketModel') -const TicketMessageModel = require('../../../models/TicketMessageModel') -const jMoment = require('moment-jalaali') -const path = require('path') -const fs = require('fs-extra') - -const getUserTickets = async (req, res) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - const { page = 1, limit = 10, search } = req.query // افزودن پارامترهای صفحه‌بندی به درخواست - const filter = { user: userId } - if (search) { - filter.$or = [ - { title: { $regex: search, $options: 'i' } } - ] - } - const options = { - page: parseInt(page) || 1, - limit: parseInt(limit) || 10, - sort: { updatedAt: -1 } - } - const tickets = await TicketModel.paginate(filter, options) - const ticketList = tickets?.docs.map(ticket => { - const jDate = jMoment(ticket.createdAt).format('jYYYY-jMM-jDD HH:mm') - return { - ...ticket._doc, - createdAt: jDate - } - }) - res.json({ - tickets: ticketList, - totalPages: tickets.totalPages, // ارسال تعداد کل صفحات - totalItems: tickets.totalDocs // ارسال تعداد کل آیتم‌ها - }) - } catch (error) { - res.status(500).json({ error: 'Internal Server Error' }) - } -} - -const createTicket = async (req, res) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - - const { title } = req.body - - const newTicket = new TicketModel({ - title, - user: userId - }) - await newTicket.save() - - res.status(201).json(newTicket) - } catch (error) { - res.status(500).json({ error: 'Internal Server Error' }) - } -} -const addUserMessageToTicket = async (req, res) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - - const { ticketId } = req.query - const { text } = req.body - const { file } = req.files - let fileUrl = null - if (file) { - // اگر فایل ارسال شده است، آن را ذخیره کنید - const uploadDir = path.join(__dirname, '../../../../storage/tickets') - if (!fs.existsSync(uploadDir)) { - fs.mkdirSync(uploadDir, { recursive: true }) - } - - const uniqueFileName = `${Date.now()}-${file.name}` - const filePath = path.join(uploadDir, uniqueFileName) - await fs.move(file.path, filePath) - - fileUrl = `/tickets/${uniqueFileName}` - } - const newMessage = new TicketMessageModel({ - text, - senderType: 'User', - senderId: userId, - ticket: ticketId, - file: fileUrl - }) - await newMessage.save() - - const ticket = await TicketModel.findById(ticketId) - if (!ticket) { - return res.status(404).json({ error: 'Ticket not found' }) - } - - ticket.status = 'Customer Response' - await ticket.save() - const newMessageWithJalaliDate = { - ...newMessage._doc, - createdAt: jMoment(newMessage.createdAt).format('jYYYY-jMM-jDD HH:mm') - } - res.status(201).json(newMessageWithJalaliDate) - } catch (error) { - res.status(500).json({ error: 'Internal Server Error' }) - } -} -const getTicketMessages = async (req, res) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const { ticketId } = req.query - const { page = 1, limit = 10 } = req.query - const options = { - page: parseInt(page) || 1, - limit: parseInt(limit) || 10, - sort: { createdAt: -1 } - } - const messages = await TicketMessageModel.paginate({ ticket: ticketId }, options) - const ticket = await TicketModel.findById(ticketId) - ticket.new_message = false - await ticket.save() - const messageList = messages?.docs.map(message => { - const jDate = jMoment(message.createdAt).format('jYYYY-jMM-jDD HH:mm') - return { - ...message._doc, - createdAt: jDate - } - }) - res.json({ - messages: messageList.reverse(), - totalPages: messages.totalPages, // ارسال تعداد کل صفحات - totalItems: messages.totalDocs // ارسال تعداد کل آیتم‌ها - }) - } catch (error) { - res.status(500).json({ error: 'Internal Server Error' }) - } -} -module.exports = { getUserTickets, createTicket, addUserMessageToTicket, getTicketMessages } diff --git a/public/modstagram-back/controllers/application/users/getUserController.js b/public/modstagram-back/controllers/application/users/getUserController.js deleted file mode 100644 index 8df2dcb..0000000 --- a/public/modstagram-back/controllers/application/users/getUserController.js +++ /dev/null @@ -1,1378 +0,0 @@ -/* eslint-disable camelcase */ -const { default: mongoose } = require("mongoose"); -const LikeModel = require("../../../models/LikeModel"); -const UserModel = require("../../../models/UserModel"); -const jwt = require("jsonwebtoken"); -const moment = require("moment-jalaali"); -const NotificationModel = require("../../../models/NotificationModel"); -const CommentModel = require("../../../models/CommentModel"); -const { ProvinceModel, CityModel } = require("../../../models/StateCity"); -const OfferModel = require("../../../models/OfferModel"); -const PostModel = require("../../../models/PostModel"); -const ProjectModel = require("../../../models/ProjectModel"); -const LicenseModel = require("../../../models/license") - - -const getAllLicenses = async (req, res, next) => { - try { - const token = req.header("Authorization")?.split(" ")[1]; - if (!token) return res.status(401).send("Access Denied"); - - jwt.verify(token, process.env.APP_SECRET); - - const { page = 1, limit = 10 } = req.query; - - const options = { - page: parseInt(page), - limit: parseInt(limit), - sort: { createdAt: -1 }, - populate: { - path: "userId", - model: UserModel, - select: "user_name first_name last_name is_verified profile_image", - }, - }; - - const licenses = await LicenseModel.paginate({}, options); - - const formattedLicenses = licenses.docs.map((license) => ({ - _id: license._id, - userId: license.userId, - Confirmation: license.Confirmation, - licenseImg: license.licenseImg, // چون خودش Base64 هست - createdAt: moment(license.createdAt).format("jYYYY-jMM-jDD HH:mm"), - updatedAt: moment(license.updatedAt).format("jYYYY-jMM-jDD HH:mm"), - user: license.userId, - })); - - res.status(200).json({ - licenses: formattedLicenses, - totalPages: licenses.totalPages, - totalItems: licenses.totalDocs, - currentPage: licenses.page, - }); - } catch (error) { - console.error("Error fetching licenses:", error); - next(error); - } -}; - - -// GET: دریافت License بر اساس userId -const getLicenseByUserId = async (req, res, next) => { - try { - const token = req.header("Authorization")?.split(" ")[1]; - if (!token) return res.status(401).send("Access Denied"); - jwt.verify(token, process.env.APP_SECRET); - - const { userId } = req.params; - - if (!mongoose.Types.ObjectId.isValid(userId)) { - return res.status(400).json({ message: "شناسه کاربر معتبر نیست" }); - } - - const license = await LicenseModel.findOne({ userId }).populate({ - path: "userId", - model: UserModel, - select: "user_name first_name last_name is_verified profile_image", - }); - - if (!license) { - return res.status(404).json({ message: "License یافت نشد" }); - } - - res.status(200).json(license); // licenseImg همان Base64 است - } catch (error) { - console.error("Error fetching license:", error); - next(error); - } -}; - - - -// POST: ذخیره License به صورت Base64 -const createLicense = async (req, res, next) => { - try { - const token = req.header("Authorization")?.split(" ")[1]; - if (!token) return res.status(401).send("Access Denied"); - - jwt.verify(token, process.env.APP_SECRET); - - const { userId, image } = req.body; - - if (!userId || !image) { - return res.status(400).json({ message: "userId و تصویر الزامی هستند" }); - } - - if (!mongoose.Types.ObjectId.isValid(userId)) { - return res.status(400).json({ message: "شناسه کاربر معتبر نیست" }); - } - - if (!image.startsWith("data:image/")) { - return res.status(400).json({ message: "فقط فایل‌های تصویری مجاز هستند" }); - } - - const existingLicense = await LicenseModel.findOne({ userId }); - if (existingLicense) { - existingLicense.licenseImg = image; - existingLicense.Confirmation = false; // نیاز به تأیید دوباره - await existingLicense.save(); - - return res.status(200).json({ - message: "تصویر مجوز با موفقیت به‌روزرسانی شد", - license: existingLicense, - }); - } - - const license = new LicenseModel({ - userId, - Confirmation: false, - licenseImg: image, - }); - await license.save(); - - res.status(201).json({ message: "License با موفقیت ذخیره شد", license }); - } catch (error) { - console.error("Error saving license:", error); - next(error); - } -}; - - -// PUT: به‌روزرسانی Confirmation و is_verified -const updateLicenseConfirmation = async (req, res, next) => { - try { - const token = req.header("Authorization")?.split(" ")[1]; - if (!token) return res.status(401).send("Access Denied"); - jwt.verify(token, process.env.APP_SECRET); - - const { userId } = req.params; - const { Confirmation } = req.body; - - if (!mongoose.Types.ObjectId.isValid(userId)) { - return res.status(400).json({ message: "شناسه کاربر معتبر نیست" }); - } - - if (typeof Confirmation !== "boolean") { - return res.status(400).json({ message: "Confirmation باید بولین باشد" }); - } - - const license = await LicenseModel.findOneAndUpdate( - { userId }, - { Confirmation }, - { new: true } - ); - - if (!license) { - return res.status(404).json({ message: "License یافت نشد" }); - } - - // اگر Confirmation به true تغییر کند، is_verified را به "true" به‌روزرسانی کن - if (Confirmation) { - await UserModel.findByIdAndUpdate(userId, { is_verified: "true" }); - } - - res.status(200).json({ message: "Confirmation به‌روزرسانی شد", license }); - } catch (error) { - console.error("Error updating license:", error); - next(error); - } -}; - - -// const getUsers = async (req, res, next) => { -// try { -// const token = req.header('Authorization').split(' ')[1] -// if (!token) return res.status(401).send('Access Denied') - -// const decodedToken = jwt.verify(token, process.env.APP_SECRET) -// const { expertise, page = 1, limit = 10 } = req.query -// const filter = {} -// if (expertise) { -// filter.expertise = expertise -// } - -// let users = await UserModel.aggregate([ -// { $match: filter }, -// { $match: { last_post: { $ne: null } } }, -// { -// $addFields: { -// 'last_post.likesCount': { $size: { $ifNull: ['$last_post.likes', []] } } -// } -// }, -// { -// $lookup: { -// from: 'comments', -// let: { userId: '$_id' }, -// pipeline: [ -// { $match: { $expr: { $and: [{ $eq: ['$user', '$$userId'] }, { $eq: ['$status', 'accepted'] }] } } }, -// { $count: 'commentsCount' } -// ], -// as: 'comments' -// } -// }, -// { -// $addFields: { -// commentsCount: { $arrayElemAt: ['$comments.commentsCount', 0] } -// } -// }, -// { -// $project: { -// user_level: 1, -// first_name: 1, -// last_name: 1, -// user_name: 1, -// is_verified: 1, -// user_score: 1, -// rate: 1, -// profile_image: 1, -// last_post: { -// _id: 1, -// post_image: 1, -// caption: 1, -// status: 1, -// user_id: 1, -// updatedAt: 1, -// createdAt: 1, -// __v: 1, -// likesCount: 1, -// is_liked: 1 -// }, -// commentsCount: 1 -// } -// }, -// { $sort: { 'last_post.createdAt': -1 } } -// ]) - -// users = users.filter(user => user.last_post !== null) - -// if (!users || users.length === 0) { -// return res.status(404).json({ message: 'هیچ کاربری با این مشخصات یافت نشد' }) -// } -// users = await Promise.all(users.map(async (user) => { -// const isLikedDocument = await LikeModel.findOne({ postId: user.last_post._id, userId: decodedToken.id }) -// user.last_post.is_liked = !!isLikedDocument -// return user -// })) - -// const startIndex = (page - 1) * limit -// const endIndex = page * limit -// const totalItems = users.length - -// const paginatedUsers = users.slice(startIndex, endIndex) -// if (!users || users.length === 0) { -// return res.status(404).json({ message: 'هیچ کاربری با این مشخصات یافت نشد' }) -// } - -// return res.status(200).json({ -// users: paginatedUsers, -// totalPages: Math.ceil(totalItems / limit), -// totalItems -// }) -// } catch (error) { -// next(error) -// } -// } -const getUsers = async (req, res, next) => { - try { - const token = req.header("Authorization").split(" ")[1]; - if (!token) return res.status(401).send("Access Denied"); - - const decodedToken = jwt.verify(token, process.env.APP_SECRET); - const { - expertise, - page = 1, - limit = 10, - province, - city, - userLevel, - rateFilter, - } = req.query; - const filter = {}; - if (expertise) { - filter.expertise = expertise; - } - if (province) { - const provinceFind = await ProvinceModel.findOne( - { id: province }, - { _id: 0 } - ); - console.log("provinceFind:", provinceFind); - if (provinceFind) { - filter["province.id"] = provinceFind.id; - } - } - if (city) { - const cityFind = await CityModel.findOne({ id: city }); - console.log("cityFind:", cityFind); - if (cityFind) { - filter["city.id"] = cityFind.id; - } - } - if (userLevel) { - filter.user_level = userLevel; - } - - let users = await UserModel.aggregate([ - { $match: filter }, - { $match: { last_post: { $ne: null } } }, - { - $addFields: { - "last_post.likesCount": { - $size: { $ifNull: ["$last_post.likes", []] }, - }, - }, - }, - { - $lookup: { - from: "comments", - let: { userId: "$_id" }, - pipeline: [ - { - $match: { - $expr: { - $and: [ - { $eq: ["$user", "$$userId"] }, - { $eq: ["$status", "accepted"] }, - ], - }, - }, - }, - { $count: "commentsCount" }, - ], - as: "comments", - }, - }, - { - $addFields: { - commentsCount: { $arrayElemAt: ["$comments.commentsCount", 0] }, - }, - }, - { - $project: { - user_level: 1, - first_name: 1, - last_name: 1, - user_name: 1, - is_verified: 1, - user_score: 1, - rate: 1, - profile_image: 1, - expertise: 1, - hair_color: 1, - eye_color: 1, - height: 1, - weight: 1, - size: 1, - services: 1, - last_post: { - _id: 1, - post_image: 1, - caption: 1, - status: 1, - user_id: 1, - updatedAt: 1, - createdAt: 1, - __v: 1, - likesCount: 1, - is_liked: 1, - }, - commentsCount: 1, - }, - }, - { $sort: { "last_post.createdAt": -1 } }, - ]); - - users = users.filter((user) => user.last_post !== null); - - if (!users || users.length === 0) { - return res - .status(404) - .json({ message: "هیچ کاربری با این مشخصات یافت نشد" }); - } - - users = await Promise.all( - users.map(async (user) => { - const isLikedDocument = await LikeModel.findOne({ - postId: user.last_post._id, - userId: decodedToken.id, - }); - user.last_post.is_liked = !!isLikedDocument; - return user; - }) - ); - - if (rateFilter) { - users.sort((a, b) => { - if (rateFilter === "کمترین") { - return a.rate - b.rate; - } else if (rateFilter === "بیشترین") { - return b.rate - a.rate; - } - return 0; - }); - } - - const startIndex = (page - 1) * limit; - const endIndex = page * limit; - const totalItems = users.length; - - const paginatedUsers = users.slice(startIndex, endIndex); - - return res.status(200).json({ - users: paginatedUsers, - totalPages: Math.ceil(totalItems / limit), - totalItems, - }); - } catch (error) { - next(error); - } -}; -// const getUsersWeb = async (req, res, next) => { -// try { -// const token = req.header('Authorization')?.split(' ')[1] -// const decodedToken = token && jwt.verify(token, process.env.APP_SECRET) - -// const { expertise, page = 1, limit = 10, province, city, userLevel, rateFilter } = req.query -// const filter = {} -// if (expertise) { -// filter.expertise = expertise -// } -// if (province) { -// const provinceFind = await ProvinceModel.findOne({ id: province }, { _id: 0 }) -// if (provinceFind) { -// filter['province.id'] = provinceFind.id -// } -// } -// if (city) { -// const cityFind = await CityModel.findOne({ id: city }) -// if (cityFind) { -// filter['city.id'] = cityFind.id -// } -// } -// if (userLevel) { -// filter.user_level = userLevel -// } - -// let users = await UserModel.aggregate([ -// { $match: filter }, -// { $match: { last_post: { $ne: null } } }, -// { -// $addFields: { -// 'last_post.likesCount': { $size: { $ifNull: ['$last_post.likes', []] } } -// } -// }, -// { -// $lookup: { -// from: 'comments', -// let: { userId: '$_id' }, -// pipeline: [ -// { $match: { $expr: { $and: [{ $eq: ['$user', '$$userId'] }, { $eq: ['$status', 'accepted'] }] } } }, -// { $count: 'commentsCount' } -// ], -// as: 'comments' -// } -// }, -// { -// $addFields: { -// commentsCount: { $arrayElemAt: ['$comments.commentsCount', 0] } -// } -// }, -// { -// $project: { -// user_level: 1, -// first_name: 1, -// last_name: 1, -// user_name: 1, -// is_verified: 1, -// user_score: 1, -// rate: 1, -// profile_image: 1, -// expertise: 1, -// hair_color: 1, -// eye_color: 1, -// height: 1, -// weight: 1, -// size: 1, -// services: 1, -// last_post: { -// _id: 1, -// post_image: 1, -// caption: 1, -// status: 1, -// user_id: 1, -// updatedAt: 1, -// createdAt: 1, -// __v: 1, -// likesCount: 1, -// is_liked: 1 -// }, -// commentsCount: 1 -// } -// }, -// { $sort: { 'last_post.createdAt': -1 } } -// ]) -// const getUsersWeb = async (req, res, next) => { -// try { -// const token = req.header('Authorization')?.split(' ')[1] -// const decodedToken = token && jwt.verify(token, process.env.APP_SECRET) - -// const { expertise, page = 1, limit = 10, province, city, userLevel, rateFilter, userId } = req.query -// const filter = {} - -// if (expertise) filter.expertise = expertise -// if (province) { -// const provinceFind = await ProvinceModel.findOne({ id: province }, { _id: 0 }) -// if (provinceFind) filter['province.id'] = provinceFind.id -// } -// if (city) { -// const cityFind = await CityModel.findOne({ id: city }) -// if (cityFind) filter['city.id'] = cityFind.id -// } -// if (userLevel) filter.user_level = userLevel - -// // ← اضافه کردن userId به فیلتر -// if (userId) { -// if (!mongoose.Types.ObjectId.isValid(userId)) { -// return res.status(400).json({ message: 'شناسه کاربر معتبر نیست' }) -// } -// filter._id = mongoose.Types.ObjectId(userId) -// } - -// let users = await UserModel.aggregate([ -// { $match: filter }, -// { $match: { last_post: { $ne: null } } }, -// { -// $addFields: { -// 'last_post.likesCount': { $size: { $ifNull: ['$last_post.likes', []] } } -// } -// }, -// { -// $lookup: { -// from: 'comments', -// let: { userId: '$_id' }, -// pipeline: [ -// { $match: { $expr: { $and: [{ $eq: ['$user', '$$userId'] }, { $eq: ['$status', 'accepted'] }] } } }, -// { $count: 'commentsCount' } -// ], -// as: 'comments' -// } -// }, -// { -// $addFields: { -// commentsCount: { $arrayElemAt: ['$comments.commentsCount', 0] } -// } -// }, -// { -// $project: { -// user_level: 1, -// first_name: 1, -// last_name: 1, -// user_name: 1, -// is_verified: 1, -// user_score: 1, -// rate: 1, -// profile_image: 1, -// expertise: 1, -// hair_color: 1, -// eye_color: 1, -// height: 1, -// weight: 1, -// size: 1, -// services: 1, -// last_post: 1, -// commentsCount: 1 -// } -// }, -// { $sort: { 'last_post.createdAt': -1 } } -// ]) - -// users = users.filter(user => user.last_post !== null) - -// if (!users || users.length === 0) { -// return res.status(404).json({ message: 'هیچ کاربری با این مشخصات یافت نشد' }) -// } -// // بررسی لایک‌ها فقط در صورت وجود توکن -// if (token) { -// users = await Promise.all(users.map(async (user) => { -// const isLikedDocument = await LikeModel.findOne({ postId: user.last_post._id, userId: decodedToken.id }) -// user.last_post.is_liked = !!isLikedDocument -// return user -// })) -// } else { -// // اگر توکن وجود ندارد، مقدار پیش‌فرض را تنظیم کنید -// users = users.map(user => { -// user.last_post.is_liked = false -// return user -// }) -// } - -// if (rateFilter) { -// users.sort((a, b) => { -// if (rateFilter === 'کمترین') { -// return a.rate - b.rate -// } else if (rateFilter === 'بیشترین') { -// return b.rate - a.rate -// } -// return 0 -// }) -// } - -// const startIndex = (page - 1) * limit -// const endIndex = page * limit -// const totalItems = users.length - -// const paginatedUsers = users.slice(startIndex, endIndex) - -// return res.status(200).json({ -// users: paginatedUsers, -// totalPages: Math.ceil(totalItems / limit), -// totalItems -// }) -// } catch (error) { -// next(error) -// } -// } - -// const getUsersWeb = async (req, res, next) => { -// try { -// const token = req.header("Authorization")?.split(" ")[1]; -// const decodedToken = token && jwt.verify(token, process.env.APP_SECRET); - -// const { -// expertise, -// page = 1, -// limit = 10, -// province, -// city, -// userLevel, -// rateFilter, -// _id, -// } = req.query; - -// const filter = {}; -// if (expertise) filter.expertise = expertise; - -// if (province) { -// const provinceFind = await ProvinceModel.findOne({ id: province }, { _id: 0 }); -// if (provinceFind) filter["province.id"] = provinceFind.id; -// } - -// if (city) { -// const cityFind = await CityModel.findOne({ id: city }); -// if (cityFind) filter["city.id"] = cityFind.id; -// } - -// if (userLevel) filter.user_level = userLevel; -// if (_id) filter._id = _id; - -// // پیدا کردن کاربران -// let users = await UserModel.find(filter) -// .select("-password -blocked_users -blocked_by") -// .lean(); - -// if (!users || users.length === 0) { -// return res.status(404).json({ message: "هیچ کاربری با این مشخصات یافت نشد" }); -// } - -// // آماده‌سازی لیست userIds برای گرفتن همه پست‌ها یکجا -// const userIds = users.map(u => u._id); - -// // گرفتن همه پست‌ها یکجا (به جای N+1 query) -// let posts = await PostModel.find({ user_id: { $in: userIds }, status: { $ne: null } }) -// .sort({ createdAt: -1 }) -// .lean(); - -// // گرفتن همه لایک‌های کاربران یکجا (برای بهبود کارایی) -// let likeFilter = {}; -// if (decodedToken) likeFilter.userId = decodedToken.id; -// const likes = decodedToken -// ? await LikeModel.find({ userId: decodedToken.id, postId: { $in: posts.map(p => p._id) } }).lean() -// : []; - -// const likesMap = {}; -// likes.forEach(l => { likesMap[l.postId.toString()] = true; }); - -// // گرفتن تعداد کامنت‌ها یکجا برای همه کاربران -// const comments = await CommentModel.aggregate([ -// { $match: { user: { $in: userIds }, status: "accepted" } }, -// { $group: { _id: "$user", count: { $sum: 1 } } } -// ]); -// const commentsMap = {}; -// comments.forEach(c => { commentsMap[c._id.toString()] = c.count; }); - -// // اتصال پست‌ها و کامنت‌ها به کاربران -// users = users.map(user => { -// const userPosts = posts.filter(p => p.user_id.toString() === user._id.toString()); -// user.posts = userPosts.map(p => ({ -// ...p, -// likesCount: p.likes ? p.likes.length : 0, -// is_liked: !!likesMap[p._id.toString()] -// })); -// user.commentsCount = commentsMap[user._id.toString()] || 0; -// return user; -// }); - -// // حذف کاربران بدون پست -// users = users.filter(u => u.posts.length > 0); - -// // مرتب‌سازی -// if (rateFilter) { -// users.sort((a, b) => { -// if (rateFilter === 'کمترین') return a.rate - b.rate; -// if (rateFilter === 'بیشترین') return b.rate - a.rate; -// return 0; -// }); -// } else { -// // مرتب‌سازی بر اساس جدیدترین پست آخر -// users.sort((a, b) => new Date(b.posts[0].createdAt) - new Date(a.posts[0].createdAt)); -// } - -// // صفحه‌بندی -// const startIndex = (page - 1) * limit; -// const endIndex = page * limit; -// const totalItems = users.length; -// const paginatedUsers = users.slice(startIndex, endIndex); - -// return res.status(200).json({ -// users: paginatedUsers, -// totalPages: Math.ceil(totalItems / limit), -// totalItems, -// }); - -// } catch (error) { -// console.error(error); -// next(error); -// } -// }; - -const getPostsWeb = async (req, res, next) => { - try { - const token = req.header("Authorization")?.split(" ")[1]; - const decodedToken = token ? jwt.verify(token, process.env.APP_SECRET) : null; - - const { - expertise, - page = 1, - limit = 10, - province, - city, - userLevel, - rateFilter, - _id, - type, - } = req.query; - - const postFilter = { status: { $ne: null } }; - if (type === 'video' || type === 'image') { - postFilter.type = type; - } - - // اکسپلور: ویدئوهای همه کاربران بدون فیلتر تخصص - if (type === 'video' && !expertise && !_id && !province && !city) { - let explorePosts = await PostModel.find(postFilter) - .sort({ createdAt: -1 }) - .lean(); - const userIds = [...new Set(explorePosts.map((p) => String(p.user_id)))]; - const usersMap = await UserModel.find({ _id: { $in: userIds } }) - .select('_id user_name first_name last_name expertise province city user_level') - .lean(); - const usersById = Object.fromEntries(usersMap.map((u) => [String(u._id), u])); - explorePosts = explorePosts.map((post) => { - const user = usersById[String(post.user_id)] || {}; - return { - ...post, - user_name: user.user_name || '', - first_name: user.first_name || '', - last_name: user.last_name || '', - expertise: user.expertise || '', - province: user.province || {}, - city: user.city || {}, - user_level: user.user_level || '', - likesCount: post.likes ? post.likes.length : 0, - is_liked: false, - commentsCount: 0 - }; - }); - const startIndex = (page - 1) * limit; - const paginatedPosts = explorePosts.slice(startIndex, startIndex + parseInt(limit)); - return res.status(200).json({ - posts: paginatedPosts, - totalPages: Math.ceil(explorePosts.length / limit) || 1, - totalItems: explorePosts.length - }); - } - - const userFilter = {}; - - if (expertise) userFilter.expertise = expertise; - if (province) { - const provinceFind = await ProvinceModel.findOne({ id: province }, { _id: 0 }); - if (provinceFind) userFilter["province.id"] = provinceFind.id; - } - if (city) { - const cityFind = await CityModel.findOne({ id: city }); - if (cityFind) userFilter["city.id"] = cityFind.id; - } - if (userLevel) userFilter.user_level = userLevel; - if (_id) userFilter._id = _id; - - const users = await UserModel.find(userFilter) - .select("_id user_name first_name last_name expertise province city user_level") - .lean(); - - if (!users || users.length === 0) { - return res.status(200).json({ posts: [], totalPages: 0, totalItems: 0 }); - } - - const userIds = users.map(u => u._id); - postFilter.user_id = { $in: userIds }; - - let posts = await PostModel.find(postFilter) - .sort({ createdAt: -1 }) - .lean(); - - if (!posts || posts.length === 0) { - return res.status(200).json({ posts: [], totalPages: 0, totalItems: 0 }); - } - - let likeFilter = {}; - if (decodedToken) likeFilter.userId = decodedToken.id; - const likes = decodedToken - ? await LikeModel.find({ userId: decodedToken.id, postId: { $in: posts.map(p => p._id) } }).lean() - : []; - - const likesMap = {}; - likes.forEach(l => { likesMap[l.postId.toString()] = true; }); - - const comments = await CommentModel.aggregate([ - { $match: { post: { $in: posts.map(p => p._id) }, status: "accepted" } }, - { $group: { _id: "$post", count: { $sum: 1 } } } - ]); - const commentsMap = {}; - comments.forEach(c => { commentsMap[c._id.toString()] = c.count; }); - - posts = posts.map(post => { - const user = users.find(u => u._id.toString() === post.user_id.toString()); - return { - ...post, - user_name: user?.user_name || "", - first_name: user?.first_name || "", - last_name: user?.last_name || "", - expertise: user?.expertise || "", - province: user?.province || {}, - city: user?.city || {}, - user_level: user?.user_level || "", - likesCount: post.likes ? post.likes.length : 0, - is_liked: !!likesMap[post._id.toString()], - commentsCount: commentsMap[post._id.toString()] || 0, - }; - }); - - if (rateFilter) { - posts.sort((a, b) => { - if (rateFilter === 'کمترین') return (a.rate || 0) - (b.rate || 0); - if (rateFilter === 'بیشترین') return (b.rate || 0) - (a.rate || 0); - return 0; - }); - } - - const startIndex = (page - 1) * limit; - const endIndex = page * limit; - const totalItems = posts.length; - const paginatedPosts = posts.slice(startIndex, endIndex); - - return res.status(200).json({ - posts: paginatedPosts, - totalPages: Math.ceil(totalItems / limit), - totalItems, - }); - - } catch (error) { - console.error("Error in getPostsWeb:", error.message, error.stack); - return res.status(500).json({ message: "خطای سرور: " + error.message }); - } -}; - -const getSingleUser = async (req, res, next) => { - try { - const token = req.header("Authorization").split(" ")[1]; - if (!token) return res.status(401).send("Access Denied"); - const user_id = req.query.user_id; - // eslint-disable-next-line no-unused-vars - const decodedToken = jwt.verify(token, process.env.APP_SECRET); - const userReqId = decodedToken.id; - - if (!mongoose.Types.ObjectId.isValid(user_id)) { - return res.status(400).json({ message: "شناسه کاربر معتبر نیست" }); - } - const user = await UserModel.findById(user_id); - - if (!user) { - return res.status(404).json({ message: "کاربر مورد نظر یافت نشد" }); - } - const shamsiDate = moment(user.created_at).format("jYYYY-jMM-jDD"); - const lastOnline = moment(user.last_online).format("jYYYY-jMM-jDD"); - - // بررسی بلاک شدن - const blockedByCurrentUser = user.blocked_by.includes(userReqId); - const blockedYou = user.blocked_users.includes(userReqId); - - // Allow chat - const offerExists = await OfferModel.exists({ - $or: [ - { sender: userReqId, receiver: user_id }, - { sender: user_id, receiver: userReqId }, - ], - }); - const response = { - is_self: user_id.toString() === userReqId.toString() ? "true" : "false", - _id: user._id, - last_online: lastOnline, - created_at: shamsiDate, - user_type: user.user_type, - user_level: user.user_level, - first_name: user.first_name, - last_name: user.last_name, - user_name: user.user_name, - show_location: user.show_location, - is_verified: user.is_verified, - user_score: user.user_score, - rate: user.rate, - bio: user.bio, - height: user.height, - weight: user.weight, - size: user.size, - eye_color: user.eye_color, - hair_color: user.hair_color, - profile_image: user.profile_image, - lat: user.show_location ? user.lat : null, - lng: user.show_location ? user.lng : null, - province: user.province, - city: user.city, - address: user.show_location ? user.address : null, - is_blocked: blockedByCurrentUser, - blocked_you: blockedYou, - offer_status: !!offerExists, - monthly_free_offer: user.monthly_free_offer, - services: user.services, - expertise: user.expertise, - sub_expertise: user.sub_expertise, - }; - return res.status(200).json({ user: response }); - } catch (error) { - next(error); - } -}; -const getSingleUserWeb = async (req, res, next) => { - try { - let userReqId = null; - - // دریافت توکن و بررسی معتبر بودنش (اگر وجود داشت) - const authHeader = req.header("Authorization"); - if (authHeader) { - const token = authHeader.split(" ")[1]; - try { - const decodedToken = jwt.verify(token, process.env.APP_SECRET); - userReqId = decodedToken.id; - } catch (err) { - console.warn("توکن نامعتبر است، ادامه بدون احراز هویت"); // فقط هشدار، نه ارور - } - } - - let user; - const { user_id, user_name } = req.query; - - if (user_id) { - if (!mongoose.Types.ObjectId.isValid(user_id)) { - return res.status(400).json({ message: "شناسه کاربر معتبر نیست" }); - } - user = await UserModel.findById(user_id); - } else if (user_name) { - user = await UserModel.findOne({ user_name }); - } else { - return res - .status(400) - .json({ message: "لطفاً user_id یا user_name ارسال کنید" }); - } - - if (!user) { - return res.status(404).json({ message: "کاربر مورد نظر یافت نشد" }); - } - - const shamsiDate = moment(user.created_at).format("jYYYY-jMM-jDD"); - const lastOnline = moment(user.last_online).format("jYYYY-jMM-jDD"); - - // بررسی بلاک شدن (فقط اگر توکن معتبر داشتیم) - let blockedByCurrentUser = false; - let blockedYou = false; - let offerExists = false; - - if (userReqId) { - blockedByCurrentUser = user.blocked_by.includes(userReqId); - blockedYou = user.blocked_users.includes(userReqId); - offerExists = await OfferModel.exists({ - sender: userReqId, - receiver: user._id, - }); - } - // دریافت تعداد پست‌ها و پروژه‌ها - const postsCount = await PostModel.countDocuments({ - user_id: user._id, - status: { $in: ["accept"] }, - }); - const allProjectsCount = await ProjectModel.countDocuments({ - selected_user: user._id, - }); - const successfulProjectsCount = await ProjectModel.countDocuments({ - selected_user: user._id, - status: "done", - }); - - const response = { - is_self: userReqId - ? user._id.toString() === userReqId.toString() - : "false", - _id: user._id, - last_online: lastOnline, - created_at: shamsiDate, - user_type: user.user_type, - user_level: user.user_level, - first_name: user.first_name, - last_name: user.last_name, - user_name: user.user_name, - show_location: user.show_location, - is_verified: user.is_verified, - user_score: user.user_score, - rate: user.rate, - bio: user.bio, - height: user.height, - weight: user.weight, - size: user.size, - eye_color: user.eye_color, - hair_color: user.hair_color, - profile_image: user.profile_image, - lat: user.show_location ? user.lat : null, - lng: user.show_location ? user.lng : null, - province: user.province, - city: user.city, - address: user.show_location ? user.address : null, - is_blocked: blockedByCurrentUser, - blocked_you: blockedYou, - offer_status: !!offerExists, - services: user.services, - expertise: user.expertise, - sub_expertise: user.sub_expertise, - postsCount, - allProjectsCount, - successfulProjectsCount, - }; - - return res.status(200).json({ user: response }); - } catch (error) { - next(error); - } -}; -const getUserContactInfo = async (req, res, next) => { - try { - const token = req.header("Authorization").split(" ")[1]; - if (!token) return res.status(401).send("Access Denied"); - // eslint-disable-next-line no-unused-vars - const decodedToken = jwt.verify(token, process.env.APP_SECRET); - const user_id = decodedToken.id; - - if (!mongoose.Types.ObjectId.isValid(user_id)) { - return res.status(400).json({ message: "شناسه کاربر معتبر نیست" }); - } - const user = await UserModel.findById(user_id); - - if (!user) { - return res.status(404).json({ message: "کاربر مورد نظر یافت نشد" }); - } - - const response = { - contactInfo: user?.contactInfo, - _id: user._id, - }; - return res.status(200).json({ data: response }); - } catch (error) { - next(error); - } -}; -const blockUser = async (req, res) => { - try { - const { user_to_block } = req.body; - const token = req.header("Authorization").split(" ")[1]; - if (!token) return res.status(401).send("Access Denied"); - const decodedToken = jwt.verify(token, process.env.APP_SECRET); - const userReqId = decodedToken.id; - - const currentUser = await UserModel.findById(userReqId); // Req - const userToBlock = await UserModel.findById(user_to_block); // To Block - - userToBlock.blocked_by.push(currentUser); - currentUser.blocked_users.push(userToBlock); - - // بررسی تعداد بلاک ها و تنظیم block_status - if (userToBlock.blocked_by.length >= 3) { - userToBlock.block_status = true; - } - - await currentUser.save(); - await userToBlock.save(); - - res.status(200).json({ message: "کاربر با موفقیت بلاک شد" }); - } catch (error) { - console.error("Error blocking user:", error); - res.status(500).json({ error: "Server error" }); - } -}; - -const unblockUser = async (req, res) => { - try { - const { user_to_unblock } = req.body; - const token = req.header("Authorization").split(" ")[1]; - if (!token) return res.status(401).send("Access Denied"); - const decodedToken = jwt.verify(token, process.env.APP_SECRET); - const userReqId = decodedToken.id; - - const currentUser = await UserModel.findById(userReqId); // Req - const userToUnblock = await UserModel.findById(user_to_unblock); // To Unblock - - // حذف کاربر از لیست blocked_by کاربر فعلی - currentUser.blocked_users.pull(userToUnblock._id); - // حذف کاربر از لیست blocked_users کاربر مورد نظر - userToUnblock.blocked_by.pull(currentUser._id); - - // بررسی تعداد بلاک ها و تنظیم block_status - if (userToUnblock.blocked_by.length < 3) { - userToUnblock.block_status = null; - } - - await currentUser.save(); - await userToUnblock.save(); - - res.status(200).json({ message: "کاربر با موفقیت آنبلاک شد" }); - } catch (error) { - console.error("Error unblocking user:", error); - res.status(500).json({ error: "Server error" }); - } -}; - -const getComments = async (req, res, next) => { - try { - const token = req.header("Authorization").split(" ")[1]; - if (!token) return res.status(401).send("Access Denied"); - const user_id = req.query.user_id; - const post_id = req.query.post_id; - - if (!mongoose.Types.ObjectId.isValid(user_id)) { - return res.status(400).json({ message: "شناسه کاربر معتبر نیست" }); - } - const user = await UserModel.findById(user_id); - const { page = 1, limit = 10 } = req.query; - if (!user) { - return res.status(404).json({ message: "کاربر مورد نظر یافت نشد" }); - } - - const filter = { user: user_id, status: "accepted" }; - if (post_id && mongoose.Types.ObjectId.isValid(post_id)) { - filter.post = post_id; - } - - const options = { - page: parseInt(page), - limit: parseInt(limit), - sort: { createdAt: -1 }, - populate: [ - { path: "creator", select: "user_name profile_image is_verified" }, - { path: "project", select: "project_name" }, - ], - }; - - const comments = await CommentModel.paginate(filter, options); - - const formattedComments = comments.docs.map((comment) => ({ - _id: comment._id, - comment: comment.comment, - rating: comment.rating, - createdAt: moment(comment.createdAt).format("jYYYY-jMM-jDD HH:mm"), - status: comment.status, - user: { - profile_image: comment.creator.profile_image, - user_name: comment.creator.user_name, - is_verified: comment.creator.is_verified, - _id: comment.creator._id, - }, - project: comment.project ? comment.project.project_name : null, - post_id: comment.post ? comment.post.toString() : null, - })); - - res.status(200).json({ - comments: formattedComments, - totalPages: comments.totalPages, - totalItems: comments.totalDocs, - currentPage: comments.page, - }); - } catch (error) { - next(error); - } -}; -const createUserComment = async (req, res, next) => { - try { - const token = req.header("Authorization").split(" ")[1]; - if (!token) return res.status(401).send("Access Denied"); - - const decodedToken = jwt.verify(token, process.env.APP_SECRET); - const creatorId = decodedToken.id; - - const { user_id, comment, rate, post_id } = req.body; - if (!user_id || !comment) { - return res.status(400).send({ message: "All fields are required" }); - } - - const existingRating = await CommentModel.findOne({ - user: user_id, - creator: creatorId, - comment_for: post_id ? "post" : "user", - rating: { $exists: true, $ne: null } - }); - - let ratingValue = rate; - if (existingRating) { - ratingValue = existingRating.rating; - } else { - if (!rate || rate < 1 || rate > 5) { - return res.status(400).send({ message: "Rating must be between 1 and 5" }); - } - } - - const newComment = new CommentModel({ - user: user_id, - creator: creatorId, - rating: ratingValue, - comment, - comment_for: post_id ? "post" : "user", - post: post_id || undefined, - status: "pending", - }); - await newComment.save(); - - const user = await UserModel.findById(user_id); - - // محاسبه امتیاز جدید کاربر - const comments = await CommentModel.find({ - user: user_id, - comment_for: "user", - }); - const totalRating = comments.reduce( - (acc, comment) => acc + comment.rating, - 0 - ); - const totalComments = comments.length; - const averageRating = totalRating / totalComments; - - // تعیین سطح کاربر - let userLevel; - if (user.expertise === "مدل") { - if (totalRating <= 50) userLevel = "تازه وارد"; - else if (totalRating <= 100) userLevel = "استاندارد"; - else if (totalRating <= 300) userLevel = "حرفه‌ای"; - else userLevel = "استاد"; - } else if (["زیبایی", "عکاس"].includes(user.expertise)) { - if (totalRating <= 50) userLevel = "تازه وارد"; - else if (totalRating <= 100) userLevel = "استاندارد"; - else if (totalRating <= 300) userLevel = "حرفه‌ای"; - else userLevel = "استاد"; - } - - // به‌روزرسانی اطلاعات کاربر - user.user_score = totalRating; - user.user_level = userLevel; - user.rate = averageRating.toFixed(1); - await user.save(); - - // ارسال نوتیفیکیشن - const notification = new NotificationModel({ - user_id: user._id, - type: "user_comment", - title: "نظر جدید", - description: `یک کاربر جدید برای شما نظر ثبت کرد: - ${comment} - امتیاز: ${rate} از 5`, - }); - await notification.save(); - - res.status(201).json({ - message: "نظر با موفقیت ثبت شد و بعد از تایید، منتشر میشود.", - comment: newComment, - }); - } catch (error) { - next(error); - } -}; - -const inviteEmployer = async (req, res, next) => { - const token = req.header("Authorization").split(" ")[1]; - if (!token) return res.status(401).send("Access Denied"); - const user_id = req.query.user_id; - // eslint-disable-next-line no-unused-vars - const decodedToken = jwt.verify(token, process.env.APP_SECRET); - const userReqId = decodedToken.id; - - if (!mongoose.Types.ObjectId.isValid(user_id)) { - return res.status(400).json({ message: "شناسه کاربر معتبر نیست" }); - } - const user = await UserModel.findById(user_id); - const creatorUser = await UserModel.findById(userReqId); - - if (!user) { - return res.status(404).json({ message: "کاربر مورد نظر یافت نشد" }); - } - - const today = new Date(); - today.setHours(0, 0, 0, 0); - - const existingNotification = await NotificationModel.findOne({ - user_id: user._id, - project_post_id: userReqId, - type: "invite", - createdAt: { $gte: today }, - }); - - if (existingNotification) { - return res - .status(400) - .json({ - message: "شما امروز برای این کارفرما درخواست همکاری ارسال کرده اید.", - type: "today", - }); - } - const notification = new NotificationModel({ - user_id: user._id, - project_post_id: userReqId, - type: "invite", - title: "دعوت به همکاری", - description: `کاربر ${creatorUser.user_name} شما را برای همکاری دعوت کرده است.`, - }); - await notification.save(); - - res.status(201).json({ message: "درخواست همکاری با موفقیت ثبت شد" }); -}; - -module.exports = { - getUsers, - getSingleUser, - blockUser, - unblockUser, - getComments, - inviteEmployer, - getUserContactInfo, - getPostsWeb, - getSingleUserWeb, - createUserComment, - getAllLicenses, - getLicenseByUserId, - createLicense, - updateLicenseConfirmation, -}; diff --git a/public/modstagram-back/controllers/application/verify/addressController.js b/public/modstagram-back/controllers/application/verify/addressController.js deleted file mode 100644 index 4f021ba..0000000 --- a/public/modstagram-back/controllers/application/verify/addressController.js +++ /dev/null @@ -1,112 +0,0 @@ -/* eslint-disable camelcase */ -const { ProvinceModel, CityModel } = require('../../../models/StateCity') -const UserModel = require('../../../models/UserModel') -const jwt = require('jsonwebtoken') - -const setAddress = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const { province_id, city_id, address, lat, lng, show_location } = req.body - // اعتبارسنجی داده‌ها - if (!province_id || !city_id || !address || !lat || !lng || show_location === 'undefined') { - return res.status(422).json({ - error: true, - message: 'اطلاعات ارسالی ناقص است' - }) - } - - // یافتن کاربر با شماره موبایل - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const user = await UserModel.findById(decodedToken.id) - if (!user) { - return res.status(404).json({ - error: true, - message: 'کاربری با این شماره موبایل یافت نشد' - }) - } - - // یافتن استان و شهر - const province = await ProvinceModel.findOne({ id: province_id }) - const city = await CityModel.findOne({ id: city_id }) - if (!province || !city) { - return res.status(404).json({ - error: true, - message: 'استان یا شهر موردنظر یافت نشد' - }) - } - - user.province = province - user.city = city - user.address = address - user.lat = lat - user.lng = lng - user.show_location = show_location - - await user.save() - - return res.json({ - message: 'آدرس با موفقیت به‌روزرسانی شد' - }) - } catch (error) { - next(error) - } -} -const updateAddress = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const { province_id, city_id, address, lat, lng, show_location } = req.body - - // اعتبارسنجی داده‌ها - if (!province_id || !city_id || !address || !lat || !lng || show_location === undefined) { - return res.status(422).json({ - error: true, - message: 'اطلاعات ارسالی ناقص است' - }) - } - - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - - // یافتن کاربر با استفاده از شناسه کاربر - const user = await UserModel.findById(userId) - if (!user) { - return res.status(404).json({ - error: true, - message: 'کاربری با این شناسه یافت نشد' - }) - } - - // یافتن استان و شهر با استفاده از شناسه استان و شهر - const province = await ProvinceModel.findOne({ id: province_id }) - const city = await CityModel.findOne({ id: city_id }) - if (!province || !city) { - return res.status(404).json({ - error: true, - message: 'استان یا شهر مورد نظر یافت نشد' - }) - } - - // به‌روزرسانی اطلاعات آدرس کاربر - user.province = province - user.city = city - user.address = address - user.lat = lat - user.lng = lng - user.show_location = show_location - - await user.save() - - return res.json({ - message: 'آدرس با موفقیت به‌روزرسانی شد' - }) - } catch (error) { - next(error) - } -} - -module.exports = { - setAddress, updateAddress -} diff --git a/public/modstagram-back/controllers/application/verify/authController.js b/public/modstagram-back/controllers/application/verify/authController.js deleted file mode 100644 index e3756e6..0000000 --- a/public/modstagram-back/controllers/application/verify/authController.js +++ /dev/null @@ -1,108 +0,0 @@ -/* eslint-disable camelcase */ -const UserModel = require('../../../models/UserModel') -const { check, validationResult } = require('express-validator') -const jwt = require('jsonwebtoken') - -const saveAuthValidationRules = () => { - return [ - check('shaba').notEmpty().withMessage('شماره شبا نمی‌تواند خالی باشد') - .matches(/^(?=.{24}$)[0-9]*$/).withMessage('فرمت شماره شبا صحیح نیست'), - check('birthday').notEmpty().withMessage('تاریخ تولد نمی‌تواند خالی باشد'), - check('national_code').notEmpty().withMessage('کد ملی نمی‌تواند خالی باشد') - .isLength({ min: 10, max: 10 }).withMessage('کد ملی باید 10 رقم باشد') - ] -} - -const saveAuth = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const errors = validationResult(req) - if (!errors.isEmpty()) { - return res.status(422).json({ errors: errors.array() }) - } - const { shaba, birthday, national_code } = req.body - if (!shaba || !birthday || !national_code) { - return res.status(422).json({ - error: true, - message: 'اطلاعات ارسالی اشتباه است' - }) - } - - // جستجوی کاربر با شماره موبایل ارسالی - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const user = await UserModel.findById(decodedToken.id) - if (!user) { - return res.status(404).json({ - error: true, - message: 'کاربری با این شماره موبایل یافت نشد' - }) - } - - // بررسی تکراری بودن کد ملی - const existingUserWithNationalCode = await UserModel.findOne({ national_code }) - if (existingUserWithNationalCode && existingUserWithNationalCode._id.toString() !== user._id.toString()) { - return res.status(409).json({ - error: true, - message: 'کد ملی تکراری است' - }) - } - user.shaba = shaba - user.birthday = birthday - user.national_code = national_code - await user.save() - - return res.json({ - message: 'اطلاعات با موفقیت به‌روزرسانی شد' - }) - } catch (error) { - next(error) - } -} -const updateShaba = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const errors = validationResult(req) - if (!errors.isEmpty()) { - return res.status(422).json({ errors: errors.array() }) - } - - const { shaba } = req.body - - if (!shaba) { - return res.status(422).json({ - error: true, - message: 'شبا ارسال نشده است' - }) - } - - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - - // جستجوی کاربر با استفاده از شناسه کاربر - const user = await UserModel.findById(userId) - - if (!user) { - return res.status(404).json({ - error: true, - message: 'کاربری با این شناسه یافت نشد' - }) - } - - // فقط شبا را به‌روزرسانی کنید - user.shaba = shaba - await user.save() - - return res.json({ - message: 'شبا با موفقیت به‌روزرسانی شد' - }) - } catch (error) { - next(error) - } -} - -module.exports = { - saveAuth, saveAuthValidationRules, updateShaba -} diff --git a/public/modstagram-back/controllers/application/verify/colorsController.js b/public/modstagram-back/controllers/application/verify/colorsController.js deleted file mode 100644 index 6b1f040..0000000 --- a/public/modstagram-back/controllers/application/verify/colorsController.js +++ /dev/null @@ -1,80 +0,0 @@ -/* eslint-disable camelcase */ -const UserModel = require('../../../models/UserModel') -const jwt = require('jsonwebtoken') - -const setColors = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const { eye_color, hair_color } = req.body - if (!eye_color || !hair_color) { - return res.status(422).json({ - error: true, - message: 'اطلاعات ارسالی اشتباه است' - }) - } - - // جستجوی کاربر با شماره موبایل ارسالی - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const user = await UserModel.findById(decodedToken.id) - if (!user) { - return res.status(404).json({ - error: true, - message: 'کاربری با این شماره موبایل یافت نشد' - }) - } - - user.eye_color = eye_color - user.hair_color = hair_color - await user.save() - - return res.json({ - message: 'رنگ ها با موفقیت به‌روزرسانی شد' - }) - } catch (error) { - next(error) - } -} -const updateColors = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const { eye_color, hair_color } = req.body - - // اعتبارسنجی داده‌ها - if (!eye_color || !hair_color) { - return res.status(422).json({ - error: true, - message: 'اطلاعات ارسالی ناقص است' - }) - } - - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - - // یافتن کاربر با استفاده از شناسه کاربر - const user = await UserModel.findById(userId) - if (!user) { - return res.status(404).json({ - error: true, - message: 'کاربری با این شناسه یافت نشد' - }) - } - - // به‌روزرسانی اطلاعات رنگ‌ها - user.eye_color = eye_color - user.hair_color = hair_color - await user.save() - - return res.json({ - message: 'رنگ‌ها با موفقیت به‌روزرسانی شد' - }) - } catch (error) { - next(error) - } -} - -module.exports = { - setColors, updateColors -} diff --git a/public/modstagram-back/controllers/application/verify/conversationController.js b/public/modstagram-back/controllers/application/verify/conversationController.js deleted file mode 100644 index 95bc845..0000000 --- a/public/modstagram-back/controllers/application/verify/conversationController.js +++ /dev/null @@ -1,74 +0,0 @@ -/* eslint-disable camelcase */ -const UserModel = require('../../../models/UserModel') -const jwt = require('jsonwebtoken') - -const setConversation = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const { bio, conversation_projects } = req.body - if (!bio || conversation_projects === undefined) { - return res.status(422).json({ - error: true, - message: 'اطلاعات ارسالی اشتباه است' - }) - } - // جستجوی کاربر با شماره موبایل ارسالی - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const user = await UserModel.findById(decodedToken.id) - if (!user) { - return res.status(404).json({ - error: true, - message: 'کاربری با این شماره موبایل یافت نشد' - }) - } - - user.bio = bio - user.conversation_projects = conversation_projects - await user.save() - - return res.json({ - message: 'روابط عمومی با موفقیت به‌روزرسانی شد' - }) - } catch (error) { - next(error) - } -} -const updateConversation = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const { bio, conversation_projects } = req.body - - if (!bio || conversation_projects === undefined) { - return res.status(422).json({ - error: true, - message: 'اطلاعات ارسالی اشتباه است' - }) - } - - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - // جستجوی کاربر با استفاده از شناسه کاربر - const user = await UserModel.findById(userId) - if (!user) { - return res.status(404).json({ - error: true, - message: 'کاربری با این شناسه یافت نشد' - }) - } - user.bio = bio - user.conversation_projects = conversation_projects - await user.save() - - return res.json({ - message: 'روابط عمومی با موفقیت به‌روزرسانی شد' - }) - } catch (error) { - next(error) - } -} -module.exports = { - setConversation, updateConversation -} diff --git a/public/modstagram-back/controllers/application/verify/cooperationTypeController.js b/public/modstagram-back/controllers/application/verify/cooperationTypeController.js deleted file mode 100644 index 2debfbe..0000000 --- a/public/modstagram-back/controllers/application/verify/cooperationTypeController.js +++ /dev/null @@ -1,93 +0,0 @@ -/* eslint-disable camelcase */ -const UserModel = require('../../../models/UserModel') -const jwt = require('jsonwebtoken') - -const setCooperationType = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const { cooperation_type, cooperation_abroad } = req.body - if (!cooperation_type || cooperation_abroad === undefined) { - return res.status(422).json({ - error: true, - message: 'اطلاعات ارسالی اشتباه است' - }) - } - if (!['all', 'verified'].includes(cooperation_type)) { - return res.status(422).json({ - error: true, - message: 'نوع همکاری نیست' - }) - } - - // جستجوی کاربر با شماره موبایل ارسالی - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const user = await UserModel.findById(decodedToken.id) - if (!user) { - return res.status(404).json({ - error: true, - message: 'کاربری با این شماره موبایل یافت نشد' - }) - } - - user.cooperation_type = cooperation_type - user.cooperation_abroad = cooperation_abroad - await user.save() - - return res.json({ - message: 'نوع همکاری با موفقیت به‌روزرسانی شد' - }) - } catch (error) { - next(error) - } -} -const updateCooperationType = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const { cooperation_type, cooperation_abroad } = req.body - - if (!cooperation_type || cooperation_abroad === undefined) { - return res.status(422).json({ - error: true, - message: 'اطلاعات ارسالی اشتباه است' - }) - } - - if (!['all', 'verified'].includes(cooperation_type)) { - return res.status(422).json({ - error: true, - message: 'نوع همکاری نامعتبر است' - }) - } - - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - - // جستجوی کاربر با استفاده از شناسه کاربر - const user = await UserModel.findById(userId) - - if (!user) { - return res.status(404).json({ - error: true, - message: 'کاربری با این شناسه یافت نشد' - }) - } - - user.cooperation_type = cooperation_type - user.cooperation_abroad = cooperation_abroad - await user.save() - - return res.json({ - message: 'نوع همکاری با موفقیت به‌روزرسانی شد' - }) - } catch (error) { - next(error) - } -} - -module.exports = { - setCooperationType, - updateCooperationType -} diff --git a/public/modstagram-back/controllers/application/verify/expertiseController.js b/public/modstagram-back/controllers/application/verify/expertiseController.js deleted file mode 100644 index 3c88796..0000000 --- a/public/modstagram-back/controllers/application/verify/expertiseController.js +++ /dev/null @@ -1,81 +0,0 @@ -/* eslint-disable camelcase */ -const UserModel = require('../../../models/UserModel') -const jwt = require('jsonwebtoken') - -const setExpertise = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const { expertise, sub_expertise } = req.body - if (!expertise || !sub_expertise) { - return res.status(422).json({ - error: true, - message: 'اطلاعات ارسالی اشتباه است' - }) - } - - // جستجوی کاربر با شماره موبایل ارسالی - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const user = await UserModel.findById(decodedToken.id) - if (!user) { - return res.status(404).json({ - error: true, - message: 'کاربری با این شماره موبایل یافت نشد' - }) - } - - // آپدیت نام کاربری به صورت lowercase - user.expertise = expertise - user.sub_expertise = sub_expertise - await user.save() - - return res.json({ - message: 'تخصص با موفقیت به‌روزرسانی شد' - }) - } catch (error) { - next(error) - } -} - -const updateExpertise = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const { expertise, sub_expertise } = req.body - - // اعتبارسنجی داده‌ها - if (!expertise || !sub_expertise) { - return res.status(422).json({ - error: true, - message: 'اطلاعات ارسالی ناقص است' - }) - } - - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - - // یافتن کاربر با استفاده از شناسه کاربر - const user = await UserModel.findById(userId) - if (!user) { - return res.status(404).json({ - error: true, - message: 'کاربری با این شناسه یافت نشد' - }) - } - - // به‌روزرسانی اطلاعات تخصص و زیرتخصص - user.expertise = expertise - user.sub_expertise = sub_expertise - await user.save() - - return res.json({ - message: 'تخصص با موفقیت به‌روزرسانی شد' - }) - } catch (error) { - next(error) - } -} -module.exports = { - setExpertise, updateExpertise -} diff --git a/public/modstagram-back/controllers/application/verify/genderController.js b/public/modstagram-back/controllers/application/verify/genderController.js deleted file mode 100644 index 2371eca..0000000 --- a/public/modstagram-back/controllers/application/verify/genderController.js +++ /dev/null @@ -1,46 +0,0 @@ -/* eslint-disable camelcase */ -const UserModel = require('../../../models/UserModel') -const jwt = require('jsonwebtoken') - -const setGender = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const { gender } = req.body - if (!gender) { - return res.status(422).json({ - error: true, - message: 'اطلاعات ورودی اشتباه است' - }) - } - if (!['male', 'female'].includes(gender)) { - return res.status(422).json({ - error: true, - message: 'جنسیت معتبر نیست' - }) - } - // جستجوی کاربر با شماره موبایل ارسالی - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const user = await UserModel.findById(decodedToken.id) - if (!user) { - return res.status(404).json({ - error: true, - message: 'کاربری با این شماره موبایل یافت نشد' - }) - } - - // آپدیت نوع یوزر - user.gender = gender.toLowerCase() - await user.save() - - return res.json({ - message: 'جنسیت با موفقیت به‌روزرسانی شد' - }) - } catch (error) { - next(error) - } -} - -module.exports = { - setGender -} diff --git a/public/modstagram-back/controllers/application/verify/servicesController.js b/public/modstagram-back/controllers/application/verify/servicesController.js deleted file mode 100644 index 6ce2826..0000000 --- a/public/modstagram-back/controllers/application/verify/servicesController.js +++ /dev/null @@ -1,107 +0,0 @@ -/* eslint-disable camelcase */ -const UserModel = require('../../../models/UserModel') -const jwt = require('jsonwebtoken') -const fs = require('fs-extra') -const path = require('path') - -const setServices = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const user = await UserModel.findById(decodedToken.id) - if (!user) { - return res.status(422).json({ - error: true, - message: 'شما دسترسی به این بخش ندارید' - }) - } - const { services } = req.body - if (!services) { - return res.status(422).json({ - error: true, - message: 'اطلاعات ارسالی اشتباه است' - }) - } - - // مدیریت تصاویر برای خدمات - const servicesWithImages = [] - const parsedServices = JSON.parse(services) // پارس کردن رشته JSON به آرایه جاوا اسکریپت - if (parsedServices && parsedServices.length > 0) { - for (const service of parsedServices) { - const serviceImages = [] - const serviceId = service.id - if (req.files && req.files.serviceImages && req.files.serviceImages[serviceId]) { - const imageFiles = Array.isArray(req.files.serviceImages[serviceId]) ? req.files.serviceImages[serviceId] : [req.files.serviceImages[serviceId]] - const uploadDir = path.join(__dirname, '../../../../storage/services') - if (!fs.existsSync(uploadDir)) { - fs.mkdirSync(uploadDir, { recursive: true }) - } - for (const imageFile of imageFiles) { - const uniqueFileName = `${user.user_name}-${Date.now()}${Math.random().toString().slice(2, 11)}${path.extname(imageFile.name)}` - const filePath = path.join(uploadDir, uniqueFileName) - // await fs.promises.rename(imageFile.path, filePath) - await fs.move(imageFile.path, filePath) - const imageUrl = `/services/${uniqueFileName}` - serviceImages.push(imageUrl) - // به‌روزرسانی مسیر تصویر در آبجکت service - service.image = imageUrl - } - } else { - console.log('sss') - } - servicesWithImages.push({ ...service, images: serviceImages }) - } - } - - user.services = servicesWithImages - await user.save() - - return res.json({ - message: 'خدمات با موفقیت ثبت شد' - }) - } catch (error) { - next(error) - } -} - -const updateServices = async (req, res, next) => { - try { - const { height, weight, size } = req.body - - if (!height || !weight || !size) { - return res.status(422).json({ - error: true, - message: 'اطلاعات ارسالی اشتباه است' - }) - } - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - // جستجوی کاربر - const user = await UserModel.findById(userId) - - if (!user) { - return res.status(404).json({ - error: true, - message: 'کاربر یافت نشد' - }) - } - - user.height = height - user.weight = weight - user.size = size - await user.save() - - return res.json({ - message: 'سایز با موفقیت به‌روزرسانی شد' - }) - } catch (error) { - next(error) - } -} -module.exports = { - setServices, updateServices -} diff --git a/public/modstagram-back/controllers/application/verify/setNationalCardImageController.js b/public/modstagram-back/controllers/application/verify/setNationalCardImageController.js deleted file mode 100644 index 9fdf27a..0000000 --- a/public/modstagram-back/controllers/application/verify/setNationalCardImageController.js +++ /dev/null @@ -1,55 +0,0 @@ -/* eslint-disable camelcase */ -const fs = require('fs-extra') -const path = require('path') -const UserModel = require('../../../models/UserModel') -const jwt = require('jsonwebtoken') - -const setNationalCardImage = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const { national_card_image } = req.files - // جستجوی کاربر با شماره موبایل ارسالی - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const user = await UserModel.findById(decodedToken.id) - if (!user) { - return res.status(404).json({ - error: true, - message: 'کاربری با این شماره موبایل یافت نشد' - }) - } - // بررسی آیا فایل آپلود شده است - if (!national_card_image) { - return res.status(400).json({ - error: true, - message: 'لطفاً عکس کارت ملی را انتخاب کنید' - }) - } - - // ذخیره فایل عکس پروفایل - const uploadDir = path.join(__dirname, '../../../../storage/carts') - if (!fs.existsSync(uploadDir)) { - fs.mkdirSync(uploadDir, { recursive: true }) - } - - const uniqueFileName = `${user.user_name}-${Date.now()}${path.extname(national_card_image.name)}` - const filePath = path.join(uploadDir, uniqueFileName) - await fs.move(national_card_image.path, filePath) - - // ذخیره مسیر فایل در دیتابیس - user.national_card_image = `/carts/${uniqueFileName}` - user.is_verified = 'pending' - await user.save() - - return res.json({ - message: 'عکس کارت ملی با موفقیت ذخیره شد', - national_card_image: user.national_card_image - }) - } catch (error) { - next(error) - } -} - -module.exports = { - setNationalCardImage -} diff --git a/public/modstagram-back/controllers/application/verify/setProfileImageController.js b/public/modstagram-back/controllers/application/verify/setProfileImageController.js deleted file mode 100644 index 5c1d357..0000000 --- a/public/modstagram-back/controllers/application/verify/setProfileImageController.js +++ /dev/null @@ -1,105 +0,0 @@ -/* eslint-disable camelcase */ -const fs = require('fs-extra') -const path = require('path') -const UserModel = require('../../../models/UserModel') -const jwt = require('jsonwebtoken') - -const setProfileImage = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const { mobile } = req.body - const { profile_image } = req.files - if (!mobile) { - return res.status(422).json({ - error: true, - message: 'اطلاعات ارسالی اشتباه است' - }) - } - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const user = await UserModel.findById(decodedToken.id) - if (!user) { - return res.status(404).json({ - error: true, - message: 'کاربری با این شماره موبایل یافت نشد' - }) - } - // بررسی آیا فایل آپلود شده است - if (!profile_image) { - return res.status(400).json({ - error: true, - message: 'لطفاً عکس پروفایل را انتخاب کنید' - }) - } - - // ذخیره فایل عکس پروفایل - const uploadDir = path.join(__dirname, '../../../../storage/profiles') - if (!fs.existsSync(uploadDir)) { - fs.mkdirSync(uploadDir, { recursive: true }) - } - const uniqueFileName = `${user.user_name}-${Date.now()}${path.extname(profile_image.name)}` - const filePath = path.join(uploadDir, uniqueFileName) - - await fs.move(profile_image.path, filePath) - // ذخیره مسیر فایل در دیتابیس - user.profile_image = `/profiles/${uniqueFileName}` - await user.save() - - return res.json({ - message: 'عکس پروفایل با موفقیت ذخیره شد', - profile_image: user.profile_image - }) - } catch (error) { - next(error) - } -} - -const updateProfileImage = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - const { profile_image } = req.files - - if (!profile_image) { - return res.status(422).json({ - error: true, - message: 'اطلاعات ارسالی اشتباه است' - }) - } - - const user = await UserModel.findById(userId) - - if (!user) { - return res.status(404).json({ - error: true, - message: 'کاربری با این شماره موبایل یافت نشد' - }) - } - - const uploadDir = path.join(__dirname, '../../../../storage/profiles') - - if (!fs.existsSync(uploadDir)) { - fs.mkdirSync(uploadDir, { recursive: true }) - } - - const uniqueFileName = `${user.user_name}-${Date.now()}${path.extname(profile_image.name)}` - const filePath = path.join(uploadDir, uniqueFileName) - - await fs.move(profile_image.path, filePath) - - user.profile_image = `/profiles/${uniqueFileName}` - await user.save() - - return res.json({ - message: 'عکس پروفایل با موفقیت به‌روزرسانی شد', - profile_image: user.profile_image - }) - } catch (error) { - next(error) - } -} -module.exports = { - setProfileImage, updateProfileImage -} diff --git a/public/modstagram-back/controllers/application/verify/sizesController.js b/public/modstagram-back/controllers/application/verify/sizesController.js deleted file mode 100644 index 3516069..0000000 --- a/public/modstagram-back/controllers/application/verify/sizesController.js +++ /dev/null @@ -1,78 +0,0 @@ -/* eslint-disable camelcase */ -const UserModel = require('../../../models/UserModel') -const jwt = require('jsonwebtoken') - -const setSizes = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const { height, weight, size } = req.body - if (!height || !weight || !size) { - return res.status(422).json({ - error: true, - message: 'اطلاعات ارسالی اشتباه است' - }) - } - - // جستجوی کاربر با شماره موبایل ارسالی - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const user = await UserModel.findById(decodedToken.id) - if (!user) { - return res.status(404).json({ - error: true, - message: 'کاربری با این شماره موبایل یافت نشد' - }) - } - - user.height = height - user.weight = weight - user.size = size - await user.save() - - return res.json({ - message: 'سایز با موفقیت به‌روزرسانی شد' - }) - } catch (error) { - next(error) - } -} - -const updateSizes = async (req, res, next) => { - try { - const { height, weight, size } = req.body - - if (!height || !weight || !size) { - return res.status(422).json({ - error: true, - message: 'اطلاعات ارسالی اشتباه است' - }) - } - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - // جستجوی کاربر - const user = await UserModel.findById(userId) - - if (!user) { - return res.status(404).json({ - error: true, - message: 'کاربر یافت نشد' - }) - } - - user.height = height - user.weight = weight - user.size = size - await user.save() - - return res.json({ - message: 'سایز با موفقیت به‌روزرسانی شد' - }) - } catch (error) { - next(error) - } -} -module.exports = { - setSizes, updateSizes -} diff --git a/public/modstagram-back/controllers/application/version/versionController.js b/public/modstagram-back/controllers/application/version/versionController.js deleted file mode 100644 index 6b557f3..0000000 --- a/public/modstagram-back/controllers/application/version/versionController.js +++ /dev/null @@ -1,16 +0,0 @@ -const VersionModel = require('../../../models/VersionModel') - -// Endpoint برای دریافت نسخه فعلی -const getVersion = async (req, res, next) => { - try { - const currentVersion = await VersionModel.findOne().sort({ _id: -1 }).exec() - if (!currentVersion) { - return res.status(200).json({ message: 'نسخه‌ای پیدا نشد' }) - } - res.json(currentVersion) - } catch (error) { - res.status(500).json({ message: 'خطای سرور', error }) - } -} - -module.exports = { getVersion } diff --git a/public/modstagram-back/controllers/application/workroom/workroomController.js b/public/modstagram-back/controllers/application/workroom/workroomController.js deleted file mode 100644 index bba1d1c..0000000 --- a/public/modstagram-back/controllers/application/workroom/workroomController.js +++ /dev/null @@ -1,232 +0,0 @@ -/* eslint-disable camelcase */ -const ProjectModel = require('../../../models/ProjectModel') -const RequestModel = require('../../../models/RequestModel') -const UserModel = require('../../../models/UserModel') -const jwt = require('jsonwebtoken') -const calculateRemainingTime = (milliseconds) => { - const days = Math.floor(milliseconds / (1000 * 60 * 60 * 24)) - const hours = Math.floor((milliseconds % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)) - - return `${days} روز و ${hours} ساعت` -} -const getProjects = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - // eslint-disable-next-line no-unused-vars - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - const user = await UserModel.findById(decodedToken.id) - const { status_filter, page = 1, limit = 10 } = req.query // افزودن پارامترهای صفحه‌بندی به درخواست - // ساخت فیلتر برای استفاده در جستجوی MongoDB - let filter = {} // افزودن شرط برای payment_status - if (user.user_type === 'user') { - if (status_filter) { - if (status_filter === 'دریافتی') { - filter = { created_for_user: userId, status: 'accepted' } - } else if (status_filter === 'ارسال شده') { - filter = { requested_users: userId, status: 'accepted' } - } else if (status_filter === 'در دست اقدام') { - filter = { selected_user: userId, status: 'ongoing' } - } else if (status_filter === 'اتمام پروژه') { - filter = { selected_user: userId, status: 'done' } - } else if (status_filter === 'کنسل شده') { - filter = { selected_user: userId, status: 'cancled' } - } else { - filter = { - $or: [ - { selected_user: userId }, - { requested_users: userId }, - { created_for_user: userId } - ] - } - } - } else { - filter = { - $or: [ - { selected_user: userId }, - { requested_users: userId }, - { created_for_user: userId } - ] - } - } - } else { - if (status_filter) { - if (status_filter === 'منتشر شده') { - filter = { creator_id: userId, status: 'accepted' } - } else if (status_filter === 'در دست اقدام') { - filter = { creator_id: userId, status: 'ongoing' } - } else if (status_filter === 'اتمام پروژه') { - filter = { creator_id: userId, status: 'done' } - } else if (status_filter === 'کنسل شده') { - filter = { creator_id: userId, status: 'cancled' } - } else if (status_filter === 'در دست بررسی') { - filter = { creator_id: userId, status: { $in: ['paid', 'rejected'] } } - } else if (status_filter === 'پرداخت نشده') { - filter = { creator_id: userId, status: 'pre_payment' } - } else { - filter = { creator_id: userId } - } - } else { - filter = { creator_id: userId } - } - } - // paid - // دریافت لیست پروژه‌ها با استفاده از فیلتر - - // استفاده از مدل پیجینیت شده برای دریافت نتایج صفحه‌بندی شده - const options = { - page: parseInt(page), // تبدیل صفحه به عدد صحیح - limit: parseInt(limit), // تبدیل محدودیت به عدد صحیح - sort: { createdAt: -1 } - } - const projects = await ProjectModel.paginate(filter, options) - const projectsWithUserInfo = await Promise.all(projects?.docs.map(async project => { - const creator = await UserModel.findById(project.creator_id).select('first_name last_name user_name user_type is_verified profile_image gender province city rate') - const projectWithUserInfo = { - ...project._doc, - creator, - status_filter - } - const currentTime = new Date() - const projectCreatedAt = new Date(project.createdAt) - const timeDiff = project.offer_time * 24 * 60 * 60 * 1000 - (currentTime - projectCreatedAt) - const remainingTime = calculateRemainingTime(timeDiff) - projectWithUserInfo.remainingTime = remainingTime - return projectWithUserInfo - })) - res.status(200).json({ - projects: projectsWithUserInfo, - totalPages: projects.totalPages, // ارسال تعداد کل صفحات - totalItems: projects.totalDocs // ارسال تعداد کل آیتم‌ها - }) - } catch (error) { - next(error) - } -} -const getSingleProject = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - const projectId = req.query.projectId - const projectRequests = await RequestModel.find({ project: projectId }) - .populate('user', 'price time user_level first_name last_name user_name is_verified user_score rate profile_image') - .sort({ status: 1 }) - .lean() - const modifiedRequests = projectRequests.map(request => ({ - ...request, - time: request?.user?._id.toString() === userId ? request.time : null, - price: request?.user?._id.toString() === userId ? request.price : null - })) - const project = await ProjectModel.findById(projectId) - if (!project) { - return res.status(404).json({ message: 'پروژه مورد نظر یافت نشد' }) - } - // محاسبه مبلغ باقیمانده و مجموع مبلغ پرداخت شده - // تابع محاسبه مبلغ پرداخت شده - const getTotalPaidAmount = (installments) => { - let totalPaidAmount = 0 - installments.forEach(installment => { - totalPaidAmount += installment.amount - }) - return totalPaidAmount - } - - // تابع محاسبه مبلغ باقیمانده - const getRemainingAmount = (project) => { - const totalPaidAmount = getTotalPaidAmount(project.installments) - const remainingAmount = project.final_price - totalPaidAmount - return remainingAmount - } - - const totalPaidAmount = getTotalPaidAmount(project.installments) - const remainingAmount = getRemainingAmount(project) - // اطلاعات کاربر سازنده را نیز دریافت کنید و به آبجکت پروژه اضافه کنید - const creator = await UserModel.findById(project.creator_id).select('first_name last_name user_name user_type is_verified profile_image gender province city rate') - - const projectWithUserInfo = { - ...project._doc, - creator // اضافه کردن اطلاعات کاربر به آبجکت پروژه - } - const selectedUser = await UserModel.findById(project.selected_user).select('_id user_name first_name last_name user_type is_verified profile_image expertise sub_expertise province city rate user_level user_score') - projectWithUserInfo.selected_user = selectedUser - // محاسبه مدت زمان باقی‌مانده برای پروژه - const currentTime = new Date() - const projectCreatedAt = new Date(project.createdAt) - const timeDiff = project.offer_time * 24 * 60 * 60 * 1000 - (currentTime - projectCreatedAt) - const remainingTime = calculateRemainingTime(timeDiff) - projectWithUserInfo.remainingTime = remainingTime - let projectDetails = projectWithUserInfo - if ((project.selected_user && project.selected_user.toString()) === userId || project.creator_id.toString() === userId) { - projectDetails = { - ...projectWithUserInfo, - total_paid_amount: totalPaidAmount, - remaining_amount: remainingAmount - } - } else { - projectDetails = - projectWithUserInfo - } - // } - res.status(200).json({ project: projectDetails, projectRequests: modifiedRequests }) - } catch (error) { - next(error) - } -} - -const getProjectRequests = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - // بررسی اینکه آیا کاربر ایجاد کننده پروژه است یا خیر - const projectId = req.params.projectId - const project = await ProjectModel.findOne({ _id: projectId, creator_id: userId }) - if (!project) { - return res.status(403).send({ message: 'Access denied: You are not the creator of this project.' }) - } - - // تابع محاسبه مبلغ پرداخت شده - const getTotalPaidAmount = (installments) => { - let totalPaidAmount = 0 - installments.forEach(installment => { - totalPaidAmount += installment.amount - }) - return totalPaidAmount - } - - // تابع محاسبه مبلغ باقیمانده - const getRemainingAmount = (project) => { - const totalPaidAmount = getTotalPaidAmount(project.installments) - const remainingAmount = project.final_price - totalPaidAmount - return remainingAmount - } - - // محاسبه مبلغ باقیمانده - const remainingAmount = getRemainingAmount(project) - - // یافتن جزییات پروژه - const creator = await UserModel.findById(project.creator_id).select('first_name last_name user_name user_type is_verified profile_image gender province city rate') - const selectedUser = await UserModel.findById(project.selected_user).select('_id user_name first_name last_name user_type is_verified profile_image expertise sub_expertise province city rate user_level user_score') - const totalPaidAmount = getTotalPaidAmount(project.installments) - - const projectRequests = await RequestModel.find({ project: projectId }).populate('user', 'price time user_level first_name last_name user_name is_verified user_score rate profile_image').sort({ status: 1 }) - const projectinfo = await ProjectModel.findById(projectId) // جزییات درخواست‌های کاربران - projectinfo.selected_user = selectedUser - const projectDetails = { - ...projectinfo._doc, - creator, - total_paid_amount: totalPaidAmount, - remaining_amount: remainingAmount - } - res.status(200).json({ projectRequests, projectDetails }) - } catch (error) { - next(error) - } -} -module.exports = { - getProjects, getSingleProject, getProjectRequests -} diff --git a/public/modstagram-back/controllers/panel/advertising/academyCategoryController.js b/public/modstagram-back/controllers/panel/advertising/academyCategoryController.js deleted file mode 100644 index 9e52065..0000000 --- a/public/modstagram-back/controllers/panel/advertising/academyCategoryController.js +++ /dev/null @@ -1,50 +0,0 @@ -const AcademyCategoryModel = require('../../models/AcademyCategoryModel'); - -// دریافت همه دسته‌بندی‌های اکادمی -exports.getAll = async (req, res) => { - try { - const categories = await AcademyCategoryModel.find({}).sort({ createdAt: -1 }); - res.json({ success: true, data: categories }); - } catch (error) { - res.status(500).json({ success: false, message: error.message }); - } -}; - -// ایجاد دسته‌بندی جدید -exports.create = async (req, res) => { - try { - const { title } = req.body; - if (!title) return res.status(400).json({ success: false, message: "عنوان الزامی است" }); - - const category = await AcademyCategoryModel.create({ title }); - res.status(201).json({ success: true, message: "دسته‌بندی ایجاد شد", data: category }); - } catch (error) { - res.status(500).json({ success: false, message: error.message }); - } -}; - -// ویرایش دسته‌بندی -exports.update = async (req, res) => { - try { - const { id } = req.params; - const { title, status } = req.body; - - const category = await AcademyCategoryModel.findByIdAndUpdate(id, { title, status }, { new: true }); - if (!category) return res.status(404).json({ success: false, message: "دسته‌بندی یافت نشد" }); - - res.json({ success: true, message: "دسته‌بندی ویرایش شد", data: category }); - } catch (error) { - res.status(500).json({ success: false, message: error.message }); - } -}; - -// حذف دسته‌بندی -exports.remove = async (req, res) => { - try { - const { id } = req.params; - await AcademyCategoryModel.findByIdAndDelete(id); - res.json({ success: true, message: "دسته‌بندی حذف شد" }); - } catch (error) { - res.status(500).json({ success: false, message: error.message }); - } -}; \ No newline at end of file diff --git a/public/modstagram-back/controllers/panel/advertising/advertisingController.js b/public/modstagram-back/controllers/panel/advertising/advertisingController.js deleted file mode 100644 index 63831b2..0000000 --- a/public/modstagram-back/controllers/panel/advertising/advertisingController.js +++ /dev/null @@ -1,350 +0,0 @@ -/* eslint-disable eqeqeq */ -/* eslint-disable camelcase */ -const { ProvinceModel, CityModel } = require('../../../models/StateCity') -const AdvertisingModel = require('../../../models/AdvertisingModel') -// const AdvertisingLikeModel = require('../../../models/AdvertisingLikeModel') -// const AdvertisingComment = require('../../../models/AdvertisingCommentModel') -const AdvertisingProfileModel = require('../../../models/AdvertisingProfile') -const NotificationModel = require('../../../models/NotificationModel') -const AdvertisingCategoryModel = require('../../../models/AdvertisingCategoryModel') - - -const getAdvertisings = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const { - page = 1, limit = 10, province, city, category, search, - startDate, - endDate, - status - } = req.query - - const filter = { - } - if (province) { - const provinceFind = await ProvinceModel.findOne({ id: province }, { _id: 0 }) - filter.province = provinceFind - } - if (city) { - const cityFind = await CityModel.findOne({ id: city }) - filter.city = cityFind - } - if (category) { - filter.category = category - } - if (search) { - filter.$or = [ - { title: { $regex: search, $options: 'i' } }, - { category: { $regex: search, $options: 'i' } } - ] - } - - // Date - if (startDate || endDate) { - filter.createdAt = {} - - if (startDate) { - filter.createdAt.$gte = new Date(startDate) // تاریخ شروع - } - - if (endDate) { - filter.createdAt.$lte = new Date(endDate) // تاریخ پایان - } - } - - if (status) { - filter.status = status - } - const options = { - page: parseInt(page), - limit: parseInt(limit), - sort: { createdAt: -1 }, - populate: [ - { path: 'creator_id', select: 'user_name first_name last_name' } - ] - } - const advertisings = await AdvertisingModel.paginate(filter, options) - - const newAds = advertisings.docs.map(ad => { - return { - // فیلدهای مشخص‌شده از ad._doc - _id: ad._doc._id, - creator_id: ad._doc.creator_id, - category: ad._doc.category, - title: ad._doc.title, - province: ad._doc.province, - city: ad._doc.city, - status: ad._doc.status, - neighbourhood: ad._doc.neighbourhood - } - }) - res.status(200).json({ - advertisings: newAds, - totalPages: advertisings.totalPages, - totalItems: advertisings.totalDocs - }) - } catch (error) { - next(error) - } -} -const getSingleAdvertising = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const advertisingId = req.query.advertisingId - const advertising = await AdvertisingModel.findById(advertisingId) - .populate('creator_id', '_id user_name first_name last_name') - - if (!advertising) { - return res.status(404).json({ message: 'ویترین مورد نظر یافت نشد' }) - } - - const creator = await AdvertisingProfileModel.findOne({ user: advertising.creator_id._id }) - - // اضافه کردن تعداد لایک‌ها، تعداد کامنت‌ها و وضعیت لایک به تبلیغ - const advertisingData = { - ...advertising._doc - } - - res.status(200).json({ - advertising: advertisingData, - creator - }) - } catch (error) { - next(error) - } -} -const acceptAdvertising = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const { advertisingId } = req.body - - // پیدا کردن تبلیغ - const advertising = await AdvertisingModel.findById(advertisingId) - if (!advertising) { - return res.status(404).json({ message: 'تبلیغ مورد نظر یافت نشد' }) - } - - // تغییر وضعیت به accepted و ذخیره زمان قبول شدن - advertising.status = 'accepted' - advertising.acceptedAt = new Date() - await advertising.save() - const notification = new NotificationModel({ - user_id: advertising?.creator_id, - project_post_id: advertising?._id, - type: 'vitrine', - title: 'تایید ویترین', - description: `ویترین شما با عنوان: ${advertising?.title} تایید و منتشر شد ` - }) - await notification.save() - - res.status(200).json({ message: 'تبلیغ اکسپت شد و پس از 15 روز منقضی خواهد شد' }) - } catch (error) { - next(error) - } -} -const rejectAdvertising = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const { advertisingId, rejectReason } = req.body - - // پیدا کردن تبلیغ - const advertising = await AdvertisingModel.findById(advertisingId) - if (!advertising) { - return res.status(404).json({ message: 'تبلیغ مورد نظر یافت نشد' }) - } - - // تغییر وضعیت به rejected و ذخیره دلیل رد شدن - advertising.status = 'rejected' - advertising.reject_reason = rejectReason - await advertising.save() - const notification = new NotificationModel({ - user_id: advertising?.creator_id, - project_post_id: advertising?._id, - type: 'vitrine', - title: 'رد ویترین', - description: `ویترین شما با عنوان: ${advertising?.title} رد شد، برای دیدن علت رد، لمس کنید ` - }) - await notification.save() - res.status(200).json({ message: 'تبلیغ رد شد', advertising }) - } catch (error) { - next(error) - } -} - - -const deleteAdvertisingCategory = async (req, res, next) => { - try { - const { id } = req.params - - // چک کنه که ID معتبره - if (!id.match(/^[0-9a-fA-F]{24}$/)) { - return res.status(400).json({ - success: false, - message: 'شناسه معتبر نمی‌باشد' - }) - } - - // پیدا کنه دسته‌بندی رو - const category = await AdvertisingCategoryModel.findById(id) - if (!category) { - return res.status(404).json({ - success: false, - message: 'دسته‌بندی مورد نظر یافت نشد' - }) - } - - // حذف کنه - await category.deleteOne() - - return res.status(200).json({ - success: true, - message: 'دسته‌بندی تبلیغات با موفقیت حذف شد', - data: { id } - }) - } catch (error) { - next(error) - } -} - -const createAdvertisingCategory = async (req, res, next) => { - try { - const { title, status } = req.body - - // اعتبارسنجی ورودی‌ها - if (!title || title.trim().length < 1) { - return res.status(400).json({ - success: false, - message: 'عنوان دسته‌بندی الزامی است' - }) - } - - if (title.length > 255) { - return res.status(400).json({ - success: false, - message: 'عنوان دسته‌بندی نباید بیشتر از ۲۵۵ کاراکتر باشد' - }) - } - - // بررسی اینکه دسته‌بندی تکراری نباشد - const exists = await AdvertisingCategoryModel.findOne({ title: title.trim() }) - if (exists) { - return res.status(409).json({ - success: false, - message: 'این دسته‌بندی از قبل وجود دارد' - }) - } - - // ایجاد دسته‌بندی جدید - const newCategory = await AdvertisingCategoryModel.create({ - title: title.trim(), - status: status ?? true - }) - - return res.status(201).json({ - success: true, - message: 'دسته‌بندی تبلیغات با موفقیت ایجاد شد', - data: newCategory - }) - } catch (error) { - next(error) // میره به errorHandler مرکزی - } -} - -const getAdvertisingCategories = async (req, res, next) => { - try { - const page = Math.max(parseInt(req.query.page || '1', 10), 1); - const limit = Math.max(Math.min(parseInt(req.query.limit || '20', 10), 100), 1); - const { status, q, sort } = req.query; - - const query = {}; - if (typeof status !== 'undefined') { - // accept 'true'/'false' or boolean - if (status === 'true' || status === 'false') query.status = status === 'true'; - else if (status === '1' || status === '0') query.status = status === '1'; - } - if (q) { - query.title = { $regex: q.trim(), $options: 'i' }; - } - - const options = { - page, - limit, - sort: sort || '-createdAt', - lean: true, - }; - - // اگر mongoose-paginate-v2 نصب و فعال است: - if (typeof AdvertisingCategoryModel.paginate === 'function') { - const result = await AdvertisingCategoryModel.paginate(query, options); - return res.status(200).json({ - success: true, - totalDocs: result.totalDocs, - totalPages: result.totalPages, - page: result.page, - limit: result.limit, - docs: result.docs, - }); - } - - // fallback بدون paginate - const docs = await AdvertisingCategoryModel.find(query) - .sort(options.sort) - .skip((page - 1) * limit) - .limit(limit) - .lean(); - - const totalDocs = await AdvertisingCategoryModel.countDocuments(query); - const totalPages = Math.ceil(totalDocs / limit); - - return res.status(200).json({ - success: true, - totalDocs, - totalPages, - page, - limit, - docs, - }); - } catch (error) { - next(error); - } -}; - -/** - * GET /advertising/advertising-categories/:id - */ -const getAdvertisingCategoryById = async (req, res, next) => { - try { - const { id } = req.params; - if (!id || !id.match(/^[0-9a-fA-F]{24}$/)) { - return res.status(400).json({ success: false, message: 'شناسه معتبر نیست' }); - } - - const category = await AdvertisingCategoryModel.findById(id).lean(); - if (!category) { - return res.status(404).json({ success: false, message: 'دسته‌بندی یافت نشد' }); - } - - return res.status(200).json({ success: true, data: category }); - } catch (error) { - next(error); - } -}; - - -module.exports = { - getSingleAdvertising, - getAdvertisings, - deleteAdvertisingCategory, - createAdvertisingCategory, - getAdvertisingCategories, - getAdvertisingCategoryById, - acceptAdvertising, - rejectAdvertising -} diff --git a/public/modstagram-back/controllers/panel/comments/advertisingCommentController.js b/public/modstagram-back/controllers/panel/comments/advertisingCommentController.js deleted file mode 100644 index f992c03..0000000 --- a/public/modstagram-back/controllers/panel/comments/advertisingCommentController.js +++ /dev/null @@ -1,195 +0,0 @@ -/* eslint-disable camelcase */ -const AdvertisingComment = require('../../../models/AdvertisingCommentModel') -const jMoment = require('moment-jalaali') -const mongoose = require('mongoose') -const AdvertisingModel = require('../../../models/AdvertisingModel') -const NotificationModel = require('../../../models/NotificationModel') - -// دریافت کامنت‌ها -const getAdvertisingComments = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const { - page = 1, limit = 10, - startDate, - endDate, - status - } = req.query - const filter = {} - - // Date - if (startDate || endDate) { - filter.createdAt = {} - - if (startDate) { - filter.createdAt.$gte = new Date(startDate) // تاریخ شروع - } - - if (endDate) { - filter.createdAt.$lte = new Date(endDate) // تاریخ پایان - } - } - - if (status) { - filter.status = status - } - const options = { - page: parseInt(page), - limit: parseInt(limit), - sort: { createdAt: -1 }, - populate: [ - { path: 'userId', select: 'user_name first_name last_name profile_image' }, - { path: 'advertisingId', select: 'title', populate: { path: 'creator_id', select: 'user_name first_name last_name' } } - // اضافه کردن اطلاعات سازنده - ] - } - - const comments = await AdvertisingComment.paginate(filter, options) - const commentList = comments.docs.map(comment => ({ - _id: comment._id, - createdAt: jMoment(comment.createdAt).format('jYYYY-jMM-jDD HH:mm'), - status: comment.status, - text: comment.text, - advertising: comment.advertisingId ? comment.advertisingId.title : null, - user: comment.userId ? { - _id: comment.userId._id, - user_name: comment.userId.user_name, - first_name: comment.userId.first_name, - last_name: comment.userId.last_name, - profile_image: comment.userId.profile_image - } : null, - creator: (comment.advertisingId && comment.advertisingId.creator_id) ? { - _id: comment.advertisingId.creator_id._id, - user_name: comment.advertisingId.creator_id.user_name, - first_name: comment.advertisingId.creator_id.first_name, - last_name: comment.advertisingId.creator_id.last_name - } : null - })); - - - res.status(200).json({ - comments: commentList, - totalPages: comments.totalPages, - totalItems: comments.totalDocs - }) - } catch (error) { - next(error) - } -} - -// دریافت جزئیات یک کامنت -const getAdvertisingCommentDetail = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const comment_id = req.query.comment_id - - if (!mongoose.Types.ObjectId.isValid(comment_id)) { - return res.status(400).json({ message: 'شناسه کامنت معتبر نیست' }) - } - - const comment = await AdvertisingComment.findById(comment_id) - .populate('userId', 'user_name first_name last_name profile_image') - .populate({ - path: 'advertisingId', - select: 'title creator_id', - populate: { - path: 'creator_id', - select: 'user_name first_name last_name' - } - }) - if (!comment) { - return res.status(404).json({ message: 'کامنت مورد نظر یافت نشد' }) - } - - const response = { - _id: comment._id, - text: comment.text, - createdAt: jMoment(comment.createdAt).format('jYYYY-jMM-jDD HH:mm'), - status: comment.status, - advertising: comment.advertisingId ? comment.advertisingId.title : null, - creator: { - _id: comment?.advertisingId?.creator_id._id, - user_name: comment?.advertisingId?.creator_id.user_name, - first_name: comment?.advertisingId?.creator_id.first_name, - last_name: comment?.advertisingId?.creator_id.last_name - }, - user: { - _id: comment.userId._id, - user_name: comment.userId.user_name, - first_name: comment.userId.first_name, - last_name: comment.userId.last_name, - profile_image: comment.userId.profile_image - } - } - - res.status(200).json({ comment: response }) - } catch (error) { - next(error) - } -} - -// تایید یک کامنت -const acceptAdvertisingComment = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const { id, status, text } = req.body - - if (!id || !status) { - return res.status(422).json({ - error: true, - message: 'اطلاعات ارسالی اشتباه است' - }) - } - - const comment = await AdvertisingComment.findById(id) - // افزایش تعداد کامنت‌های تبلیغ - await AdvertisingModel.findByIdAndUpdate(comment?.advertisingId, { $inc: { commentsCount: 1 } }) - if (!comment) { - return res.status(404).json({ - error: true, - message: 'کامنت مورد نظر یافت نشد' - }) - } - - if (text) { - comment.text = text - } - comment.status = status - await comment.save() - - if (status === 'accepted') { - const notification = new NotificationModel({ - user_id: comment?.userId, - project_post_id: comment?.advertisingId, - type: 'vitrine-comment', - title: 'انتشار نظر', - description: 'نظر شما منتشر شد.' - }) - await notification.save() - } else { - const notification = new NotificationModel({ - user_id: comment?.userId, - project_post_id: comment?.advertisingId, - type: 'vitrine-comment', - title: 'رد نظر', - description: 'نظر شما رد شد.' - }) - await notification.save() - } - res.status(201).json({ message: 'کامنت با موفقیت تایید شد' }) - } catch (error) { - next(error) - } -} - -module.exports = { - getAdvertisingComments, - getAdvertisingCommentDetail, - acceptAdvertisingComment -} diff --git a/public/modstagram-back/controllers/panel/comments/commentController.js b/public/modstagram-back/controllers/panel/comments/commentController.js deleted file mode 100644 index c0548e9..0000000 --- a/public/modstagram-back/controllers/panel/comments/commentController.js +++ /dev/null @@ -1,172 +0,0 @@ -/* eslint-disable camelcase */ -const CommentModel = require('../../../models/CommentModel') -const jMoment = require('moment-jalaali') -const { default: mongoose } = require('mongoose') - -// دریافت لیست کامنت‌ها با پیجینیشن -const getComments = async (req, res, next) => { - try { - console.log("gg6"); - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const { - page = 1, limit = 10, - startDate, - endDate, - status - } = req.query - const filter = {} // فیلتر بر اساس وضعیت کامنت - - // Date - if (startDate || endDate) { - filter.createdAt = {} - - if (startDate) { - filter.createdAt.$gte = new Date(startDate) // تاریخ شروع - } - - if (endDate) { - filter.createdAt.$lte = new Date(endDate) // تاریخ پایان - } - } - console.log("gg8"); - if (status) { - filter.status = status - } - const options = { - page: parseInt(page), // تبدیل صفحه به عدد صحیح - limit: parseInt(limit), // تبدیل محدودیت به عدد صحیح - sort: { createdAt: -1 }, - populate: [ - { path: 'creator', select: 'user_name first_name last_name profile_image ' }, - { path: 'user', select: 'user_name first_name last_name' }, - { path: 'project', select: 'title' } - ] - } - - const comments = await CommentModel.paginate(filter, options) - const commentList = comments.docs.map(comment => ({ - _id: comment._id, - createdAt: jMoment(comment.createdAt).format('jYYYY-jMM-jDD HH:mm'), - status: comment.status, - comment_for: comment.comment_for, - project: comment.project ? comment.project.title : null, - creator: comment.creator ? { - _id: comment.creator._id, - user_name: comment.creator.user_name, - first_name: comment.creator.first_name, - last_name: comment.creator.last_name, - profile_image: comment.creator.profile_image - } : null, - user: comment.user ? { - _id: comment.user._id, - user_name: comment.user.user_name, - first_name: comment.user.first_name, - last_name: comment.user.last_name - } : null - })); - - console.log("gg9"); - res.status(200).json({ - comments: commentList, - totalPages: comments.totalPages, - totalItems: comments.totalDocs - }) - } catch (error) { - console.log("gg"); - - next(error) - } -} - -// دریافت جزئیات یک کامنت -const getCommentDetail = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const comment_id = req.query.comment_id - - if (!mongoose.Types.ObjectId.isValid(comment_id)) { - return res.status(400).json({ message: 'شناسه کامنت معتبر نیست' }) - } - - const comment = await CommentModel.findById(comment_id) - .populate('creator', 'user_name first_name last_name profile_image ') - .populate('user', 'user_name first_name last_name') - .populate('project', 'title') - - if (!comment) { - return res.status(404).json({ message: 'کامنت مورد نظر یافت نشد' }) - } - - const response = { - _id: comment._id, - comment: comment.comment, - rating: comment.rating, - createdAt: jMoment(comment.createdAt).format('jYYYY-jMM-jDD HH:mm'), - status: comment.status, - comment_for: comment.comment_for, - project: comment.project ? comment.project.title : null, - creator: { - _id: comment.creator._id, - user_name: comment.creator.user_name, - first_name: comment.creator.first_name, - last_name: comment.creator.last_name, - profile_image: comment.creator.profile_image - }, - user: { - _id: comment.user._id, - user_name: comment.user.user_name, - first_name: comment.user.first_name, - last_name: comment.user.last_name - } - } - - res.status(200).json({ comment: response }) - } catch (error) { - next(error) - } -} - -// تایید یک کامنت -const acceptComment = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const { id, status, text } = req.body - - if (!id || !status) { - return res.status(422).json({ - error: true, - message: 'اطلاعات ارسالی اشتباه است' - }) - } - - const comment = await CommentModel.findById(id) - - if (!comment) { - return res.status(404).json({ - error: true, - message: 'کامنت مورد نظر یافت نشد' - }) - } - if (text) { - comment.comment = text - } - comment.status = status - await comment.save() - - res.status(201).json({ message: 'کامنت با موفقیت تایید شد' }) - } catch (error) { - next(error) - } -} - -module.exports = { - getComments, - getCommentDetail, - acceptComment -} diff --git a/public/modstagram-back/controllers/panel/expertise/expertiseController.js b/public/modstagram-back/controllers/panel/expertise/expertiseController.js deleted file mode 100644 index e1cf9b4..0000000 --- a/public/modstagram-back/controllers/panel/expertise/expertiseController.js +++ /dev/null @@ -1,111 +0,0 @@ -/* eslint-disable camelcase */ -const ExpertiseModel = require('../../../models/ExpertiseModel') - -const createExpertise = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const { expertise } = req.body - if (!expertise - ) { - return res.status(422).json({ - error: true, - message: 'اطلاعات ارسالی اشتباه است' - }) - } - // بررسی وجود تخصص با این نام در پایگاه داده - const existingExpertise = await ExpertiseModel.findOne({ expertise }) - - if (existingExpertise) { - return res.status(400).json({ message: 'تخصص با این نام قبلاً ثبت شده است' }) - } - - // ایجاد یک نمونه جدید از مدل ExpertiseModel - const newExpertise = new ExpertiseModel({ - expertise - }) - - // ذخیره تخصص جدید در پایگاه داده - await newExpertise.save() - - res.json({ message: 'تخصص با موفقیت اضافه شد' }) - } catch (error) { - next(error) - } -} - -const createSubExpertise = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const expertiseId = req.query.id - const { name } = req.body - if (!expertiseId || !name) { - return res.status(422).json({ - error: true, - message: 'اطلاعات ارسالی اشتباه است' - }) - } - // یافتن تخصص موردنظر از طریق آیدی - const expertise = await ExpertiseModel.findById(expertiseId) - - if (!expertise) { - return res.status(404).json({ message: 'تخصص موردنظر یافت نشد' }) - } - - // اضافه کردن زیرتخصص جدید به آرایه sub_expertise تخصص موجود - expertise.sub_expertise.push({ name }) - await expertise.save() - - res.json({ message: 'زیرتخصص با موفقیت به تخصص اضافه شد' }) - } catch (error) { - next(error) - } -} -const getExpertise = async (req, res, next) => { - try { - const expertises = await ExpertiseModel.find().select('expertise sub_expertise') - res.json({ expertises }) - } catch (error) { - next(error) - } -} - -// ویرایش تخصص -const editExpertise = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const { expertise } = req.body - const expertiseId = req.params.id - - if (!expertise || !expertiseId) { - return res.status(422).json({ message: 'اطلاعات ارسالی اشتباه است' }) - } - - const updatedExpertise = await ExpertiseModel.findByIdAndUpdate( - expertiseId, - { expertise }, - { new: true } - ) - - if (!updatedExpertise) { - return res.status(404).json({ message: 'تخصص یافت نشد' }) - } - - res.json({ message: 'تخصص با موفقیت ویرایش شد' }) - } catch (error) { - next(error) - } -} - -module.exports = { - createExpertise, - createSubExpertise, - getExpertise, - editExpertise - -} diff --git a/public/modstagram-back/controllers/panel/financial/financialController.js b/public/modstagram-back/controllers/panel/financial/financialController.js deleted file mode 100644 index c87c796..0000000 --- a/public/modstagram-back/controllers/panel/financial/financialController.js +++ /dev/null @@ -1,108 +0,0 @@ -/* eslint-disable camelcase */ -const { default: mongoose } = require('mongoose') -const PaymentModel = require('../../../models/PaymentModel') -const jMoment = require('moment-jalaali') - -const getFinancial = async (req, res) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const { - page = 1, limit = 10, - startDate, - endDate, - status - } = req.query - const filter = {} // افزودن شرط‌های دیگر برای فیلتر - - // Date - if (startDate || endDate) { - filter.createdAt = {} - - if (startDate) { - filter.createdAt.$gte = new Date(startDate) // تاریخ شروع - } - - if (endDate) { - filter.createdAt.$lte = new Date(endDate) // تاریخ پایان - } - } - - if (status) { - filter.status = status - } - - const options = { - page: parseInt(page), // تبدیل صفحه به عدد صحیح - limit: parseInt(limit), // تبدیل محدودیت به عدد صحیح - sort: { createdAt: -1 }, - populate: [ - { - path: 'user_id', - select: '_id user_name first_name mobile last_name ' - }, - { - path: 'project_id', - select: '_id title project_type' - } - ] - } - const financial = await PaymentModel.paginate( - filter, // فیلتر - options // گزینه‌های پیجینیشن - ) - const financialList = financial?.docs.map(financia => { - const jDate = jMoment(financia.createdAt).format('jYYYY-jMM-jDD HH:mm') - return { - ...financia._doc, - createdAt: jDate - } - }) - res.json({ - financials: financialList, - totalPages: financial.totalPages, // ارسال تعداد کل صفحات - totalItems: financial.totalDocs // ارسال تعداد کل آیتم‌ها - }) - } catch (error) { - console.error('Error occurred:', error) - res.status(500).json({ error: 'Internal server error' }) - } -} -const getFinancialDetail = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const financial_id = req.query.financial_id - if (!mongoose.Types.ObjectId.isValid(financial_id)) { - return res.status(400).json({ message: 'شناسه تراکنش معتبر نیست' }) - } - const financial = await PaymentModel.findById(financial_id).populate([ - { - path: 'user_id', - select: '_id user_name first_name mobile last_name shaba' - }, - { - path: 'project_id', - select: '_id title project_type', - populate: { - path: 'selected_user', - select: '_id user_name first_name mobile last_name shaba' - } - } - ]) - - if (!financial) { - return res.status(404).json({ message: 'تراکنش مورد نظر یافت نشد' }) - } - const newfinancial = { - ...financial._doc, - createdAt: jMoment(financial.createdAt).format('jYYYY-jMM-jDD HH:mm') - } - return res.status(200).json({ financial: newfinancial }) - } catch (error) { - console.error('Error occurred:', error) - res.status(500).json({ error: 'Internal server error' }) - } -} -module.exports = { getFinancial, getFinancialDetail } diff --git a/public/modstagram-back/controllers/panel/login/loginController.js b/public/modstagram-back/controllers/panel/login/loginController.js deleted file mode 100644 index 1b38717..0000000 --- a/public/modstagram-back/controllers/panel/login/loginController.js +++ /dev/null @@ -1,94 +0,0 @@ -/* eslint-disable camelcase */ -const AdminModel = require('../../../models/AdminModel') -const bcrypt = require('bcryptjs') -const TokenService = require('../../../services/TokenService') - -const adminLogin = async (req, res, next) => { - try { - // اعتبارسنجی ورودی ها - const { user_name, password } = req.body - if (!user_name || !password) { - return res.status(422).json({ - error: true, - message: 'اطلاعات ارسالی اشتباه است' - }) - } - // یافتن کاربر با نام کاربری - const userLow = user_name.toLowerCase() - const user = await AdminModel.findOne({ user_name: userLow }) - - if (!user) { - return res.status(404).json({ - error: true, - message: 'کاربری با این نام کاربری یافت نشد' - }) - } - if (!user.password) { - return res.status(422).json({ - error: true, - message: 'رمز عبور برای این کاربر تنظیم نشده است' - }) - } - const isPasswordValid = await bcrypt.compare(password, user.password) - if (!isPasswordValid) { - return res.status(422).json({ - error: true, - message: 'نام کاربری یا رمز عبور اشتباه است' - }) - } - - // اگر هم نام کاربری و هم رمز عبور درست بود، ارسال پیام موفقیت آمیز - const token = TokenService.sign({ id: user._id }) - return res.json({ - message: 'کد تایید صحیح بود', - token, - id: user._id - }) - } catch (error) { - next(error) - } -} -const changePassword = async (req, res, next) => { - try { - // اعتبارسنجی ورودی ها - const { user_name, password, new_password } = req.body - if (!user_name || !password || !new_password) { - return res.status(422).json({ - error: true, - message: 'اطلاعات ارسالی اشتباه است' - }) - } - // یافتن کاربر با نام کاربری - const userLow = user_name.toLowerCase() - const user = await AdminModel.findOne({ user_name: userLow }) - - if (!user) { - return res.status(404).json({ - error: true, - message: 'کاربری با این نام کاربری یا رمز عبور یافت نشد' - }) - } - const isPasswordValid = await bcrypt.compare(password, user.password) - if (!isPasswordValid) { - return res.status(422).json({ - error: true, - message: 'نام کاربری یا رمز عبور اشتباه است' - }) - } - - // هش کردن پسورد جدید و ذخیره در دیتابیس - const hashedPassword = await bcrypt.hash(new_password, 10) - user.password = hashedPassword - await user.save() - - return res.json({ - message: 'کلمه عبور با موفقیت ذخیره شد' - }) - } catch (error) { - next(error) - } -} - -module.exports = { - adminLogin, changePassword -} diff --git a/public/modstagram-back/controllers/panel/posts/postController.js b/public/modstagram-back/controllers/panel/posts/postController.js deleted file mode 100644 index 9f7ff85..0000000 --- a/public/modstagram-back/controllers/panel/posts/postController.js +++ /dev/null @@ -1,176 +0,0 @@ -/* eslint-disable camelcase */ -const NotificationModel = require('../../../models/NotificationModel') -const PostModel = require('../../../models/PostModel') -const UserModel = require('../../../models/UserModel') -const jMoment = require('moment-jalaali') -const { default: mongoose } = require('mongoose') - -const getPosts = async (req, res, next) => { - try { - const authHeader = req.header('Authorization'); - if (!authHeader || !authHeader.startsWith('Bearer ')) { - return res.status(401).json({ message: 'Access Denied: No token provided' }); - } - const token = authHeader.split(' ')[1]; - - const { - page = 1, - limit = 10, - startDate, - endDate, - status, - } = req.query; - - const filter = {}; - if (startDate || endDate) { - filter.createdAt = {}; - if (startDate) { - filter.createdAt.$gte = new Date(startDate); - } - if (endDate) { - filter.createdAt.$lte = new Date(endDate); - } - } - if (status) { - filter.status = status; - } - - const options = { - page: parseInt(page), - limit: parseInt(limit), - sort: { createdAt: -1 }, - populate: { - path: 'user_id', - select: '_id user_name first_name mobile last_name national_code user_type expertise', - }, - }; - - const posts = await PostModel.paginate(filter, options); - const postList = posts.docs.map((post) => ({ - _id: post._id, - post_image: post.post_images && post.post_images.length > 0 ? post.post_images[0] : post.post_video || null, // استفاده از اولین تصویر یا ویدئو - status: post.status, - post_images: post.post_images, - post_video: post.post_video, - type: post.type, - files: post.files, - user_id: post.user_id?._id || null, - user_name: post.user_id?.user_name || '-', - user_type: post.user_id?.user_type || '-', - expertise: post.user_id?.expertise || '-', - first_name: post.user_id?.first_name || '-', - last_name: post.user_id?.last_name || '-', - mobile: post.user_id?.mobile || '-', - national_code: post.user_id?.national_code || '-', - createdAt: post.createdAt ? jMoment(post.createdAt).format('jYYYY-jMM-jDD HH:mm') : '-', - })); - - res.status(200).json({ - posts: postList, - totalPages: posts.totalPages, - totalItems: posts.totalDocs, - }); - } catch (error) { - console.error('Error in getPosts:', error); - res.status(500).json({ message: 'خطا در دریافت پست‌ها.' }); - } -}; -const getPostDetail = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const post_id = req.query.post_id - // eslint-disable-next-line no-unused-vars - - if (!mongoose.Types.ObjectId.isValid(post_id)) { - return res.status(400).json({ message: 'شناسه پست معتبر نیست' }) - } - const post = await PostModel.findById(post_id).populate('user_id', '_id user_name first_name last_name profile_image user_level') - - if (!post) { - return res.status(404).json({ message: 'پست مورد نظر یافت نشد' }) - } - const response = { - _id: post._id, - post_image: post.post_images && post.post_images.length > 0 ? post.post_images[0] : post.post_video || null, // استفاده از اولین تصویر یا ویدئو - status: post.status, - caption: post.caption, - comments: post.comments, - post_images: post.post_images, - post_video: post.post_video, - type: post.type, - files: post.files, - user_id: post.user_id?._id || null, - user_name: post.user_id?.user_name || '-', - user_type: post.user_id?.user_type || '-', - expertise: post.user_id?.expertise || '-', - first_name: post.user_id?.first_name || '-', - last_name: post.user_id?.last_name || '-', - mobile: post.user_id?.mobile || '-', - national_code: post.user_id?.national_code || '-', - createdAt: post.createdAt ? jMoment(post.createdAt).format('jYYYY-jMM-jDD HH:mm') : '-', - } - return res.status(200).json({ post: response }) - } catch (error) { - next(error) - } -} - -const acceptPost = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const { id, user_id, status } = req.body - - if (!id || !user_id || !status) { - return res.status(422).json({ - error: true, - message: 'اطلاعات ارسالی اشتباه است' - }) - } - - const user = await UserModel.findById(user_id) - const post = await PostModel.findById(id) - - if (!post) { - return res.status(404).json({ - error: true, - message: 'پست مورد نظر یافت نشد' - }) - } - - post.status = status - await post.save() - if (status === 'accept') { - user.last_post = post - await user.save() - - const notification = new NotificationModel({ - user_id: user?._id, - project_post_id: post?._id, - type: 'accept-post', - title: 'انتشار پست', - description: 'پست شما مورد تایید قرار گرفت.' - }) - await notification.save() - } else { - const notification = new NotificationModel({ - user_id: user?._id, - project_post_id: post?._id, - type: 'reject-post', - title: 'رد پست', - description: 'پست شما مورد تایید قرار نگرفت.' - }) - await notification.save() - } - - res.status(201).json({ message: 'پست با موفقیت تایید شد' }) - } catch (error) { - next(error) - } -} - -module.exports = { - acceptPost, getPosts, getPostDetail -} diff --git a/public/modstagram-back/controllers/panel/projects/projectController.js b/public/modstagram-back/controllers/panel/projects/projectController.js deleted file mode 100644 index 6ae52a9..0000000 --- a/public/modstagram-back/controllers/panel/projects/projectController.js +++ /dev/null @@ -1,256 +0,0 @@ -/* eslint-disable camelcase */ -const ProjectModel = require('../../../models/ProjectModel') -const jMoment = require('moment-jalaali') -const RequestModel = require('../../../models/RequestModel') -const NotificationModel = require('../../../models/NotificationModel') - -const getProjects = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - // eslint-disable-next-line no-unused-vars - const { - page = 1, limit = 10, - startDate, - endDate, - status - } = req.query - // ساخت فیلتر برای استفاده در جستجوی MongoDB - const filter = { - } // افزودن شرط‌های دیگر برای فیلتر - // Date - if (startDate || endDate) { - filter.createdAt = {} - - if (startDate) { - filter.createdAt.$gte = new Date(startDate) // تاریخ شروع - } - - if (endDate) { - filter.createdAt.$lte = new Date(endDate) // تاریخ پایان - } - } - - if (status) { - filter.status = status - } - - // دریافت لیست پروژه‌ها با استفاده از فیلتر و گزینه‌های صفحه‌بندی - const options = { - page: parseInt(page), // تبدیل صفحه به عدد صحیح - limit: parseInt(limit), // تبدیل محدودیت به عدد صحیح - sort: { createdAt: -1 }, - populate: [ - { path: 'creator_id', select: '_id user_name first_name last_name' }, - { path: 'selected_user', select: '_id user_name first_name last_name' } - ] - } - const projects = await ProjectModel.paginate(filter, options) - const projectsList = projects.docs.map(project => ({ - _id: project._id, - title: project.title, - expertise: project.expertise, - sub_expertise: project.sub_expertise, - offer_time: project.offer_time, - offer_price: project.offer_price, - final_price: project.final_price, - final_time: project.final_time, - createdAt: jMoment(project.createdAt).format('jYYYY-jMM-jDD HH:mm'), - status: project.status, - creator: project.creator_id - ? { - _id: project.creator_id._id, - user_name: project.creator_id.user_name, - first_name: project.creator_id.first_name, - last_name: project.creator_id.last_name - } - : null, - selected_user: project.selected_user - ? { - _id: project.selected_user._id, - user_name: project.selected_user.user_name, - first_name: project.selected_user.first_name, - last_name: project.selected_user.last_name - } - : null - })) - - res.status(200).json({ - projects: projectsList, - totalPages: projects.totalPages, // ارسال تعداد کل صفحات - totalItems: projects.totalDocs // ارسال تعداد کل آیتم‌ها - }) - } catch (error) { - next(error) - } -} -const getProjectDetails = async (req, res, next) => { - try { - const { project_id } = req.query - - // بررسی وجود projectId - if (!project_id) { - return res.status(400).send('Project ID is required') - } - - // یافتن پروژه و جمع‌آوری اطلاعات مرتبط با سازنده و کاربر انتخاب شده - const project = await ProjectModel.findById(project_id) - .populate('creator_id', '_id user_name first_name last_name mobile') - .populate('selected_user', '_id user_name first_name last_name mobile') - .lean() - - // بررسی وجود پروژه - if (!project) { - return res.status(404).send('Project not found') - } - - // دریافت لیست درخواست‌های پروژه - const projectRequests = await RequestModel.find({ project: project_id }) - .populate('user', '_id first_name last_name user_name rate profile_image') - .sort({ status: 1 }) - .lean() - - // ساختاردهی پاسخ نهایی - const projectDetails = { - _id: project._id, - title: project.title, - description: project.description, - creator: project.creator_id - ? { - _id: project.creator_id._id, - first_name: project.creator_id.first_name, - last_name: project.creator_id.last_name, - user_name: project.creator_id.user_name, - mobile: project.creator_id.mobile - } - : null, - selected_user: project.selected_user - ? { - _id: project.selected_user._id, - first_name: project.selected_user.first_name, - last_name: project.creator_id.last_name, - user_name: project.selected_user.user_name, - mobile: project.selected_user.mobile - } - : null, - province: project.province, - city: project.city, - createdAt: jMoment(project.createdAt).format('jYYYY-jMM-jDD HH:mm'), - expertise: project.expertise, - sub_expertise: project.sub_expertise, - offer_time: project.offer_time, - offer_price: project.offer_price, - final_price: project.final_price, - final_time: project.final_time, - status: project.status, - reject_reason: project.reject_reason, - requested_users: projectRequests.map(request => ({ - _id: request.user._id, - first_name: request.user.first_name, - last_name: request.user.last_name, - user_name: request.user.user_name, - profile_image: request.user.profile_image, - time: request.time, - price: request.price - })) - } - - res.status(200).json({ project: projectDetails }) - } catch (error) { - next(error) - } -} -const acceptProject = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const { id, user_name } = req.body - - if (!id) { - return res.status(422).json({ - error: true, - message: 'اطلاعات ارسالی اشتباه است' - }) - } - - const project = await ProjectModel.findById(id) - - if (!project) { - return res.status(404).json({ - error: true, - message: 'پست مورد نظر یافت نشد' - }) - } - project.acceptedAt = new Date() - project.status = 'accepted' - await project.save() - const notification = new NotificationModel({ - user_id: project?.creator_id, - project_post_id: project?._id, - type: 'accept-project', - title: 'انتشار درخواست', - description: `درخواست شما با عنوان: ${project?.title} منتشر شد ` - }) - await notification.save() - if (project?.public_status === 'private' && project?.created_for_user) { - const notification = new NotificationModel({ - user_id: project?.created_for_user, - project_post_id: project?._id, - type: 'recive-project', - title: 'دعوت به همکاری', - description: `کاربر ${user_name} برای شما پروژه ایجاد کرده است ، برای نمایش جزئیات لمس کنید` - }) - await notification.save() - } - res.status(201).json({ message: 'پروژه با موفقیت تایید شد' }) - } catch (error) { - next(error) - } -} -const rejectProject = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const { id, rejectReason } = req.body - - if (!id) { - return res.status(422).json({ - error: true, - message: 'اطلاعات ارسالی اشتباه است' - }) - } - - const project = await ProjectModel.findById(id) - - if (!project) { - return res.status(404).json({ - error: true, - message: 'پست مورد نظر یافت نشد' - }) - } - - project.status = 'rejected' - project.reject_reason = rejectReason - await project.save() - const notification = new NotificationModel({ - user_id: project?.creator_id, - project_post_id: project?._id, - type: 'reject-project', - title: 'رد درخواست', - description: `درخواست شما با عنوان: ${project?.title} رد شد، برای دیدن علت رد، لمس کنید ` - }) - await notification.save() - res.status(201).json({ message: 'پروژه با موفقیت رد شد' }) - } catch (error) { - next(error) - } -} -module.exports = { - getProjects, - getProjectDetails, - acceptProject, - rejectProject -} diff --git a/public/modstagram-back/controllers/panel/projects/projectTypesController.js b/public/modstagram-back/controllers/panel/projects/projectTypesController.js deleted file mode 100644 index 5f50f47..0000000 --- a/public/modstagram-back/controllers/panel/projects/projectTypesController.js +++ /dev/null @@ -1,63 +0,0 @@ -const TypeAndPriceModel = require('../../../models/TypeAndPriceModel') -const jwt = require('jsonwebtoken') -const UserModel = require('../../../models/UserModel') - -const getProjectTypes = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const userId = decodedToken.id - - const user = await UserModel.findById(userId) - if (!user) { - return res.status(422).json({ - error: true, - message: 'کاربر یافت نشد' - }) - } - // درخواست انواع پروژه از دیتابیس - let projectTypes = await TypeAndPriceModel.find({}, 'name price') - - // بررسی برای مواردی مانند پیدا نشدن انواع پروژه - if (!projectTypes) { - return res.status(404).json({ message: 'انواع پروژه یافت نشد.' }) - } - // اگر کاربر درخواست رایگان روزانه نداشته باشد، نوع پروژه رایگان را حذف کنید - if (user.daily_free_request <= 0) { - projectTypes = projectTypes.filter(projectType => projectType.name !== 'free') - } - // ارسال انواع پروژه به کاربر - res.status(200).json({ projectTypes }) - } catch (error) { - // در صورت بروز خطا، ارسال پیام خطا به کاربر - console.error('Error in getProjectTypes:', error) - res.status(500).json({ message: 'خطا در دریافت انواع پروژه.' }) - } -} - -const createProjectTypes = async (req, res, next) => { - try { - const { name, price } = req.body - // بررسی اعتبار ورودی‌ها - if (!name || price == null || price === undefined) { - return res.status(400).json({ message: 'لطفا نام و قیمت پروژه را وارد کنید.' }) - } - - // ایجاد نوع پروژه جدید - const newType = new TypeAndPriceModel({ name, price }) - await newType.save() - - // ارسال پیام موفقیت آمیز به کاربر - res.status(201).json({ message: 'نوع پروژه جدید با موفقیت ایجاد شد.' }) - } catch (error) { - // در صورت بروز خطا، ارسال پیام خطا به کاربر - console.error('Error in createProjectTypes:', error) - res.status(500).json({ message: 'خطا در ایجاد نوع پروژه.' }) - } -} - -module.exports = { - getProjectTypes, - createProjectTypes -} diff --git a/public/modstagram-back/controllers/panel/settings/settingsController.js b/public/modstagram-back/controllers/panel/settings/settingsController.js deleted file mode 100644 index b6ee8bc..0000000 --- a/public/modstagram-back/controllers/panel/settings/settingsController.js +++ /dev/null @@ -1,36 +0,0 @@ -// controllers/settingController.js - -const SettingModel = require('../../../models/SettingsModel') - -// متد برای دریافت تنظیمات بر اساس key -const getSetting = async (req, res, next) => { - try { - const { key } = req.params - const setting = await SettingModel.findOne({ key }) - if (!setting) { - return res.status(404).json({ message: 'تنظیمات مورد نظر یافت نشد' }) - } - res.status(200).json(setting) - } catch (error) { - next(error) - } -} - -// متد برای به‌روزرسانی تنظیمات بر اساس key -const updateSetting = async (req, res, next) => { - try { - const { key } = req.params - const { value } = req.body - // eslint-disable-next-line no-unused-vars - const setting = await SettingModel.findOneAndUpdate( - { key }, - { value }, - { new: true, upsert: true } // اگر وجود نداشت، آن را ایجاد کن - ) - res.status(200).json({ message: 'تنظیمات با موفقیت بروز شد' }) - } catch (error) { - next(error) - } -} - -module.exports = { getSetting, updateSetting } diff --git a/public/modstagram-back/controllers/panel/shops/shopsController.js b/public/modstagram-back/controllers/panel/shops/shopsController.js deleted file mode 100644 index b9bb591..0000000 --- a/public/modstagram-back/controllers/panel/shops/shopsController.js +++ /dev/null @@ -1,161 +0,0 @@ -/* eslint-disable camelcase */ -const { default: mongoose } = require('mongoose') -const jMoment = require('moment-jalaali') -const AdvertisingProfileModel = require('../../../models/AdvertisingProfile') -const AdvertisingModel = require('../../../models/AdvertisingModel') - -const getShops = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - // eslint-disable-next-line no-unused-vars - const { page = 1, limit = 10, expertise, most_price, most_requests, age, gender } = req.query - const filter = {} // افزودن شرط‌های دیگر برای فیلتر - - // if (expertise) { - // filter.expertise = expertise - // } - // if (age) { - // filter.age = age - // } - // if (gender) { - // filter.gender = gender - // } - // استفاده از مدل پیجینیت شده برای دریافت نتایج صفحه‌بندی شده - const options = { - page: parseInt(page), // تبدیل صفحه به عدد صحیح - limit: parseInt(limit), // تبدیل محدودیت به عدد صحیح - sort: { createdAt: -1 }, - populate: [ - { path: 'user', select: '_id user_name first_name last_name' } - ] - } - const shops = await AdvertisingProfileModel.paginate(filter, options) - const newShops = shops.docs.map(user => ({ - _id: user._id, - user_name: user?.user?.user_name, - first_name: user?.user?.first_name, - last_name: user?.user?.last_name, - user_id: user?.user?._id, - profile_image: user.profile_image, - category: user.category, - vitrine_name: user.vitrine_name, - province: user.province, - city: user.city, - neighbourhood: user.neighbourhood, - createdAt: jMoment(user.createdAt).format('jYYYY-jMM-jDD HH:mm') - })) - res.status(200).json({ - shops: newShops, - totalPages: shops.totalPages, // ارسال تعداد کل صفحات - totalItems: shops.totalDocs // ارسال تعداد کل آیتم‌ها - }) - } catch (error) { - // در صورت بروز خطا، ارسال پیام خطا به کاربر - console.error('Error in getProjectTypes:', error) - res.status(500).json({ message: 'خطا در دریافت انواع پروژه.' }) - } -} -const getShopDetail = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const profile_id = req.query.profile_id - // eslint-disable-next-line no-unused-vars - // دریافت جزئیات فروشگاه با استفاده از profile_id - const shop = await AdvertisingProfileModel.findById(profile_id) - .populate('user', '_id user_name first_name last_name') - .exec() - const userAds = await AdvertisingModel.find({ creator_id: shop?.user }) - // جمع‌آوری اطلاعات از تبلیغات‌ها - let allImages = [] - let allServices = [] - let allFeatures = [] - for (const ad of userAds) { - allImages = allImages.concat(ad.images) - allServices = allServices.concat(ad.services) - allFeatures = allFeatures.concat(ad.features) - } - // حذف آیتم‌های null و تکراری از allFeatures - const uniqueFeatures = [] - const featureTitles = new Set() - for (const feature of allFeatures) { - if (feature && !featureTitles.has(feature.title)) { - uniqueFeatures.push(feature) - featureTitles.add(feature.title) - } - } - if (!shop) { - return res.status(404).json({ message: 'فروشگاه مورد نظر یافت نشد' }) - } - const response = { - _id: shop?._id, - user_name: shop?.user?.user_name, - first_name: shop?.user?.first_name, - last_name: shop?.user?.last_name, - user_id: shop?.user?._id, - profile_image: shop?.profile_image, - category: shop?.category, - vitrine_name: shop?.vitrine_name, - province: shop?.province, - city: shop?.city, - neighbourhood: shop?.neighbourhood, - contactInfo: shop?.contactInfo, - address: shop?.address, - allImages: allImages?.reverse(), - allServices, - allFeatures: uniqueFeatures, - about_us: shop?.about_us - // اطلاعات اضافی که بعداً به شما می‌گویم - } - return res.status(200).json({ shop: response }) - } catch (error) { - next(error) - } -} -const updateShop = async (req, res, next) => { - try { - const shopId = req.query.shopId // دریافت شناسه کاربر از درخواست - - // چک کردن اعتبار شناسه کاربر - if (!mongoose.Types.ObjectId.isValid(shopId)) { - return res.status(400).json({ message: 'شناسه کاربر معتبر نیست' }) - } - - // فیلدهایی که می‌خواهید آپدیت شوند را از درخواست دریافت کنید - const updateFields = req.body - - // اجرای آپدیت و بازگشت مقدار آپدیت شده - const updatedUser = await AdvertisingProfileModel.findByIdAndUpdate( - shopId, - updateFields, - { new: true } - ) - - // بررسی آیا کاربر وجود دارد یا نه - if (!updatedUser) { - return res.status(404).json({ message: 'کاربر مورد نظر یافت نشد' }) - } - - // ارسال پاسخ با مقادیر آپدیت شده - res.status(200).json({ message: 'کاربر با موفقیت ویرایش شد', id: updatedUser._id }) - } catch (error) { - const errors = [] - - if (error.code === 11000) { - // Duplicate key error - for (const key in error.keyValue) { - errors.push({ message: `ارور در فیلد ${key}` }) - } - } else { - errors.push({ message: 'خطا در آپدیت کاربر' }) - } - - res.status(500).json({ errors }) - } -} - -module.exports = { - getShops, getShopDetail, updateShop -} diff --git a/public/modstagram-back/controllers/panel/tickets/ticketsController.js b/public/modstagram-back/controllers/panel/tickets/ticketsController.js deleted file mode 100644 index 5a71ef2..0000000 --- a/public/modstagram-back/controllers/panel/tickets/ticketsController.js +++ /dev/null @@ -1,153 +0,0 @@ -const NotificationModel = require('../../../models/NotificationModel') -const TicketMessageModel = require('../../../models/TicketMessageModel') -const TicketModel = require('../../../models/TicketModel') -const jwt = require('jsonwebtoken') -const jMoment = require('moment-jalaali') - -const getAllTickets = async (req, res) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const { - page = 1, limit = 10, - startDate, - endDate, - status - } = req.query // افزودن پارامترهای صفحه‌بندی به درخواست - - const filter = {} // افزودن شرط‌های دیگر برای فیلتر - - // Date - if (startDate || endDate) { - filter.createdAt = {} - - if (startDate) { - filter.createdAt.$gte = new Date(startDate) // تاریخ شروع - } - - if (endDate) { - filter.createdAt.$lte = new Date(endDate) // تاریخ پایان - } - } - - if (status) { - filter.status = status - } - - const options = { - page: parseInt(page, 10) || 1, - limit: parseInt(limit, 10) || 10, - populate: [ - { path: 'user', select: '_id user_name first_name last_name mobile expertise' } - ], - sort: { updatedAt: -1 } - } - const tickets = await TicketModel.paginate(filter, options) - const ticketList = tickets?.docs.map(ticket => { - const jDate = jMoment(ticket.createdAt).format('jYYYY-jMM-jDD HH:mm') - return { - ...ticket._doc, - createdAt: jDate - } - }) - res.json({ - tickets: ticketList, - totalPages: tickets.totalPages, // ارسال تعداد کل صفحات - totalItems: tickets.totalDocs // ارسال تعداد کل آیتم‌ها - }) - } catch (error) { - res.status(500).json({ error: 'Internal Server Error' }) - } -} -const addAdminMessageToTicket = async (req, res) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - const adminId = decodedToken.id - - const { text, ticketId } = req.body - - const newMessage = new TicketMessageModel({ - text, - senderType: 'Admin', - senderId: adminId, - ticket: ticketId - }) - await newMessage.save() - - const ticket = await TicketModel.findById(ticketId) - if (!ticket) { - return res.status(404).json({ error: 'Ticket not found' }) - } - ticket.status = 'Answered' - ticket.new_message = true - await ticket.save() - const notification = new NotificationModel({ - user_id: ticket?.user, - project_post_id: ticket?._id, - type: 'ticket-message', - title: 'پاسخ پشتیبانی', - description: `پاسخ جدید در تیکت: ${ticket?.title}` - }) - await notification.save() - res.status(201).json(newMessage) - } catch (error) { - res.status(500).json({ error: 'Internal Server Error' }) - } -} -// senderId -const getTicketMessages = async (req, res) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const { ticketId } = req.query - const { page = 1, limit = 10 } = req.query - const options = { - page: parseInt(page) || 1, - limit: parseInt(limit) || 10, - populate: [ - { path: 'senderId', select: '_id user_name first_name last_name mobile expertise' } - ], - sort: { createdAt: -1 } - } - const messages = await TicketMessageModel.paginate({ ticket: ticketId }, options) - const messageList = messages?.docs.map(message => { - const jDate = jMoment(message.createdAt).format('jYYYY-jMM-jDD HH:mm') - return { - ...message._doc, - createdAt: jDate - } - }) - res.json({ - messages: messageList.reverse(), - totalPages: messages.totalPages, // ارسال تعداد کل صفحات - totalItems: messages.totalDocs // ارسال تعداد کل آیتم‌ها - }) - } catch (error) { - res.status(500).json({ error: 'Internal Server Error' }) - } -} -const closeTicket = async (req, res) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - - const { ticketId } = req.body - if (!ticketId) return res.status(400).send('Ticket ID is required') - - const ticket = await TicketModel.findById(ticketId) - if (!ticket) return res.status(404).send('Ticket not found') - - ticket.status = 'Closed' - await ticket.save() - - res.status(200).json({ message: 'Ticket has been closed successfully' }) - } catch (error) { - res.status(500).json({ error: 'Internal Server Error' }) - } -} - -module.exports = { getAllTickets, addAdminMessageToTicket, getTicketMessages, closeTicket } diff --git a/public/modstagram-back/controllers/panel/users/usersController.js b/public/modstagram-back/controllers/panel/users/usersController.js deleted file mode 100644 index f0c2761..0000000 --- a/public/modstagram-back/controllers/panel/users/usersController.js +++ /dev/null @@ -1,410 +0,0 @@ -/* eslint-disable no-unused-vars */ -/* eslint-disable camelcase */ -const { default: mongoose } = require('mongoose') -const UserModel = require('../../../models/UserModel') -const jMoment = require('moment-jalaali') -const NotificationModel = require('../../../models/NotificationModel') -const { default: axios } = require('axios') - -const getUsers = async (req, res, next) => { - try { - // بررسی توکن - const token = req.header('Authorization')?.split(' ')[1]; - if (!token) return res.status(401).send('Access Denied'); - - // پارامترهای query - const { - page = 1, - limit = 20, - expertise, - most_price, - most_requests, - age, - gender, - startDate, - endDate, - status, - search - } = req.query; - - const filter = {}; // شرط‌های فیلتر - - // فیلتر تاریخ - if (startDate || endDate) { - filter.createdAt = {}; - if (startDate) filter.createdAt.$gte = new Date(startDate); - if (endDate) filter.createdAt.$lte = new Date(endDate); - } - - // فیلتر وضعیت - if (status) { - filter.is_verified = status; - } - - // فیلتر سرچ - if (search) { - const regex = new RegExp(search, "i"); // i = ignore case - filter.$or = [ - { first_name: regex }, - { last_name: regex }, - { user_name: regex }, - { mobile: regex } - ]; - } - - // فیلترهای دیگر (اختیاری) - if (expertise) filter.expertise = expertise; - if (age) filter.age = age; - if (gender) filter.gender = gender; - - // گزینه‌های صفحه‌بندی - const options = { - page: parseInt(page), - limit: parseInt(limit), - sort: { createdAt: -1 } - }; - - // گرفتن کاربران با paginate - const users = await UserModel.paginate(filter, options); - - // آماده‌سازی خروجی - const newUsers = users.docs.map(user => ({ - _id: user._id, - mobile: user.mobile, - user_name: user.user_name, - first_name: user.first_name, - last_name: user.last_name, - user_type: user.user_type, - is_verified: user.is_verified, - profile_image: user.profile_image, - expertise: user.expertise, - sub_expertise: user.sub_expertise, - gender: user.gender, - national_code: user.national_code, - province: user.province, - city: user.city, - last_online: jMoment(user.last_online).format('jYYYY-jMM-jDD HH:mm'), - createdAt: jMoment(user.createdAt).format('jYYYY-jMM-jDD HH:mm'), - block_status: user.block_status - })); - - res.status(200).json({ - users: newUsers, - totalPages: users.totalPages, - totalItems: users.totalDocs - }); - } catch (error) { - console.error('Error in getUsers:', error); - res.status(500).json({ message: 'خطا در دریافت کاربران.' }); - } -}; - - - -// const getUsers = async (req, res, next) => { -// try { -// const token = req.header('Authorization').split(' ')[1] -// if (!token) return res.status(401).send('Access Denied') - -// // eslint-disable-next-line no-unused-vars -// const { -// page = 1, -// limit = 10, -// expertise, -// most_price, -// most_requests, -// age, -// gender, -// startDate, -// endDate, -// status -// } = req.query -// const filter = {} // افزودن شرط‌های دیگر برای فیلتر - -// // Date -// if (startDate || endDate) { -// filter.createdAt = {} - -// if (startDate) { -// filter.createdAt.$gte = new Date(startDate) // تاریخ شروع -// } - -// if (endDate) { -// filter.createdAt.$lte = new Date(endDate) // تاریخ پایان -// } -// } - -// if (status) { -// filter.is_verified = status -// } - -// // if (expertise) { -// // filter.expertise = expertise -// // } -// // if (age) { -// // filter.age = age -// // } -// // if (gender) { -// // filter.gender = gender -// // } -// // استفاده از مدل پیجینیت شده برای دریافت نتایج صفحه‌بندی شده -// const options = { -// page: parseInt(page), // تبدیل صفحه به عدد صحیح -// limit: parseInt(limit), // تبدیل محدودیت به عدد صحیح -// sort: { createdAt: -1 } -// } -// const users = await UserModel.paginate(filter, options) -// const newUsers = users.docs.map(user => ({ -// _id: user._id, -// mobile: user.mobile, -// user_name: user.user_name, -// first_name: user.first_name, -// last_name: user.last_name, -// user_type: user.user_type, -// is_verified: user.is_verified, -// profile_image: user.profile_image, -// expertise: user.expertise, -// sub_expertise: user.sub_expertise, -// gender: user.gender, -// national_code: user.national_code, -// province: user.province, -// city: user.city, -// last_online: jMoment(user.last_online).format('jYYYY-jMM-jDD HH:mm'), -// createdAt: jMoment(user.createdAt).format('jYYYY-jMM-jDD HH:mm'), -// block_status: user.block_status -// })) -// res.status(200).json({ -// users: newUsers, -// totalPages: users.totalPages, // ارسال تعداد کل صفحات -// totalItems: users.totalDocs // ارسال تعداد کل آیتم‌ها -// }) -// } catch (error) { -// // در صورت بروز خطا، ارسال پیام خطا به کاربر -// console.error('Error in getProjectTypes:', error) -// res.status(500).json({ message: 'خطا در دریافت انواع پروژه.' }) -// } -// } -const getUserDetail = async (req, res, next) => { - try { - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const user_id = req.query.user_id - // eslint-disable-next-line no-unused-vars - - if (!mongoose.Types.ObjectId.isValid(user_id)) { - return res.status(400).json({ message: 'شناسه کاربر معتبر نیست' }) - } - const user = await UserModel.findById(user_id) - - if (!user) { - return res.status(404).json({ message: 'کاربر مورد نظر یافت نشد' }) - } - - const response = { - _id: user?._id, - profile_image: user?.profile_image, - first_name: user?.first_name, - last_name: user?.last_name, - user_name: user?.user_name, - mobile: user?.mobile, - national_code: user?.national_code, - province: user?.province, - city: user?.city, - address: user?.address, - height: user?.height, - weight: user?.weight, - size: user?.size, - birthday: user?.birthday, - show_location: user?.show_location, - cooperation_abroad: user?.cooperation_abroad, - conversation_projects: user?.conversation_projects, - expertise: user?.expertise, - sub_expertise: user?.sub_expertise, - shaba: user?.shaba, - national_card_image: user?.national_card_image, - last_online: jMoment(user?.last_online).format('jYYYY-jMM-jDD HH:mm'), - createdAt: jMoment(user?.createdAt).format('jYYYY-jMM-jDD HH:mm'), - block_status: user?.block_status, - user_level: user?.user_level, - user_type: user?.user_type, - user_score: user?.user_score, - services :user?.services, - is_verified: user?.is_verified, - rate: user?.rate, - bio: user?.bio, - eye_color: user?.eye_color, - hair_color: user?.hair_color, - lat: user?.lat, - lng: user?.lng - } - return res.status(200).json({ user: response }) - } catch (error) { - next(error) - } -} -const updateUser = async (req, res, next) => { - try { - const userId = req.query.userId // دریافت شناسه کاربر از درخواست - - // چک کردن اعتبار شناسه کاربر - if (!mongoose.Types.ObjectId.isValid(userId)) { - return res.status(400).json({ message: 'شناسه کاربر معتبر نیست' }) - } - - // فیلدهایی که می‌خواهید آپدیت شوند را از درخواست دریافت کنید - const updateFields = req.body - - // اجرای آپدیت و بازگشت مقدار آپدیت شده - const updatedUser = await UserModel.findByIdAndUpdate( - userId, - updateFields, - { new: true } - ) - - // بررسی آیا کاربر وجود دارد یا نه - if (!updatedUser) { - return res.status(404).json({ message: 'کاربر مورد نظر یافت نشد' }) - } - - // ارسال پاسخ با مقادیر آپدیت شده - res.status(200).json({ message: 'کاربر با موفقیت ویرایش شد', id: updatedUser._id }) - } catch (error) { - const errors = [] - - if (error.code === 11000) { - // Duplicate key error - for (const key in error.keyValue) { - errors.push({ message: `ارور در فیلد ${key}` }) - } - } else { - errors.push({ message: 'خطا در آپدیت کاربر' }) - } - - res.status(500).json({ errors }) - } -} -const verifyUser = async (req, res, next) => { - try { - const userId = req.query.userId // دریافت شناسه کاربر از درخواست - const user = await UserModel.findById(userId) - if (!user) { - return res.status(404).json({ message: 'کاربر مورد نظر یافت نشد' }) - } - user.is_verified = 'verified'; - user.is_Register = true; - await user.save(); - - - const notification = new NotificationModel({ - user_id: userId, - type: 'verify', - title: 'تایید مدارک', - description: 'مدارک ارسالی شما با موفقیت تایید شد' - }) - await notification.save() - - // Sms - - const userReciver = await UserModel.findById(userId) - - const data = JSON.stringify({ - mobile: userReciver?.mobile, - templateId: '632057', - parameters: [ - { name: 'USERS', value: userReciver?.first_name + ' ' + userReciver?.last_name } - ] - }) - - const config = { - method: 'post', - url: 'https://api.sms.ir/v1/send/verify', - headers: { - 'Content-Type': 'application/json', - Accept: 'text/plain', - 'x-api-key': '2JKxGbTzE64t0YTkjip6RYHnm9mq1haMlidF8WWwQunwubHFVW6iaMmfFQbMXEDt' - }, - data - } - axios(config) - .then(function (response) { - }) - .catch(function (error) { - console.log(error) - }) - - // End Sms - - // ارسال پاسخ با مقادیر آپدیت شده - res.status(200).json({ message: 'مدارک کاربر با موفقیت تایید شد' }) - } catch (error) { - next(error) - } -} - -const updateUserStatus = async (req, res, next) => { - try { - const { userId, block_status } = req.body; - - - if (!mongoose.Types.ObjectId.isValid(userId)) { - return res.status(400).json({ message: 'شناسه کاربر معتبر نیست' }); - } - - const user = await UserModel.findByIdAndUpdate( - userId, - { block_status }, - { new: true } - ); - - if (!user) return res.status(404).json({ message: 'کاربر یافت نشد' }); - - res.status(200).json({ message: 'وضعیت کاربر با موفقیت تغییر کرد', block_status: user.block_status }); - } catch (error) { - console.error(error); - res.status(500).json({ message: 'خطای سرور' }); - } -}; - -const rejectUser = async (req, res, next) => { - try { - const userId = req.query.userId // دریافت شناسه کاربر از درخواست - const user = await UserModel.findById(userId) - if (!user) { - return res.status(404).json({ message: 'کاربر مورد نظر یافت نشد' }) - } - user.is_verified = 'rejected' - user.is_Register = false - await user.save() - const notification = new NotificationModel({ - user_id: userId, - type: 'reject-user', - title: 'رد مدارک', - description: 'مدارک ارسالی شما رد شد، برای اطلاعات بیشتر از بخش تیکت به پشتیبانی پیام دهید.' - }) - await notification.save() - - // ارسال پاسخ با مقادیر آپدیت شده - res.status(200).json({ message: 'مدارک کاربر با موفقیت رد شد' }) - } catch (error) { - next(error) - } -} -const changePass = async (req, res, next) => { - try { - const { userId, password } = req.body; - const user = await UserModel.findById(userId) - if (!user) { - return res.status(404).json({ message: 'کاربر مورد نظر یافت نشد' }) - } - user.password = password - await user.save() - - // ارسال پاسخ با مقادیر آپدیت شده - res.status(200).json({ message: 'رمز عبور با موفقیت تغییر کرد' }); - } catch (error) { - next(error) - } -} -module.exports = { - getUsers, getUserDetail, updateUser, verifyUser, rejectUser, updateUserStatus, changePass -} diff --git a/public/modstagram-back/controllers/panel/version/versionController.js b/public/modstagram-back/controllers/panel/version/versionController.js deleted file mode 100644 index fca01d6..0000000 --- a/public/modstagram-back/controllers/panel/version/versionController.js +++ /dev/null @@ -1,37 +0,0 @@ -const VersionModel = require('../../../models/VersionModel') - -// Endpoint برای دریافت نسخه فعلی -const getVersion = async (req, res, next) => { - try { - const currentVersion = await VersionModel.findOne().sort({ _id: -1 }).exec() - if (!currentVersion) { - return res.status(200).json({ message: 'نسخه‌ای پیدا نشد' }) - } - res.json(currentVersion) - } catch (error) { - res.status(500).json({ message: 'خطای سرور', error }) - } -} -// متد برای ایجاد یا ویرایش نسخه -const upsertVersion = async (req, res, next) => { - try { - const { version, mandatory, releaseNotes, updateUrls } = req.body - - if (!version || !Array.isArray(updateUrls) || updateUrls.length === 0) { - return res.status(400).json({ message: 'اطلاعات ناقص است' }) - } - - // پیدا کردن نسخه‌ای که مشابه باشد و ویرایش یا ایجاد - const updatedVersion = await VersionModel.findOneAndUpdate( - { version }, // شرط برای پیدا کردن نسخه با همین شماره - { mandatory, releaseNotes, updateUrls }, // به‌روزرسانی مقادیر - { new: true, upsert: true } // ایجاد نسخه جدید اگر وجود ندارد - ) - - res.status(200).json({ message: 'نسخه به‌روزرسانی شد', version: updatedVersion }) - } catch (error) { - res.status(500).json({ message: 'خطای سرور', error }) - } -} - -module.exports = { getVersion, upsertVersion } diff --git a/public/modstagram-back/helpers/chatHelpers.js b/public/modstagram-back/helpers/chatHelpers.js deleted file mode 100644 index a22af9f..0000000 --- a/public/modstagram-back/helpers/chatHelpers.js +++ /dev/null @@ -1,72 +0,0 @@ -const moment = require('moment-jalaali') -const MessageModel = require('../models/MessageModel') -const UserModel = require('../models/UserModel') - -function formatTimeOnly(date) { - return moment(date).locale('fa').format('HH:mm:ss') -} - -async function enrichMessage(message) { - const doc = message._doc ? { ...message._doc } : { ...message } - let replyTo = null - - if (doc.replyToId) { - const parent = await MessageModel.findById(doc.replyToId).lean() - if (parent) { - const parentUser = - String(parent.senderId) === String(doc.senderId) - ? await UserModel.findById(doc.senderId).select('first_name last_name user_name').lean() - : await UserModel.findById(parent.senderId).select('first_name last_name user_name').lean() - replyTo = { - _id: parent._id, - content: (parent.content || 'پیام').slice(0, 200), - senderName: parentUser - ? `${parentUser.first_name || ''} ${parentUser.last_name || ''}`.trim() || parentUser.user_name - : 'کاربر' - } - } - } - - return { - ...doc, - createdAt: formatTimeOnly(doc.createdAt), - replyTo, - forwardedFrom: doc.forwardedFrom || undefined - } -} - -function emitChatEvents(io, message, senderId, receiverId) { - const payload = message - const roomA = `chat:${senderId}:${receiverId}` - const roomB = `chat:${receiverId}:${senderId}` - io.to(roomA).to(roomB).emit('newMessage', payload) - io.to(`user:${senderId}`).to(`user:${receiverId}`).emit('chatListUpdate', { - senderId, - receiverId, - message: payload - }) -} - -function parseForwardedContent(content) { - if (!content) return { body: '', forwardedFrom: null } - try { - const line = content.split('\n')[0] - const j = JSON.parse(line) - if (j.forwardedFrom) { - return { - forwardedFrom: j.forwardedFrom, - body: content.replace(/^\{.*\}\n?/, '').trim() - } - } - } catch (_) { - /* not json */ - } - return { body: content, forwardedFrom: null } -} - -module.exports = { - formatTimeOnly, - enrichMessage, - emitChatEvents, - parseForwardedContent -} diff --git a/public/modstagram-back/index.js b/public/modstagram-back/index.js deleted file mode 100644 index 67ae759..0000000 --- a/public/modstagram-back/index.js +++ /dev/null @@ -1,357 +0,0 @@ -const express = require('express'); -const app = express(); -const path = require('path'); -const http = require('http').createServer(app); -const cors = require('cors'); -const moment = require('moment-jalaali'); -const MessageModel = require('./models/MessageModel'); -const fs = require('fs-extra'); -const cron = require('node-cron'); -const UserModel = require('./models/UserModel'); -const blockCheck = require('./middlewares/blockCheck'); -const rateLimit = require('express-rate-limit'); -const { default: axios } = require('axios'); - -const allowedOrigins = [ - 'http://localhost:3000', - 'http://localhost:3001', // اضافه شد — مهم برای توسعه فرانت - 'http://localhost:3002', - 'http://localhost:3003', - 'http://localhost', - 'https://modstagram.com', - 'https://www.modstagram.com', - 'https://api.modstagram.com', - 'https://panel.modstagram.com', - 'https://www.panel.modstagram.com', - 'https://panel.modstagram.ir', - 'https://www.panel.modstagram.ir', - 'ionic://localhost', - 'capacitor://localhost', - // IPهای محلی (برای تست در شبکه داخلی) - /^http:\/\/192\.168\.\d{1,3}\.\d{1,3}:\d+$/, - /^http:\/\/10\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d+$/, -]; - -app.use(cors({ - origin: (origin, callback) => { - // در محیط توسعه، همه originها مجاز باشن - if (process.env.NODE_ENV !== 'production') { - return callback(null, true); - } - - // اگر origin وجود نداشته باشه (مثل درخواست از موبایل یا Postman) اجازه بده - if (!origin) { - return callback(null, true); - } - - // چک لیست یا RegExp - const isAllowed = allowedOrigins.some(item => { - if (typeof item === 'string') return item === origin; - if (item instanceof RegExp) return item.test(origin); - return false; - }); - - if (isAllowed) { - callback(null, true); - } else { - callback(new Error('Not allowed by CORS')); - } - }, - methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'], - allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With', 'x-no-toast'], - credentials: true, - optionsSuccessStatus: 200 // برای مرورگرهای قدیمی -})); - -// Socket.IO CORS -const io = require('socket.io')(http, { - cors: { - origin: (origin, callback) => { - if (process.env.NODE_ENV !== 'production') { - return callback(null, true); - } - - if (!origin) { - return callback(null, true); - } - - const isAllowed = allowedOrigins.some(item => { - if (typeof item === 'string') return item === origin; - if (item instanceof RegExp) return item.test(origin); - return false; - }); - - if (isAllowed) { - callback(null, true); - } else { - callback(new Error('Not allowed by CORS')); - } - }, - methods: ['GET', 'POST', 'PATCH', 'PUT', 'DELETE', 'OPTIONS'], - credentials: true - } -}); - -// افزایش limit برای Base64 (1000mb کافیه) -app.use(express.json({ limit: '1000mb' })); -app.use(express.urlencoded({ limit: '1000mb', extended: true })); - -app.use('/storage', express.static(path.join(__dirname, 'storage'))); -app.use('/storage/profiles', express.static(path.join(__dirname, '../storage/profiles'))); -app.use('/storage/carts', express.static(path.join(__dirname, '../storage/carts'))); -app.use('/storage/posts', express.static(path.join(__dirname, '../storage/posts'))); -app.use('/storage/messages', express.static(path.join(__dirname, '../storage/messages'))); -app.use('/storage/tickets', express.static(path.join(__dirname, '../storage/tickets'))); -app.use('/storage/advertising', express.static(path.join(__dirname, '../storage/advertising'))); -app.use('/storage/services', express.static(path.join(__dirname, '../storage/services'))); - -require('./boot'); - -// غیرفعال کردن پارس‌کننده‌های بدنه برای روت‌های آپلود فایل -app.use((req, res, next) => { - if (req.path === '/api/v1/posts/create' && req.method === 'POST') { - console.log('DEBUG: Skipping body parsers for /api/v1/posts/create'); - return next(); - } - express.json()(req, res, next); -}); -app.use((req, res, next) => { - if (req.path === '/api/v1/posts/create' && req.method === 'POST') { - return next(); - } - express.urlencoded({ extended: true })(req, res, next); -}); - -require('./middlewares')(app); - -const limiter = rateLimit({ - windowMs: 3 * 60 * 1000, - max: 3000, - standardHeaders: true, - legacyHeaders: false, - message: 'تعداد درخواست‌های شما بیشتر از حد مجاز است، لطفاً بعداً دوباره تلاش کنید.', - handler: (req, res) => { - const retryAfter = Math.ceil((req.rateLimit.resetTime - Date.now()) / 1000); - res.set('Retry-After', retryAfter); - res.status(429).json({ - error: `شما بیش از حد مجاز درخواست ارسال کرده‌اید. لطفاً بعد از ${retryAfter} ثانیه دوباره تلاش کنید.` - }); - } -}); -app.use(limiter); -app.set('trust proxy', 'loopback'); - -require('./routes')(app); - -const { enrichMessage, emitChatEvents, parseForwardedContent } = require('./helpers/chatHelpers') - -app.get('/api/v1/chat', async (req, res) => { - try { - const { senderId, receiverId, limit, page } = req.query - const pageNumber = parseInt(page) || 1 - const limitPerPage = parseInt(limit) || 40 - - const filter = { - $or: [ - { senderId, receiverId }, - { senderId: receiverId, receiverId: senderId } - ] - } - - const totalMessagesCount = await MessageModel.countDocuments(filter) - const totalPages = Math.ceil(totalMessagesCount / limitPerPage) || 1 - const skip = (pageNumber - 1) * limitPerPage - - const messages = await MessageModel.find(filter) - .sort({ createdAt: -1 }) - .skip(skip) - .limit(limitPerPage) - - await MessageModel.updateMany( - { _id: { $in: messages.map((m) => m._id) }, receiverId: senderId }, - { $set: { readStatus: 1 } } - ) - - const enriched = await Promise.all(messages.map((m) => enrichMessage(m))) - res.json({ messages: enriched.reverse(), totalPages }) - } catch (error) { - console.error('Error fetching messages:', error) - res.status(500).json({ error: 'Server error' }) - } -}) - -app.post('/api/v1/chat', [blockCheck], async (req, res) => { - try { - const { senderId, receiverId, content, replyToId, forwardedFrom: fwdBody } = req.body - const { body, forwardedFrom: fwdParsed } = parseForwardedContent(content) - - const payload = { - senderId, - receiverId, - content: body || content, - replyToId: replyToId || undefined, - forwardedFrom: fwdBody || fwdParsed || undefined - } - - const newMessage = new MessageModel(payload) - await newMessage.save() - const formatted = await enrichMessage(newMessage) - - res.status(201).json({ data: formatted }) - emitChatEvents(io, formatted, senderId, receiverId) - } catch (error) { - console.error('Error sending message:', error) - res.status(500).json({ error: 'Server error' }) - } -}) -app.get('/api/v1/chat/read', async (req, res) => { - try { - const { senderId, receiverId } = req.query // شناسه فرستنده و گیرنده از درخواست دریافت شود - // پیدا کردن تمام پیام‌هایی که کاربر دوم مشاهده کرده است و کاربر اول آنها را ارسال کرده است - const messages = await MessageModel.find( - { senderId: receiverId, receiverId: senderId } // برای مواقعی که شناسه‌ها معکوس باشند - ) - // به روزرسانی وضعیت خوانده شده یا نشده بودن پیام‌ها به "خوانده شده" - await MessageModel.updateMany({ _id: { $in: messages.map(message => message._id) } }, { $set: { readStatus: 1 } }) - res.status(200).json({ message: 'Message read status updated successfully' }) - } catch (error) { - console.error('Error updating message read status:', error) - res.status(500).json({ error: 'Server error' }) - } -}) - -app.post("/api/v1/notification/send-sms", async (req, res) => { - const { receiverId, message } = req.body; - const user = await UserModel.findById(receiverId); - if (!user || !user.mobile) return res.status(404).json({ error: "User not found" }); - console.log("3"); - - const mobile = user.mobile - const user_name = user.user_name - const data = JSON.stringify({ - mobile, - templateId: '876533', - parameters: [ - { name: 'USER', value: user_name } - ] - }) - - const config = { - method: 'post', - url: 'https://api.sms.ir/v1/send/verify', - headers: { - 'Content-Type': 'application/json', - Accept: 'text/plain', - 'x-api-key': '2JKxGbTzE64t0YTkjip6RYHnm9mq1haMlidF8WWwQunwubHFVW6iaMmfFQbMXEDt' - }, - data - } - - axios(config) - .then(function (response) { - console.log(response); - - }) - .catch(function (error) { - console.log(error) - }) - - res.status(200).json({ success: true }); -}); - -app.post('/api/v1/chat/file', [blockCheck], async (req, res) => { - try { - const { senderId, receiverId, content, replyToId, fileType } = req.body - const { file } = req.files - let fileUrl = null - if (file) { - const uploadDir = path.join(__dirname, '../storage/messages') - if (!fs.existsSync(uploadDir)) { - fs.mkdirSync(uploadDir, { recursive: true }) - } - const uniqueFileName = `${Date.now()}-${file.name}` - const filePath = path.join(uploadDir, uniqueFileName) - await fs.move(file.path, filePath) - fileUrl = `/messages/${uniqueFileName}` - } - - const newMessage = new MessageModel({ - senderId, - receiverId, - content: content || '', - file: fileUrl, - fileType: fileType || undefined, - replyToId: replyToId || undefined - }) - await newMessage.save() - const formatted = await enrichMessage(newMessage) - - res.status(201).json({ data: formatted }) - emitChatEvents(io, formatted, senderId, receiverId) - } catch (error) { - console.error('Error sending message:', error) - res.status(500).json({ error: 'Server error' }) - } -}) -// Errors -require('./middlewares/exception')(app) -require('./middlewares/404')(app) -io.on('connection', (socket) => { - socket.on('joinUser', ({ userId }) => { - if (userId) socket.join(`user:${userId}`) - }) - - socket.on('joinChat', ({ userId, receiverId }) => { - if (userId && receiverId) { - socket.join(`chat:${userId}:${receiverId}`) - socket.join(`chat:${receiverId}:${userId}`) - } - }) - - socket.on('typing', ({ senderId, receiverId }) => { - io.to(`chat:${receiverId}:${senderId}`).emit('userTyping', { userId: senderId }) - }) - - socket.on('stopTyping', ({ senderId, receiverId }) => { - io.to(`chat:${receiverId}:${senderId}`).emit('userStoppedTyping', { userId: senderId }) - }) - - socket.on('messageSeen', async ({ messageId, senderId, receiverId }) => { - try { - if (messageId) { - await MessageModel.findByIdAndUpdate(messageId, { readStatus: 1 }) - io.to(`chat:${receiverId}:${senderId}`).emit('messageStatusUpdate', { - messageId, - status: 'seen' - }) - } - } catch (e) { - console.error('messageSeen error', e) - } - }) -}) - -// Free Project -require('./services/AdvertisingCron') -require('./services/ProjectCron') -cron.schedule('0 0 1 * *', async () => { - try { - await UserModel.updateMany({}, { - daily_free_request: 1, - last_free_request_date: new Date(), - monthly_free_offer: 1, - last_free_offer_date: new Date() - }) - console.log('Monthly free requests reset for all users.') - } catch (error) { - console.error('Error resetting daily free requests:', error) - } -}, { - scheduled: true, - timezone: 'Asia/Tehran' -}) -module.exports = (port) => { - http.listen(port, () => { - console.log(`HTTP server is running on port ${port}`) - }) -} diff --git a/public/modstagram-back/liara.json b/public/modstagram-back/liara.json deleted file mode 100644 index 110cccc..0000000 --- a/public/modstagram-back/liara.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "disks": [{ "name": "public", "mountTo": "/storage" }] -} diff --git a/public/modstagram-back/logs/sms-irs/13-03-2024.log b/public/modstagram-back/logs/sms-irs/13-03-2024.log deleted file mode 100644 index 16b1f43..0000000 --- a/public/modstagram-back/logs/sms-irs/13-03-2024.log +++ /dev/null @@ -1,18 +0,0 @@ -[Wed Mar 13 00:31:27 2024] [Token] {"TokenKey":"OVlma3FmZmJOTjNoY1A3bmxRbE5odHBHTTNZbGpjcGxvcVVJTmZIMDFHdjkvWDNYaG55WlB0cXNpaWRmclVCeHlXNFVrd2xxZThZQktIVEdGak9Xd29QTGNhMWtpYXlWUmwwNXcvZUdxQjhmbHFyenpPNVlDVk9ZbGZsUmplQ3NjUHdHNE5ma0hGdHpQV040MkV0OUx0M285SkdBcGp6OFA5SGpoNHZHUzFEajkwc0ZWQWRWSlNBNFlOMWxxOC9k","IsSuccessful":true,"Message":" درخواست Token با موفقیت انجام شد"} -[Wed Mar 13 00:31:27 2024] [VerificationCode] {"VerificationCodeId":634458365,"IsSuccessful":true,"Message":"your verification code is sent"} -[Wed Mar 13 00:34:14 2024] [Token] {"TokenKey":"OVlma3FmZmJOTjNoY1A3bmxRbE5odHBHTTNZbGpjcGxvcVVJTmZIMDFHdjkvWDNYaG55WlB0cXNpaWRmclVCeHlXNFVrd2xxZThZQktIVEdGak9Xd29QTGNhMWtpYXlWUmwwNXcvZUdxQjhmbHFyenpPNVlDVk9ZbGZsUmplQ3M0WTRVeG9SeVNtN0xnMWUzQWo4WG1Oam9mNUw2SkJPV04rMGVOMUJ6Njhpb1RXMTl2LzFEdGRESXhZazBwaHBk","IsSuccessful":true,"Message":" درخواست Token با موفقیت انجام شد"} -[Wed Mar 13 00:34:15 2024] [VerificationCode] {"VerificationCodeId":634459857,"IsSuccessful":true,"Message":"your verification code is sent"} -[Wed Mar 13 00:34:48 2024] [Token] {"TokenKey":"OVlma3FmZmJOTjNoY1A3bmxRbE5odHBHTTNZbGpjcGxvcVVJTmZIMDFHdjkvWDNYaG55WlB0cXNpaWRmclVCeHlXNFVrd2xxZThZQktIVEdGak9Xd29QTGNhMWtpYXlWUmwwNXcvZUdxQjhmbHFyenpPNVlDVk9ZbGZsUmplQ3NGN0NVV3V1K01VRTg3TGY1by9PcmtlSVpWaFpBa0l4RXNCOERHMzIxMDRkL1RYbWRhOXc5ZmovT0lFV0FDamJs","IsSuccessful":true,"Message":" درخواست Token با موفقیت انجام شد"} -[Wed Mar 13 00:34:48 2024] [VerificationCode] {"VerificationCodeId":634460165,"IsSuccessful":true,"Message":"your verification code is sent"} -[Wed Mar 13 00:34:57 2024] [Token] {"TokenKey":"OVlma3FmZmJOTjNoY1A3bmxRbE5odHBHTTNZbGpjcGxvcVVJTmZIMDFHdjkvWDNYaG55WlB0cXNpaWRmclVCeHlXNFVrd2xxZThZQktIVEdGak9Xd29QTGNhMWtpYXlWUmwwNXcvZUdxQjhmbHFyenpPNVlDVk9ZbGZsUmplQ3NyNmxiRjUwVlF6UUlkSStnOWpOc0lLSyt5VHJjSjFRa0xsTkk0dFB2L3VSaE1PTDdQREY4WGlzcUFQeE01QWRP","IsSuccessful":true,"Message":" درخواست Token با موفقیت انجام شد"} -[Wed Mar 13 00:34:57 2024] [VerificationCode] {"VerificationCodeId":634460241,"IsSuccessful":true,"Message":"your verification code is sent"} -[Wed Mar 13 00:39:39 2024] [Token] {"TokenKey":"OVlma3FmZmJOTjNoY1A3bmxRbE5odHBHTTNZbGpjcGxvcVVJTmZIMDFHdjkvWDNYaG55WlB0cXNpaWRmclVCeHlXNFVrd2xxZThZQktIVEdGak9Xd29QTGNhMWtpYXlWUmwwNXcvZUdxQjhmbHFyenpPNVlDVk9ZbGZsUmplQ3N6MHErTmJEVzMydjZRcVJQaHNLb0R3MzJKcWk5bGJYNTh5UzFmSEpSSUY0b0Q4MFppdDRoeFlxWTZZSEQrL1hL","IsSuccessful":true,"Message":" درخواست Token با موفقیت انجام شد"} -[Wed Mar 13 00:39:39 2024] [VerificationCode] {"VerificationCodeId":634462768,"IsSuccessful":true,"Message":"your verification code is sent"} -[Wed Mar 13 00:40:18 2024] [Token] {"TokenKey":"OVlma3FmZmJOTjNoY1A3bmxRbE5odHBHTTNZbGpjcGxvcVVJTmZIMDFHdjkvWDNYaG55WlB0cXNpaWRmclVCeHlXNFVrd2xxZThZQktIVEdGak9Xd29QTGNhMWtpYXlWUmwwNXcvZUdxQjhmbHFyenpPNVlDVk9ZbGZsUmplQ3NLRlVYejdBcTJxMGl6dXJVSTRsQkNiOGh2M241WTZrSGI3Z0JCY3kxeFZvUzVCTnRkdmVWalFzd25KQzIzV21I","IsSuccessful":true,"Message":" درخواست Token با موفقیت انجام شد"} -[Wed Mar 13 00:40:18 2024] [VerificationCode] {"VerificationCodeId":634463121,"IsSuccessful":true,"Message":"your verification code is sent"} -[Wed Mar 13 00:41:38 2024] [Token] {"TokenKey":"OVlma3FmZmJOTjNoY1A3bmxRbE5odHBHTTNZbGpjcGxvcVVJTmZIMDFHdjkvWDNYaG55WlB0cXNpaWRmclVCeHlXNFVrd2xxZThZQktIVEdGak9Xd29QTGNhMWtpYXlWUmwwNXcvZUdxQjhmbHFyenpPNVlDVk9ZbGZsUmplQ3NOMUs3ZVN3eDU0OVBZdXR1VU1Yd3dhS2lyWmMrWkpjTGpUVVkzWDQ4ZU10VDBTWnFZc0gwYlVSZHArS1FBU2ZL","IsSuccessful":true,"Message":" درخواست Token با موفقیت انجام شد"} -[Wed Mar 13 00:41:38 2024] [VerificationCode] {"VerificationCodeId":634463845,"IsSuccessful":true,"Message":"your verification code is sent"} -[Wed Mar 13 01:11:21 2024] [Token] {"TokenKey":"OVlma3FmZmJOTjNoY1A3bmxRbE5odHBHTTNZbGpjcGxvcVVJTmZIMDFHdjkvWDNYaG55WlB0cXNpaWRmclVCeHlXNFVrd2xxZThZQktIVEdGak9Xd29QTGNhMWtpYXlWUmwwNXcvZUdxQjhmbHFyenpPNVlDVk9ZbGZsUmplQ3M4em1oSG05eU9XbVlna0U1TDRjRWdlRi8zTE10YnAzYVZia0hRTmQ3bWV4cEUyUUl4TCtPMncvWStrNi9TSjNt","IsSuccessful":true,"Message":" درخواست Token با موفقیت انجام شد"} -[Wed Mar 13 01:11:21 2024] [VerificationCode] {"VerificationCodeId":634470192,"IsSuccessful":true,"Message":"your verification code is sent"} -[Wed Mar 13 02:55:34 2024] [Token] {"TokenKey":"OVlma3FmZmJOTjNoY1A3bmxRbE5odHBHTTNZbGpjcGxvcVVJTmZIMDFHdjkvWDNYaG55WlB0cXNpaWRmclVCeHlXNFVrd2xxZThZQktIVEdGak9Xd29QTGNhMWtpYXlWUmwwNXcvZUdxQjhmbHFyenpPNVlDVk9ZbGZsUmplQ3MwSFZidjNtY0p1T3RwQVFlbkxJdjFHZ0xUaFpqZW9CdllCR21oNFNyaXRUczFaVUVSemZ3Rzk0TW0zRG50Q3VU","IsSuccessful":true,"Message":" درخواست Token با موفقیت انجام شد"} -[Wed Mar 13 02:55:34 2024] [VerificationCode] {"VerificationCodeId":634481796,"IsSuccessful":true,"Message":"your verification code is sent"} diff --git a/public/modstagram-back/middlewares/404.js b/public/modstagram-back/middlewares/404.js deleted file mode 100644 index fb30b71..0000000 --- a/public/modstagram-back/middlewares/404.js +++ /dev/null @@ -1,9 +0,0 @@ -module.exports = (app) => { - app.use((req, res, next) => { - res.status(404).send({ - code: 'Not Found', - status: 404, - message: 'requested resource could not be found!' - }) - }) -} diff --git a/public/modstagram-back/middlewares/adminAuth.js b/public/modstagram-back/middlewares/adminAuth.js deleted file mode 100644 index 060d854..0000000 --- a/public/modstagram-back/middlewares/adminAuth.js +++ /dev/null @@ -1,55 +0,0 @@ -const AdminModel = require('../models/AdminModel') -const jwt = require('jsonwebtoken') - -module.exports = async (req, res, next) => { - if (!('authorization' in req.headers)) { - return res.status(401).send({ - status: 'error', - code: 401, - message: 'you are not authorized!' - }) - } - - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - let decodedToken - try { - decodedToken = jwt.verify(token, process.env.APP_SECRET) - } catch (err) { - return res.status(401).send({ - status: 'error', - code: 401, - message: 'Your token is not valid!', - error: err.message - }) - } - if (!decodedToken) { - return res.status(401).send({ - status: 'error', - code: 401, - message: 'Your token is not valid!' - }) - } - try { - // پیدا کردن کاربر با استفاده از اطلاعات موجود در توکن - const admin = await AdminModel.findOne({ _id: decodedToken.id }) - if (!admin) { - return res.status(403).send({ - status: 'error', - code: 403, - message: 'Access denied!' - }) - } - - // ادامه مسیر در صورتی که کاربر ادمین باشد - req.admin = admin - next() - } catch (error) { - return res.status(500).send({ - status: 'error', - code: 500, - message: 'Internal Server Error', - error: error.message - }) - } -} diff --git a/public/modstagram-back/middlewares/auth.js b/public/modstagram-back/middlewares/auth.js deleted file mode 100644 index d97a1cd..0000000 --- a/public/modstagram-back/middlewares/auth.js +++ /dev/null @@ -1,21 +0,0 @@ -const TokenService = require('../services/TokenService') -module.exports = (req, res, next) => { - console.log(1); - if (!('authorization' in req.headers)) { - return res.status(401).send({ - status: 'error', - code: 401, - message: 'you are not authorized!' - }) - } - const [, tokenValue] = req.headers.authorization.split(' ') - const token = TokenService.verify(tokenValue) - if (!token) { - return res.status(401).send({ - status: 'error', - code: 401, - message: 'your token is not valid!' - }) - } - next() -} diff --git a/public/modstagram-back/middlewares/blockCheck.js b/public/modstagram-back/middlewares/blockCheck.js deleted file mode 100644 index 7af2097..0000000 --- a/public/modstagram-back/middlewares/blockCheck.js +++ /dev/null @@ -1,47 +0,0 @@ -const UserModel = require('../models/UserModel') // مسیر درست به مدل کاربر -const jwt = require('jsonwebtoken') - -module.exports = async (req, res, next) => { - console.log(2); - try { - if (!('authorization' in req.headers)) { - return res.status(401).send({ - status: 'error', - code: 401, - message: 'You are not authorized!' - }) - } - - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - - if (!decodedToken) { - return res.status(401).send({ - status: 'error', - code: 401, - message: 'Your token is not valid!' - }) - } - - const user = await UserModel.findById(decodedToken.id) - if (user.block_status === true) { - return res.status(403).send({ - status: 'error', - code: 403, - message: 'حساب کاربری شما مسدود شده است، برای اطلاعات بیشتر با پشتیبانی تماس بگیرید!', - type: 'block' - }) - } - - req.user = user // کاربر را به درخواست اضافه کنید تا در سایر middleware ها و کنترلرها استفاده شود. - next() - } catch (error) { - console.error('Error in blockCheck middleware:', error) - res.status(500).send({ - status: 'error', - code: 500, - message: 'Server error' - }) - } -} diff --git a/public/modstagram-back/middlewares/exception.js b/public/modstagram-back/middlewares/exception.js deleted file mode 100644 index 1d7ddff..0000000 --- a/public/modstagram-back/middlewares/exception.js +++ /dev/null @@ -1,11 +0,0 @@ -module.exports = (app) => { - app.use((error, req, res, next) => { - const status = error.status || 500 - res.status(500).send({ - code: 'Eception', - status, - en_message: error.message, - message: 'خطایی در عملیات مورد نظر رخ داده است.' - }) - }) -} diff --git a/public/modstagram-back/middlewares/index.js b/public/modstagram-back/middlewares/index.js deleted file mode 100644 index 1192668..0000000 --- a/public/modstagram-back/middlewares/index.js +++ /dev/null @@ -1,17 +0,0 @@ -const bodyParser = require('body-parser') -const cors = require('cors') -const formData = require('express-form-data') -const session = require('express-session') -const lastOnline = require('./lastOnline') -module.exports = (app) => { - app.use(cors()) // develop - app.use(formData.parse()) - app.use(bodyParser.json()) - app.use(bodyParser.urlencoded({ extended: true })) - app.use(session({ - secret: 'your_secret_key', // کلید مخفی برای امنیت جلسات - resave: false, - saveUninitialized: false - })) - app.use(lastOnline) -} diff --git a/public/modstagram-back/middlewares/isHalfRegister.js b/public/modstagram-back/middlewares/isHalfRegister.js deleted file mode 100644 index 4285c46..0000000 --- a/public/modstagram-back/middlewares/isHalfRegister.js +++ /dev/null @@ -1,53 +0,0 @@ -const UserModel = require('../models/UserModel') // مسیر درست به مدل کاربر -const jwt = require('jsonwebtoken') - -module.exports = async (req, res, next) => { - console.log(3); - try { - console.log(31); - if (!('authorization' in req.headers)) { - return res.status(401).send({ - status: 'error', - code: 401, - message: 'You are not authorized!' - }) - } - console.log(32); - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - - if (!decodedToken) { - return res.status(401).send({ - status: 'error', - code: 401, - message: 'Your token is not valid!' - }) - } - console.log(33); - const user = await UserModel.findById(decodedToken.id) - if (!user.user_name || - !user.first_name || - !user.last_name || - !user.user_type || - !user.password) { - return res.status(403).send({ - status: 'error', - code: 403, - message: 'لطفا از بخش تنظیمات، ثبت نام خود را کامل کنید', - type: 'not_register' - }) - } - console.log(34); - req.user = user // کاربر را به درخواست اضافه کنید تا در سایر middleware ها و کنترلرها استفاده شود. - next() - } catch (error) { - console.log(35); - console.error('not_register middleware:', error) - res.status(500).send({ - status: 'error', - code: 500, - message: 'Server error' - }) - } -} diff --git a/public/modstagram-back/middlewares/isRegister.js b/public/modstagram-back/middlewares/isRegister.js deleted file mode 100644 index 1f97f96..0000000 --- a/public/modstagram-back/middlewares/isRegister.js +++ /dev/null @@ -1,50 +0,0 @@ -const UserModel = require('../models/UserModel') // مسیر درست به مدل کاربر -const jwt = require('jsonwebtoken') - -module.exports = async (req, res, next) => { - try { - if (!('authorization' in req.headers)) { - return res.status(401).send({ - status: 'error', - code: 401, - message: 'You are not authorized!' - }) - } - - const token = req.header('Authorization').split(' ')[1] - if (!token) return res.status(401).send('Access Denied') - const decodedToken = jwt.verify(token, process.env.APP_SECRET) - - if (!decodedToken) { - return res.status(401).send({ - status: 'error', - code: 401, - message: 'Your token is not valid!' - }) - } - - const user = await UserModel.findById(decodedToken.id) - if (!user.user_name || - !user.first_name || - !user.last_name || - !user.password) { - return res.status(403).send({ - status: 'error', - code: 403, - message: 'لطفا از بخش تنظیمات، ثبت نام خود را کامل کنید', - type: 'not_register' - }) - } - - - req.user = user // کاربر را به درخواست اضافه کنید تا در سایر middleware ها و کنترلرها استفاده شود. - next() - } catch (error) { - console.error('not_register middleware:', error) - res.status(500).send({ - status: 'error', - code: 500, - message: 'Server error' - }) - } -} diff --git a/public/modstagram-back/middlewares/lastOnline.js b/public/modstagram-back/middlewares/lastOnline.js deleted file mode 100644 index 716a901..0000000 --- a/public/modstagram-back/middlewares/lastOnline.js +++ /dev/null @@ -1,21 +0,0 @@ -const jwt = require('jsonwebtoken') -const UserModel = require('../models/UserModel') - -module.exports = async (req, res, next) => { - if (req.header && req.header('Authorization')) { - const token = await req.header('Authorization').split(' ')[1] - const decodedToken = await jwt.verify(token, process.env.APP_SECRET) - const user = await UserModel.findById(decodedToken.id) - if (user) { - try { - user.last_online = new Date() - await user.save() // ذخیره تغییرات در دیتابیس - } catch (error) { - // بررسی و پردازش خطاها - console.error('Error updating last online time:', error) - } - } - } - - next() -} diff --git a/public/modstagram-back/middlewares/upload.js b/public/modstagram-back/middlewares/upload.js deleted file mode 100644 index 2229afb..0000000 --- a/public/modstagram-back/middlewares/upload.js +++ /dev/null @@ -1,24 +0,0 @@ -const multer = require('multer'); -const path = require('path'); -const fs = require('fs-extra'); - -const uploadDir = path.join(__dirname, '../storage/posts'); -fs.ensureDirSync(uploadDir); // مطمئن میشه مسیر وجود داره - -const storage = multer.diskStorage({ - destination: (req, file, cb) => cb(null, uploadDir), - filename: (req, file, cb) => { - const ext = path.extname(file.originalname); - const name = file.originalname.replace(ext, '').replace(/\s/g, '_'); - cb(null, `${Date.now()}-${name}${ext}`); - } -}); - -const fileFilter = (req, file, cb) => { - if (!file.mimetype.startsWith('image/')) return cb(new Error('فقط تصاویر مجاز است')); - cb(null, true); -}; - -const upload = multer({ storage, fileFilter, limits: { files: 10 } }); // حداکثر ۱۰ فایل - -module.exports = upload; diff --git a/public/modstagram-back/models/AcademyCategoryModel.js b/public/modstagram-back/models/AcademyCategoryModel.js deleted file mode 100644 index be50bf0..0000000 --- a/public/modstagram-back/models/AcademyCategoryModel.js +++ /dev/null @@ -1,190 +0,0 @@ -const mongoose = require('mongoose'); -const mongoosePaginate = require('mongoose-paginate-v2'); -const timestamp = require('mongoose-timestamp'); - -const AcademyCategorySchema = new mongoose.Schema({ - title: { - type: String, - required: [true, 'عنوان دسته‌بندی الزامی است'], - trim: true, - minLength: [2, 'عنوان باید حداقل ۲ کاراکتر باشد'], - maxLength: [100, 'عنوان باید حداکثر ۱۰۰ کاراکتر باشد'], - unique: true, - index: true, - }, - slug: { - type: String, - required: true, - unique: true, - lowercase: true, - trim: true, - index: true, - }, - description: { - type: String, - required: false, - trim: true, - maxLength: 500, - default: null, - }, - icon: { - type: String, - required: false, - default: null, - }, - color: { - type: String, - required: false, - default: '#3B82F6', - match: /^#[0-9A-F]{6}$/i, - }, - parent: { - type: mongoose.Schema.Types.ObjectId, - ref: 'AcademyCategory', - required: false, - default: null, - index: true, - }, - level: { - type: Number, - required: true, - default: 0, - min: 0, - max: 3, - }, - order: { - type: Number, - required: true, - default: 0, - index: true, - }, - image: { - type: String, - required: false, - default: null, - }, - course_count: { - type: Number, - required: true, - default: 0, - min: 0, - }, - status: { - type: String, - enum: ['active', 'inactive', 'deleted'], - required: true, - default: 'active', - index: true, - }, - is_featured: { - type: Boolean, - required: true, - default: false, - index: true, - }, - seo_title: { - type: String, - required: false, - trim: true, - maxLength: 70, - }, - seo_description: { - type: String, - required: false, - trim: true, - maxLength: 160, - }, - created_by: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: true, - }, - updated_by: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: false, - }, -}, { - toJSON: { virtuals: true }, - toObject: { virtuals: true } -}); - -// Virtual برای زیردسته‌ها -AcademyCategorySchema.virtual('children', { - ref: 'AcademyCategory', - localField: '_id', - foreignField: 'parent', - justOne: false, - options: { sort: { order: 1, title: 1 } } -}); - -// Virtual برای دوره‌های این دسته -AcademyCategorySchema.virtual('courses', { - ref: 'Course', - localField: '_id', - foreignField: 'category_id', - justOne: false, - match: { status: 'accept' } -}); - -// Middleware: قبل از save -AcademyCategorySchema.pre('save', async function(next) { - if (this.isModified('title') || this.isNew) { - // تولید slug - this.slug = this.title - .replace(/[^\u0600-\u06FF\uFB8A\u067E\u0686\u06AF\u200C\uFB8E\u0698a-zA-Z0-9\s]/g, '') - .trim() - .replace(/\s+/g, '-') - .toLowerCase(); - - // اگه parent داره، سطح رو محاسبه کن - if (this.parent) { - const parent = await this.constructor.findById(this.parent); - if (parent) { - this.level = parent.level + 1; - } - } else { - this.level = 0; - } - } - next(); -}); - -// استاتیک متدها -AcademyCategorySchema.statics = { - // دریافت درخت دسته‌بندی‌ها - async getTree() { - const categories = await this.find({ status: 'active', parent: null }) - .sort({ order: 1, title: 1 }) - .populate({ - path: 'children', - match: { status: 'active' }, - options: { sort: { order: 1, title: 1 } }, - populate: { - path: 'children', - match: { status: 'active' }, - options: { sort: { order: 1, title: 1 } } - } - }); - return categories; - }, - - // افزایش تعداد دوره‌ها - async incrementCourseCount(categoryId, increment = 1) { - return this.findByIdAndUpdate(categoryId, { - $inc: { course_count: increment } - }); - }, - - // دریافت دسته‌بندی با اسلاگ - async getBySlug(slug) { - return this.findOne({ slug, status: 'active' }) - .populate('children') - .populate('parent'); - } -}; - -AcademyCategorySchema.plugin(timestamp); -AcademyCategorySchema.plugin(mongoosePaginate); - -module.exports = mongoose.model('AcademyCategory', AcademyCategorySchema); \ No newline at end of file diff --git a/public/modstagram-back/models/AcademyContentModel.js b/public/modstagram-back/models/AcademyContentModel.js deleted file mode 100644 index 092990f..0000000 --- a/public/modstagram-back/models/AcademyContentModel.js +++ /dev/null @@ -1,71 +0,0 @@ -const mongoose = require('mongoose'); -const timestamp = require('mongoose-timestamp'); -const mongoosePaginate = require('mongoose-paginate-v2'); - -const modelSchema = new mongoose.Schema({ - course_images: { - type: [String], // آرایه‌ای از مسیرهای تصاویر - required: false, - default: [], - }, - course_video: { - type: String, // مسیر ویدئو - required: false, - trim: true, - default: null, - }, - type: { - type: String, // نوع پست: 'image' یا 'video' - required: true, - enum: ['image', 'video'], - }, - files: [ - { - path: { type: String, required: false }, - type: { type: String, enum: ['image', 'video'], required: false }, - } - ], - caption: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 1000, - default: null, - }, - status: { - type: String, - required: false, - trim: true, - enum: ['pending', 'accept', 'reject'], - default: 'accept', - }, - user_id: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - }, - likes: [{ - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - }], - comments: { - type: Object, - default: null, - }, - courseId: { - type: String, - }, - - is_free: { - type: Boolean, - }, - file_name: { - type: String, - }, - -}); - -modelSchema.plugin(timestamp); -modelSchema.plugin(mongoosePaginate); -const PostModel = mongoose.model('AcademyContent', modelSchema); -module.exports = PostModel; \ No newline at end of file diff --git a/public/modstagram-back/models/AcademyLikeModel.js b/public/modstagram-back/models/AcademyLikeModel.js deleted file mode 100644 index 358f036..0000000 --- a/public/modstagram-back/models/AcademyLikeModel.js +++ /dev/null @@ -1,25 +0,0 @@ -const mongoose = require("mongoose"); -const timestamp = require("mongoose-timestamp"); -const mongoosePaginate = require("mongoose-paginate-v2"); - -const modelSchema = new mongoose.Schema({ - - user_id: { - type: String, - required: true, - trim: true, - default: 0, - }, - course_id: { - type: String, - required: true, - trim: true, - default: 0, - }, - -}); - -modelSchema.plugin(timestamp); -modelSchema.plugin(mongoosePaginate); -const PostModel = mongoose.model("Likes", modelSchema); -module.exports = PostModel; diff --git a/public/modstagram-back/models/AcademyModel.js b/public/modstagram-back/models/AcademyModel.js deleted file mode 100644 index 9f8e758..0000000 --- a/public/modstagram-back/models/AcademyModel.js +++ /dev/null @@ -1,55 +0,0 @@ -const mongoose = require("mongoose"); -const timestamp = require("mongoose-timestamp"); -const mongoosePaginate = require("mongoose-paginate-v2"); - -const modelSchema = new mongoose.Schema({ - academy_image: { - type: String, - required: false, - trim: true, - default: null, - }, - academy_name: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null, - }, - userId: { - type: String, - required: true, - }, - rate: { - type: Number, - trim: true, - default: 0 - }, - number_of_rate: { - type: Number, - trim: true, - default: 0 - }, - sheba: { - type: String, - required: false, - default: null - }, - bio: { - type: String, - required: false, - default: null - }, - tag: { - type: Object, - required: false, - default: null - }, - -}); - -modelSchema.plugin(timestamp); -modelSchema.plugin(mongoosePaginate); -const PostModel = mongoose.model("Academy", modelSchema); -module.exports = PostModel; diff --git a/public/modstagram-back/models/AcademyPaymentModel.js b/public/modstagram-back/models/AcademyPaymentModel.js deleted file mode 100644 index b7c9fa7..0000000 --- a/public/modstagram-back/models/AcademyPaymentModel.js +++ /dev/null @@ -1,24 +0,0 @@ -const mongoose = require("mongoose"); -const timestamp = require("mongoose-timestamp"); -const mongoosePaginate = require("mongoose-paginate-v2"); - -const modelSchema = new mongoose.Schema({ - price: { type: Number, required: true }, // قیمت نهایی شامل مالیات - discountAmount: { type: Number, default: 0 }, // مبلغ تخفیف - taxAmount: { type: Number, default: 0 }, // مبلغ مالیات - taxRate: { type: Number, default: 9 }, // درصد مالیات - course_name: { type: String, required: true }, - course_id: { type: mongoose.Schema.Types.ObjectId, ref: "Course", required: true }, - academy_id: { type: mongoose.Schema.Types.ObjectId, ref: "Academy", required: true }, - user_id: { type: mongoose.Schema.Types.ObjectId, ref: "User", required: true }, - payment_authority: { type: String }, - payment_ref_id: { type: String }, - status: { type: String, enum: ["pending", "success", "failed", "settled"], default: "success" }, - - -}); - -modelSchema.plugin(timestamp); -modelSchema.plugin(mongoosePaginate); -const PostModel = mongoose.model("AcademyPayment", modelSchema); -module.exports = PostModel; diff --git a/public/modstagram-back/models/AdminModel.js b/public/modstagram-back/models/AdminModel.js deleted file mode 100644 index 4bca3a2..0000000 --- a/public/modstagram-back/models/AdminModel.js +++ /dev/null @@ -1,80 +0,0 @@ -const mongoose = require('mongoose') -const mongoosePaginate = require('mongoose-paginate-v2') -const timestamp = require('mongoose-timestamp') -const adminSchema = new mongoose.Schema({ - mobile: { - type: String, - required: false, - trim: true, - unique: true - }, - otp: { - type: String, - required: false, - trim: true, - minLength: 6, - maxLength: 6 - }, - user_name: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - password: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - first_name: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - last_name: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - user_type: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - profile_image: { - type: String, - required: false, - trim: true - }, - gender: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - last_online: { - type: Date, // ذخیره تاریخ و زمان آخرین بازدید - default: Date.now // تنظیم تاریخ به تاریخ فعلی - } -}) - -adminSchema.plugin(timestamp) -adminSchema.plugin(mongoosePaginate) -const AdminModel = mongoose.model('Admin', adminSchema) -module.exports = AdminModel diff --git a/public/modstagram-back/models/AdvertisingCategoryModel.js b/public/modstagram-back/models/AdvertisingCategoryModel.js deleted file mode 100644 index 855035a..0000000 --- a/public/modstagram-back/models/AdvertisingCategoryModel.js +++ /dev/null @@ -1,23 +0,0 @@ -const mongoose = require('mongoose') -const mongoosePaginate = require('mongoose-paginate-v2') -const timestamp = require('mongoose-timestamp') -const advertisingCategorySchema = new mongoose.Schema({ - title: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - status: { - type: Boolean, - required: false, - default: true - } -}) - -advertisingCategorySchema.plugin(timestamp) -advertisingCategorySchema.plugin(mongoosePaginate) -const AdvertisingCategoryModel = mongoose.model('AdvertisingCategory', advertisingCategorySchema) -module.exports = AdvertisingCategoryModel diff --git a/public/modstagram-back/models/AdvertisingCommentModel.js b/public/modstagram-back/models/AdvertisingCommentModel.js deleted file mode 100644 index f6ea2b4..0000000 --- a/public/modstagram-back/models/AdvertisingCommentModel.js +++ /dev/null @@ -1,32 +0,0 @@ -const mongoose = require('mongoose') -const timestamp = require('mongoose-timestamp') -const mongoosePaginate = require('mongoose-paginate-v2') - -const advertisingCommentSchema = new mongoose.Schema({ - advertisingId: { - type: mongoose.Schema.Types.ObjectId, - ref: 'Advertising', - required: true - }, - userId: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: true - }, - text: { - type: String, - required: true, - trim: true - }, - status: { - type: String, - enum: ['pending', 'accepted', 'rejected'], - default: 'pending' - } -}) - -advertisingCommentSchema.plugin(timestamp) -advertisingCommentSchema.plugin(mongoosePaginate) -const AdvertisingComment = mongoose.model('AdvertisingComment', advertisingCommentSchema) - -module.exports = AdvertisingComment diff --git a/public/modstagram-back/models/AdvertisingFeaturesModel.js b/public/modstagram-back/models/AdvertisingFeaturesModel.js deleted file mode 100644 index 4081d59..0000000 --- a/public/modstagram-back/models/AdvertisingFeaturesModel.js +++ /dev/null @@ -1,27 +0,0 @@ -const mongoose = require('mongoose') -const mongoosePaginate = require('mongoose-paginate-v2') -const timestamp = require('mongoose-timestamp') -const advertisingFeaturesSchema = new mongoose.Schema({ - title: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - status: { - type: Boolean, - required: false, - default: true - }, - type: { - type: String, - default: 'boolean' - } -}) - -advertisingFeaturesSchema.plugin(timestamp) -advertisingFeaturesSchema.plugin(mongoosePaginate) -const AdvertisingFeaturesModel = mongoose.model('AdvertisingFeatures', advertisingFeaturesSchema) -module.exports = AdvertisingFeaturesModel diff --git a/public/modstagram-back/models/AdvertisingLikeModel.js b/public/modstagram-back/models/AdvertisingLikeModel.js deleted file mode 100644 index f8552dd..0000000 --- a/public/modstagram-back/models/AdvertisingLikeModel.js +++ /dev/null @@ -1,20 +0,0 @@ -const mongoose = require('mongoose') - -const advertisingLikeSchema = new mongoose.Schema({ - advertisingId: { - type: mongoose.Schema.Types.ObjectId, - ref: 'Advertising', - required: true - }, - userId: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: true - } - -}) - -// تعریف مدل AdvertisingLikeModel -const AdvertisingLikeModel = mongoose.model('AdvertisingLike', advertisingLikeSchema) - -module.exports = AdvertisingLikeModel diff --git a/public/modstagram-back/models/AdvertisingModel.js b/public/modstagram-back/models/AdvertisingModel.js deleted file mode 100644 index 3046a48..0000000 --- a/public/modstagram-back/models/AdvertisingModel.js +++ /dev/null @@ -1,230 +0,0 @@ -const mongoose = require('mongoose') -const mongoosePaginate = require('mongoose-paginate-v2') -const timestamp = require('mongoose-timestamp') -const advertisingSchema = new mongoose.Schema({ - title: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - category: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - description: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 1024, - default: null - }, - province: { - type: Object, - default: null - }, - city: { - type: Object, - default: null - }, - neighbourhood: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - address: { - type: String, - trim: true, - minLength: 1, - maxLength: 512, - default: null - }, - lat: { - type: String, - trim: true, - minLength: 1, - maxLength: 256, - default: null - }, - lng: { - type: String, - trim: true, - minLength: 1, - maxLength: 256, - default: null - }, - images: [{ - type: String, - required: false, - trim: true, - default: null - }], - services: [{ - title: { - type: String, - required: true, - trim: true - }, - originalPrice: { - type: String, - required: true - }, - discountPrice: { - type: String, - required: false - }, - discountPercentage: { - type: Number, - required: false - }, - status: { - type: String, - default: "UnderReview", - required: false - }, - image: { - type: String, - required: false, - trim: true - } - }], - features: [{ - title: { - type: String, - required: false, - trim: true - }, - value: { - type: Boolean, - required: true - } - }], - contactInfo: { - phone: { - type: String, - required: false, - trim: true, - default: null - }, - mobile: { - type: String, - required: false, - trim: true, - default: null - }, - telegramLink: { - type: String, - required: false, - trim: true, - default: null - }, - whatsappNumber: { - type: String, - required: false, - trim: true, - default: null - }, - instagramLink: { - type: String, - required: false, - trim: true, - default: null - }, - saveInfoForNextAds: { - type: Boolean, - required: true, - default: false - } - }, - type: { - type: String, - enum: ['free', 'normal', 'special', 'highlight'], - default: 'normal' - }, - status: { - type: String, - enum: ['pre_payment', 'paid', 'accepted', 'rejected', 'expired'], - default: 'pre_payment' - }, - payment_status: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - creator_id: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User' - }, - reject_reason: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 1024, - default: null - }, - mostDiscountPercentage: { - type: Number, - required: false - }, - showDiscount: { - type: Boolean, - required: false, - default: false - }, - likesCount: { - type: Number, - default: 0 - }, - commentsCount: { - type: Number, - default: 0 - }, - ratings: [{ - userId: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: true - }, - rating: { - type: Number, - required: true, - min: 1, - max: 5 - } - }], - averageRating: { - type: Number, - default: 0 - }, - ratingsCount: { - type: Number, - default: 0 - }, - viewCount: { - type: Number, - default: 0 - }, - acceptedAt: { - type: Date, - default: null - } -}) - -advertisingSchema.plugin(timestamp) -advertisingSchema.plugin(mongoosePaginate) -const AdvertisingModel = mongoose.model('Advertising', advertisingSchema) -module.exports = AdvertisingModel diff --git a/public/modstagram-back/models/AdvertisingProfile.js b/public/modstagram-back/models/AdvertisingProfile.js deleted file mode 100644 index 70dfc5a..0000000 --- a/public/modstagram-back/models/AdvertisingProfile.js +++ /dev/null @@ -1,113 +0,0 @@ -const mongoose = require('mongoose') -const timestamp = require('mongoose-timestamp') -const mongoosePaginate = require('mongoose-paginate-v2') - -const advertisingProfileSchema = new mongoose.Schema({ - user: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: true - }, - profile_image: { - type: String, - required: false, - trim: true, - default: null - }, - image_count: { - type: Number, - default: 0 - }, - like_count: { - type: Number, - default: 0 - }, - comment_count: { - type: Number, - default: 0 - }, - vitrine_name: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - category: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - about_us: { - type: String, - required: false, - minLength: 1, - maxLength: 1024, - default: null - }, - province: { - type: Object, - default: null - }, - city: { - type: Object, - default: null - }, - lat: { - type: String, - trim: true, - minLength: 1, - maxLength: 512, - default: null - }, - lng: { - type: String, - trim: true, - minLength: 1, - maxLength: 512, - default: null - }, - address: { - type: String, - required: false, - trim: true, - default: null - }, - neighbourhood: { - type: String, - required: false, - trim: true, - default: null - }, - adTotalRatings: { - type: Number, - default: 0 - }, - adRatingsCount: { - type: Number, - default: 0 - }, - adAverageRating: { - type: Number, - default: 0 - }, - contactInfo: { - phone: String, - mobile: String, - telegramLink: String, - whatsappNumber: String, - instagramLink: String, - saveInfoForNextAds: { type: Boolean, default: false } - } -}) - -advertisingProfileSchema.plugin(timestamp) -advertisingProfileSchema.plugin(mongoosePaginate) - -const AdvertisingProfileModel = mongoose.model('AdvertisingProfile', advertisingProfileSchema) - -module.exports = AdvertisingProfileModel diff --git a/public/modstagram-back/models/AdvertisingRatingModel.js b/public/modstagram-back/models/AdvertisingRatingModel.js deleted file mode 100644 index ac8b79b..0000000 --- a/public/modstagram-back/models/AdvertisingRatingModel.js +++ /dev/null @@ -1,26 +0,0 @@ -const mongoose = require('mongoose') -const timestamp = require('mongoose-timestamp') - -const advertisingRatingSchema = new mongoose.Schema({ - advertisingId: { - type: mongoose.Schema.Types.ObjectId, - ref: 'Advertising', - required: true - }, - userId: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: true - }, - rating: { - type: Number, - required: true, - min: 1, - max: 5 - } -}) - -advertisingRatingSchema.plugin(timestamp) - -const AdvertisingRatingModel = mongoose.model('AdvertisingRating', advertisingRatingSchema) -module.exports = AdvertisingRatingModel diff --git a/public/modstagram-back/models/AdvertisingTypeModel.js b/public/modstagram-back/models/AdvertisingTypeModel.js deleted file mode 100644 index 5b49649..0000000 --- a/public/modstagram-back/models/AdvertisingTypeModel.js +++ /dev/null @@ -1,25 +0,0 @@ -const mongoose = require('mongoose') - -const advertisingTypeSchema = new mongoose.Schema({ - name: { - type: String, - required: true, - trim: true, - minLength: 1, - maxLength: 255 - }, - price: { - type: Number, - required: true, - trim: true, - minLength: 1, - maxLength: 255 - }, - status: { - type: String, - default: 'active' - } -}) - -const AdvertisingTypeModel = mongoose.model('AdvertisingType', advertisingTypeSchema) -module.exports = AdvertisingTypeModel diff --git a/public/modstagram-back/models/CommentModel.js b/public/modstagram-back/models/CommentModel.js deleted file mode 100644 index 5fbabc9..0000000 --- a/public/modstagram-back/models/CommentModel.js +++ /dev/null @@ -1,54 +0,0 @@ -const mongoose = require('mongoose') -const timestamp = require('mongoose-timestamp') -const mongoosePaginate = require('mongoose-paginate-v2') - -const commentSchema = new mongoose.Schema({ - user: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: true - }, - project: { - type: mongoose.Schema.Types.ObjectId, - ref: 'Project', - required: false - }, - offer: { - type: mongoose.Schema.Types.ObjectId, - ref: 'Offer', - required: false - }, - creator: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: true - }, - rating: { - type: Number, - required: true - }, - comment: { - type: String, - trim: true - }, - post: { - type: mongoose.Schema.Types.ObjectId, - ref: 'Post', - required: false - }, - comment_for: { - type: String, - enum: ['user', 'project', 'post'], - required: true - }, - status: { - type: String, - enum: ['pending', 'accepted', 'rejected'], - default: 'pending' - } -}) - -commentSchema.plugin(timestamp) -commentSchema.plugin(mongoosePaginate) -const CommentModel = mongoose.model('Comment', commentSchema) -module.exports = CommentModel diff --git a/public/modstagram-back/models/CourseComentModel.js b/public/modstagram-back/models/CourseComentModel.js deleted file mode 100644 index b5c7d5c..0000000 --- a/public/modstagram-back/models/CourseComentModel.js +++ /dev/null @@ -1,40 +0,0 @@ -const mongoose = require("mongoose"); -const timestamp = require("mongoose-timestamp"); -const mongoosePaginate = require("mongoose-paginate-v2"); - -const modelSchema = new mongoose.Schema({ - - user_id: { - type: String, - required: true, - trim: true, - }, - course_id: { - type: String, - required: true, - trim: true, - }, - comment: { - type: String, - required: true, - trim: true, - default: 0, - }, - rate: { - type: String, - required: true, - trim: true, - default: 0, - }, - status: { - type: String, - enum: ['pending', 'accepted', 'rejected'], - default: 'accepted' - } - -}); - -modelSchema.plugin(timestamp); -modelSchema.plugin(mongoosePaginate); -const PostModel = mongoose.model("CourseComment", modelSchema); -module.exports = PostModel; diff --git a/public/modstagram-back/models/CourseModel.js b/public/modstagram-back/models/CourseModel.js deleted file mode 100644 index f8a5e67..0000000 --- a/public/modstagram-back/models/CourseModel.js +++ /dev/null @@ -1,79 +0,0 @@ -const mongoose = require("mongoose"); -const timestamp = require("mongoose-timestamp"); -const mongoosePaginate = require("mongoose-paginate-v2"); - -const modelSchema = new mongoose.Schema({ - price: { - type: String, - required: true, - }, - cuorse_name: { - type: String, - required: true, - }, - category:{ - type: String - }, - offer: { - type: String - }, - academyId:{ - type: String - }, - caption: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 1000, - default: null, - }, - status: { - type: String, - required: false, - trim: true, - enum: ['pending', 'accept', 'reject'], - default: 'accept', - }, - user_id: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - }, - likes: { - type: Number, - required: false, - trim: true, - default: 0, - }, - comments: { - type: Object, - default: null, - }, - type: { - type: String, - required: false, - trim: true, - enum: ['normal', 'pro', 'legend'], - default: "normal", - }, - course_time: { - type: String - }, - number_of_course_content: { - type: String - }, - teacher_number: { - type: String - }, - course_image: { - type: String - }, - teacher_name: { - type: String - }, -}); - -modelSchema.plugin(timestamp); -modelSchema.plugin(mongoosePaginate); -const PostModel = mongoose.model("Course", modelSchema); -module.exports = PostModel; diff --git a/public/modstagram-back/models/CoursePaymentModel.js b/public/modstagram-back/models/CoursePaymentModel.js deleted file mode 100644 index cb6de53..0000000 --- a/public/modstagram-back/models/CoursePaymentModel.js +++ /dev/null @@ -1,22 +0,0 @@ -const mongoose = require("mongoose"); -const timestamp = require("mongoose-timestamp"); -const mongoosePaginate = require("mongoose-paginate-v2"); - -const modelSchema = new mongoose.Schema({ - price: { - type: String, - required: true, - }, - cuorse_type: { - type: String, - required: false, - trim: true, - enum: ['normal', 'pro', 'legend'], - }, - -}); - -modelSchema.plugin(timestamp); -modelSchema.plugin(mongoosePaginate); -const PostModel = mongoose.model("CoursePayment", modelSchema); -module.exports = PostModel; diff --git a/public/modstagram-back/models/ExpertiseModel.js b/public/modstagram-back/models/ExpertiseModel.js deleted file mode 100644 index 29b490a..0000000 --- a/public/modstagram-back/models/ExpertiseModel.js +++ /dev/null @@ -1,47 +0,0 @@ -// const mongoose = require('mongoose') -// const timestamp = require('mongoose-timestamp') - -// const subExpertiseSchema = new mongoose.Schema({ -// id: { -// type: mongoose.Schema.Types.ObjectId, -// ref: 'ExpertiseModel' -// }, -// name: { -// type: String -// } -// }) - -// const expertiseSchema = new mongoose.Schema({ -// expertise: { -// type: String, -// unique: true -// }, -// sub_expertise: [subExpertiseSchema] -// }) - -// expertiseSchema.plugin(timestamp) - -// const ExpertiseModel = mongoose.model('Expertise', expertiseSchema) -// module.exports = ExpertiseModel - -const mongoose = require('mongoose') -const timestamp = require('mongoose-timestamp') - -const subExpertiseSchema = new mongoose.Schema({ - name: { - type: String - } -}) - -const expertiseSchema = new mongoose.Schema({ - expertise: { - type: String, - unique: true - }, - sub_expertise: [subExpertiseSchema] -}) - -expertiseSchema.plugin(timestamp) - -const ExpertiseModel = mongoose.model('Expertise', expertiseSchema) -module.exports = ExpertiseModel diff --git a/public/modstagram-back/models/IsPaymentCourseModel.js b/public/modstagram-back/models/IsPaymentCourseModel.js deleted file mode 100644 index 0524f3c..0000000 --- a/public/modstagram-back/models/IsPaymentCourseModel.js +++ /dev/null @@ -1,15 +0,0 @@ -const mongoose = require("mongoose"); -const timestamp = require("mongoose-timestamp"); -const mongoosePaginate = require("mongoose-paginate-v2"); - -const modelSchema = new mongoose.Schema({ - user_id: { type: mongoose.Schema.Types.ObjectId, ref: "User", required: true }, - course_id: { type: mongoose.Schema.Types.ObjectId, ref: "Course", required: true }, - price_paid: { type: Number, required: true }, // قیمت پرداخت شده - purchased_at: { type: Date, default: Date.now }, -}); - -modelSchema.plugin(timestamp); -modelSchema.plugin(mongoosePaginate); -const PostModel = mongoose.model("IsPaymentCourse", modelSchema); -module.exports = PostModel; diff --git a/public/modstagram-back/models/LikeModel.js b/public/modstagram-back/models/LikeModel.js deleted file mode 100644 index 1957530..0000000 --- a/public/modstagram-back/models/LikeModel.js +++ /dev/null @@ -1,25 +0,0 @@ -const mongoose = require('mongoose') -const timestamp = require('mongoose-timestamp') - -const likeSchema = new mongoose.Schema({ - postId: { - type: mongoose.Schema.Types.ObjectId, - ref: 'Post', - required: true - }, - userId: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: true - }, - likes: [{ - type: mongoose.Schema.Types.ObjectId, - ref: 'User' - }] -}) - -// تعریف مدل LikeModel -likeSchema.plugin(timestamp) -const LikeModel = mongoose.model('Like', likeSchema) - -module.exports = LikeModel diff --git a/public/modstagram-back/models/MessageModel.js b/public/modstagram-back/models/MessageModel.js deleted file mode 100644 index 594f7c4..0000000 --- a/public/modstagram-back/models/MessageModel.js +++ /dev/null @@ -1,51 +0,0 @@ -const mongoose = require('mongoose') -const { Schema } = mongoose - -const messageSchema = new Schema({ - senderId: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: true - }, - receiverId: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: true - }, - content: { - type: String, - required: false, - trim: true - }, - file: { - type: String, - required: false - }, - fileType: { - type: String, - enum: ['image', 'video', 'file', 'voice', 'location'], - required: false - }, - replyToId: { - type: mongoose.Schema.Types.ObjectId, - ref: 'Message', - required: false - }, - forwardedFrom: { - userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }, - userName: String, - displayName: String - }, - createdAt: { - type: Date, - default: Date.now - }, - readStatus: { - type: Number, - default: 0 - } -}) - -const MessageModel = mongoose.model('Message', messageSchema) - -module.exports = MessageModel diff --git a/public/modstagram-back/models/NotificationModel.js b/public/modstagram-back/models/NotificationModel.js deleted file mode 100644 index ff79e19..0000000 --- a/public/modstagram-back/models/NotificationModel.js +++ /dev/null @@ -1,37 +0,0 @@ -const mongoose = require('mongoose') -const timestamp = require('mongoose-timestamp') -const mongoosePaginate = require('mongoose-paginate-v2') - -const notificationSchema = new mongoose.Schema({ - user_id: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', // مرجع به مدل کاربر - required: true - }, - project_post_id: { - type: mongoose.Schema.Types.ObjectId, - required: false - }, - type: { - type: String, - required: true - }, - title: { - type: String, - required: true - }, - description: { - type: String, - required: true - }, - read: { - type: Boolean, - default: false // وضعیت خوانده شده یا نشده - } -}) - -notificationSchema.plugin(timestamp) -notificationSchema.plugin(mongoosePaginate) - -const NotificationModel = mongoose.model('Notification', notificationSchema) -module.exports = NotificationModel diff --git a/public/modstagram-back/models/OfferModel.js b/public/modstagram-back/models/OfferModel.js deleted file mode 100644 index ec36550..0000000 --- a/public/modstagram-back/models/OfferModel.js +++ /dev/null @@ -1,32 +0,0 @@ -const mongoose = require('mongoose') -const mongoosePaginate = require('mongoose-paginate-v2') -const timestamp = require('mongoose-timestamp') - -const offerSchema = new mongoose.Schema({ - sender: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: true - }, - receiver: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: true - }, - status: { - type: String, - enum: ['pending', 'accepted', 'rejected'], // وضعیت درخواست - default: 'pending' - }, - transaction_id: { - type: mongoose.Schema.Types.ObjectId, - ref: 'Payment', - default: null - } -}) - -offerSchema.plugin(timestamp) -offerSchema.plugin(mongoosePaginate) - -const OfferModel = mongoose.model('Offer', offerSchema) -module.exports = OfferModel diff --git a/public/modstagram-back/models/OfferTypeModel.js b/public/modstagram-back/models/OfferTypeModel.js deleted file mode 100644 index fa2b49c..0000000 --- a/public/modstagram-back/models/OfferTypeModel.js +++ /dev/null @@ -1,21 +0,0 @@ -const mongoose = require('mongoose') - -const offerTypeModelSchema = new mongoose.Schema({ - name: { - type: String, - required: true, - trim: true, - minLength: 1, - maxLength: 255 - }, - price: { - type: Number, - required: true, - trim: true, - minLength: 1, - maxLength: 255 - } -}) - -const OfferTypeModel = mongoose.model('OfferTypeModel', offerTypeModelSchema) -module.exports = OfferTypeModel diff --git a/public/modstagram-back/models/PaymentModel.js b/public/modstagram-back/models/PaymentModel.js deleted file mode 100644 index c78a252..0000000 --- a/public/modstagram-back/models/PaymentModel.js +++ /dev/null @@ -1,46 +0,0 @@ -const mongoose = require('mongoose') -const timestamp = require('mongoose-timestamp') -const mongoosePaginate = require('mongoose-paginate-v2') - -const paymentSchema = new mongoose.Schema({ - amount: { - type: Number, - required: true - }, - status: { - type: String, - enum: ['pending', 'successful', 'failed'], - default: 'pending' - }, - authority: { - type: String, - required: false - }, - user_id: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User' - }, - project_id: { - type: mongoose.Schema.Types.ObjectId, - ref: 'Project' - }, - advertising_id: { - type: mongoose.Schema.Types.ObjectId, - ref: 'Advertising' - }, - type: { - type: String, - required: true - }, - installment_step: { - type: String, - required: false, - default: null - } -}) - -paymentSchema.plugin(timestamp) -paymentSchema.plugin(mongoosePaginate) - -const PaymentModel = mongoose.model('Payment', paymentSchema) -module.exports = PaymentModel diff --git a/public/modstagram-back/models/PostModel.js b/public/modstagram-back/models/PostModel.js deleted file mode 100644 index ff6d8cc..0000000 --- a/public/modstagram-back/models/PostModel.js +++ /dev/null @@ -1,60 +0,0 @@ -const mongoose = require('mongoose'); -const timestamp = require('mongoose-timestamp'); -const mongoosePaginate = require('mongoose-paginate-v2'); - -const modelSchema = new mongoose.Schema({ - post_images: { - type: [String], // آرایه‌ای از مسیرهای تصاویر - required: false, - default: [], - }, - post_video: { - type: String, // مسیر ویدئو - required: false, - trim: true, - default: null, - }, - type: { - type: String, // نوع پست: 'image' یا 'video' - required: true, - enum: ['image', 'video'], - }, - files: [ - { - path: { type: String, required: true }, - type: { type: String, enum: ['image', 'video'], required: true }, - } - ], - caption: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 1000, - default: null, - }, - status: { - type: String, - required: false, - trim: true, - enum: ['pending', 'accept', 'reject'], - default: 'pending', - }, - user_id: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - }, - likes: [{ - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - }], - comments: { - type: Object, - default: null, - }, -}); - -modelSchema.plugin(timestamp); -modelSchema.plugin(mongoosePaginate); -const PostModel = mongoose.model('Post', modelSchema); -module.exports = PostModel; \ No newline at end of file diff --git a/public/modstagram-back/models/ProjectModel.js b/public/modstagram-back/models/ProjectModel.js deleted file mode 100644 index 4b4382e..0000000 --- a/public/modstagram-back/models/ProjectModel.js +++ /dev/null @@ -1,186 +0,0 @@ -const mongoose = require('mongoose') -const timestamp = require('mongoose-timestamp') -const mongoosePaginate = require('mongoose-paginate-v2') -const projectSchema = new mongoose.Schema({ - title: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - expertise: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - sub_expertise: { - type: [String], // تغییر نوع به آرایه از استرینگ - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - gender: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - age: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - conversation_projects: { - type: Boolean, - required: false, - default: null - }, - province: { - type: Object, - default: null - }, - city: { - type: Object, - default: null - }, - offer_time: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - offer_price: { - type: Number, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - description: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 1024, - default: null - }, - project_type: { - type: String, - enum: ['free', 'normal', 'force', 'highlight'], - default: 'normal' - }, - payment_status: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - // فیلد برای وضعیت پروژه - status: { - type: String, - enum: ['pre_payment', 'paid', 'accepted', 'rejected', 'done', 'cancled', 'ongoing'], - default: 'pre_payment' - }, - public_status: { - type: String, - enum: ['public', 'private'], - default: 'public' - }, - created_for_user: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - default: null - }, - creator_id: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User' - }, - requested_users: [{ - type: mongoose.Schema.Types.ObjectId, - ref: 'User' - }], - selected_user: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - default: null - }, - final_price: { - type: Number, - required: false, - default: null - }, - final_time: { - type: Number, - required: false, - default: null - }, - installments: [{ - installment_number: { - type: Number, - required: true - }, - amount: { - type: Number, - required: true - }, - due_date: { - type: Date, - required: true - } - }], - reject_reason: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 1024, - default: null - }, - ratings: [{ - creator_id: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: true - }, - rating: { - type: Number, - required: true - }, - comment: { - type: String, - trim: true - } - }], - acceptedAt: { - type: Date, - default: null - }, - isExpired: { - type: Boolean, - default: false - } - -}) - -projectSchema.plugin(timestamp) -// اضافه کردن پیجینیشن به مدل -projectSchema.plugin(mongoosePaginate) -const ProjectModel = mongoose.model('Project', projectSchema) -module.exports = ProjectModel diff --git a/public/modstagram-back/models/RequestModel.js b/public/modstagram-back/models/RequestModel.js deleted file mode 100644 index 3049ec1..0000000 --- a/public/modstagram-back/models/RequestModel.js +++ /dev/null @@ -1,33 +0,0 @@ -const mongoose = require('mongoose') -const timestamp = require('mongoose-timestamp') - -const requestSchema = new mongoose.Schema({ - project: { - type: mongoose.Schema.Types.ObjectId, - ref: 'Project', - required: true - }, - user: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: true - }, - time: { - type: Number, - required: true - }, - price: { - type: Number, - required: true - }, - status: { - type: String, - enum: ['pending', 'accepted', 'rejected'], - default: 'pending' - } -}) - -requestSchema.plugin(timestamp) - -const RequestModel = mongoose.model('Request', requestSchema) -module.exports = RequestModel diff --git a/public/modstagram-back/models/SettingsModel.js b/public/modstagram-back/models/SettingsModel.js deleted file mode 100644 index 8d41208..0000000 --- a/public/modstagram-back/models/SettingsModel.js +++ /dev/null @@ -1,19 +0,0 @@ -// models/Setting.js -const mongoose = require('mongoose') -const timestamp = require('mongoose-timestamp') - -const settingSchema = new mongoose.Schema({ - key: { - type: String, - required: true, - unique: true - }, - value: { - type: String, - required: true - } -}) -settingSchema.plugin(timestamp) - -const SettingModel = mongoose.model('Setting', settingSchema) -module.exports = SettingModel diff --git a/public/modstagram-back/models/StateCity.js b/public/modstagram-back/models/StateCity.js deleted file mode 100644 index 5f24232..0000000 --- a/public/modstagram-back/models/StateCity.js +++ /dev/null @@ -1,19 +0,0 @@ -const mongoose = require('mongoose') - -const provincesSchema = new mongoose.Schema({ - id: Number, - name: String, - slug: String -}) - -const citiesSchema = new mongoose.Schema({ - id: Number, - name: String, - slug: String, - province_id: Number -}) - -const ProvinceModel = mongoose.model('Province', provincesSchema) -const CityModel = mongoose.model('City', citiesSchema) - -module.exports = { ProvinceModel, CityModel } diff --git a/public/modstagram-back/models/TaxModel.js b/public/modstagram-back/models/TaxModel.js deleted file mode 100644 index 70b27e7..0000000 --- a/public/modstagram-back/models/TaxModel.js +++ /dev/null @@ -1,15 +0,0 @@ -const mongoose = require("mongoose"); -const timestamp = require("mongoose-timestamp"); -const mongoosePaginate = require("mongoose-paginate-v2"); - -const modelSchema = new mongoose.Schema({ - type: { type: String, enum: ["course", "product", "service"], required: true }, - tax: { type: Number, required: true, default: 9 }, // درصد مالیات - is_active: { type: Boolean, default: true }, - -}); - -modelSchema.plugin(timestamp); -modelSchema.plugin(mongoosePaginate); -const PostModel = mongoose.model("Tax", modelSchema); -module.exports = PostModel; diff --git a/public/modstagram-back/models/TicketMessageModel.js b/public/modstagram-back/models/TicketMessageModel.js deleted file mode 100644 index b054d05..0000000 --- a/public/modstagram-back/models/TicketMessageModel.js +++ /dev/null @@ -1,20 +0,0 @@ -const mongoose = require('mongoose') -const timestamp = require('mongoose-timestamp') -const mongoosePaginate = require('mongoose-paginate-v2') - -const ticketMessageSchema = new mongoose.Schema({ - text: { type: String, required: false }, - file: { - type: String, // مسیر فایل در ذخیره شود - required: false // فایل اختیاری است - }, - senderType: { type: String, enum: ['User', 'Admin'], required: true }, - senderId: { type: mongoose.Schema.Types.ObjectId, refPath: 'senderType', required: true }, - ticket: { type: mongoose.Schema.Types.ObjectId, ref: 'Ticket', required: true } -}) - -ticketMessageSchema.plugin(timestamp) -// اضافه کردن پیجینیشن به مدل -ticketMessageSchema.plugin(mongoosePaginate) -const TicketMessageModel = mongoose.model('TicketMessage', ticketMessageSchema) -module.exports = TicketMessageModel diff --git a/public/modstagram-back/models/TicketModel.js b/public/modstagram-back/models/TicketModel.js deleted file mode 100644 index 4157fb3..0000000 --- a/public/modstagram-back/models/TicketModel.js +++ /dev/null @@ -1,24 +0,0 @@ -const mongoose = require('mongoose') -const timestamp = require('mongoose-timestamp') -const mongoosePaginate = require('mongoose-paginate-v2') - -const ticketSchema = new mongoose.Schema({ - title: { type: String, required: true }, - status: { type: String, enum: ['Pending', 'Answered', 'Customer Response', 'Closed'], default: 'Pending' }, - user: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true }, - new_message: { - type: Boolean, - default: false // وضعیت خوانده شده یا نشده - } -}) - -ticketSchema.pre('save', function (next) { - this.updatedAt = Date.now() - next() -}) - -ticketSchema.plugin(timestamp) -// اضافه کردن پیجینیشن به مدل -ticketSchema.plugin(mongoosePaginate) -const TicketModel = mongoose.model('Ticket', ticketSchema) -module.exports = TicketModel diff --git a/public/modstagram-back/models/TypeAndPriceModel.js b/public/modstagram-back/models/TypeAndPriceModel.js deleted file mode 100644 index 2b059d1..0000000 --- a/public/modstagram-back/models/TypeAndPriceModel.js +++ /dev/null @@ -1,21 +0,0 @@ -const mongoose = require('mongoose') - -const typeAndPriceSchema = new mongoose.Schema({ - name: { - type: String, - required: true, - trim: true, - minLength: 1, - maxLength: 255 - }, - price: { - type: Number, - required: true, - trim: true, - minLength: 1, - maxLength: 255 - } -}) - -const TypeAndPriceModel = mongoose.model('TypeAndPrice', typeAndPriceSchema) -module.exports = TypeAndPriceModel diff --git a/public/modstagram-back/models/UserModel.js b/public/modstagram-back/models/UserModel.js deleted file mode 100644 index 66b025a..0000000 --- a/public/modstagram-back/models/UserModel.js +++ /dev/null @@ -1,381 +0,0 @@ -const mongoose = require('mongoose') -const mongoosePaginate = require('mongoose-paginate-v2') -const timestamp = require('mongoose-timestamp') -const userSchema = new mongoose.Schema({ - mobile: { - type: String, - required: false, - trim: true, - unique: true - }, - otp: { - type: String, - required: false, - trim: true, - minLength: 6, - maxLength: 6, - default: null - }, - user_name: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - password: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - first_name: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - last_name: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - user_type: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - is_verified: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: 'none' - }, - profile_image: { - type: String, - required: false, - trim: true, - default: null - }, - national_card_image: { - type: String, - required: false, - trim: true, - default: null - }, - expertise: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - sub_expertise: { - type: [String], // تغییر نوع به آرایه از استرینگ - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - gender: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - height: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - weight: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - size: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - eye_color: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - hair_color: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - cooperation_type: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - cooperation_abroad: { - type: Boolean, - required: false, - default: null - }, - conversation_projects: { - type: Boolean, - required: false, - default: null - }, - bio: { - type: String, - required: false, - minLength: 1, - maxLength: 1024, - default: null - }, - national_code: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - birthday: { - type: Date, - required: false, - default: null - }, - is_Register: { - type: String, - - default: false - }, - shaba: { - type: String, - required: false, - trim: true, - minLength: 1, - maxLength: 255, - default: null - }, - address: { - type: String, - trim: true, - minLength: 1, - maxLength: 512, - default: null - }, - province: { - type: Object, - default: null - }, - city: { - type: Object, - default: null - }, - lat: { - type: String, - trim: true, - minLength: 1, - maxLength: 512, - default: null - }, - lng: { - type: String, - trim: true, - minLength: 1, - maxLength: 512, - default: null - }, - show_location: { - type: Boolean, - required: false, - default: null - }, - rate: { - type: String, - trim: true, - maxLength: 512, - default: null - }, - referral_code: { - type: String, - trim: true, - minLength: 1, - maxLength: 512, - default: null - }, - shop_id: { - type: mongoose.Schema.Types.ObjectId, - ref: 'Shop', - default: null - }, - last_online: { - type: Date, // ذخیره تاریخ و زمان آخرین بازدید - default: Date.now // تنظیم تاریخ به تاریخ فعلی - }, - business_license: { - type: String, - required: false, - trim: true, - default: null - }, - user_level: { - type: String, - trim: true, - minLength: 1, - maxLength: 512, - default: null - }, - user_score: { - type: String, - trim: true, - minLength: 1, - maxLength: 512, - default: null - }, - last_post: { - type: Object, - default: null - }, - // user_ratings: [{ - // project_id: { - // type: mongoose.Schema.Types.ObjectId, - // ref: 'Project', - // required: true - // }, - // creator_id: { - // type: mongoose.Schema.Types.ObjectId, - // ref: 'User', - // required: true - // }, - // rating: { - // type: Number, - // required: true - // }, - // comment: { - // type: String, - // trim: true - // } - // }], - daily_free_request: { - type: Number, - default: 1 - }, - last_free_request_date: { - type: Date, - default: null - }, - blocked_by: [{ - type: mongoose.Schema.Types.ObjectId, - ref: 'User' - }], - blocked_users: [{ - type: mongoose.Schema.Types.ObjectId, - ref: 'User' - }], - block_status: { - type: Boolean, - required: false, - default: null - }, - advertising_profiles: [{ - type: mongoose.Schema.Types.ObjectId, - ref: 'AdvertisingProfile' - }], - services: [{ - title: { - type: String, - required: true, - trim: true - }, - originalPrice: { - type: String, - required: true - }, - discountPrice: { - type: String, - required: false - }, - discountPercentage: { - type: Number, - required: false - }, - status: { - type: String, - default: "UnderReview", - required: false - }, - image: { - type: String, - required: false, - trim: true - } - }], - monthly_free_offer: { - type: Number, - default: 1 - }, - last_free_offer_date: { - type: Date, - default: null - } - // contactInfo: { - // phone: String, - // mobile: String, - // telegramLink: String, - // whatsappNumber: String, - // instagramLink: String, - // saveInfoForNextAds: { type: Boolean, default: false } - // }, - // adTotalRatings: { - // type: Number, - // default: 0 - // }, - // adRatingsCount: { - // type: Number, - // default: 0 - // }, - // adAverageRating: { - // type: Number, - // default: 0 - // } -}) - -userSchema.plugin(timestamp) -userSchema.plugin(mongoosePaginate) -const UserModel = mongoose.model('User', userSchema) -module.exports = UserModel diff --git a/public/modstagram-back/models/VersionModel.js b/public/modstagram-back/models/VersionModel.js deleted file mode 100644 index 51aaf0b..0000000 --- a/public/modstagram-back/models/VersionModel.js +++ /dev/null @@ -1,12 +0,0 @@ -// models/VersionModel.js -const mongoose = require('mongoose') - -const versionSchema = new mongoose.Schema({ - version: { type: String, required: true }, - mandatory: { type: Boolean, required: true }, - releaseNotes: { type: String }, - updateUrls: { type: [String], required: true } // لینک‌های آپدیت -}) - -const VersionModel = mongoose.model('Version', versionSchema) -module.exports = VersionModel diff --git a/public/modstagram-back/models/license.js b/public/modstagram-back/models/license.js deleted file mode 100644 index 13c59a2..0000000 --- a/public/modstagram-back/models/license.js +++ /dev/null @@ -1,14 +0,0 @@ -const mongoose = require('mongoose') -const mongoosePaginate = require('mongoose-paginate-v2') -const timestamp = require('mongoose-timestamp') -const license = new mongoose.Schema({ - - userId : String, - Confirmation : { type : Boolean, default : false}, - licenseImg : { type : String }, -}) - -license.plugin(timestamp) -license.plugin(mongoosePaginate) -const LicenseMoldel = mongoose.model('license', license) -module.exports = LicenseMoldel diff --git a/public/modstagram-back/modstagram-back@1.0.0 b/public/modstagram-back/modstagram-back@1.0.0 deleted file mode 100644 index e69de29..0000000 diff --git a/public/modstagram-back/nodemon.json b/public/modstagram-back/nodemon.json deleted file mode 100644 index e76d883..0000000 --- a/public/modstagram-back/nodemon.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "watch": ["*.js"], - "ext": "js", - "ignore": [], - "exec": "node server.js" -} diff --git a/public/modstagram-back/package-lock.json b/public/modstagram-back/package-lock.json deleted file mode 100644 index cbd9e5c..0000000 --- a/public/modstagram-back/package-lock.json +++ /dev/null @@ -1,5576 +0,0 @@ -{ - "name": "modstagram-back", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "modstagram-back", - "version": "1.0.0", - "license": "ISC", - "dependencies": { - "axios": "^1.6.7", - "bcryptjs": "^2.4.3", - "body-parser": "^1.20.2", - "cors": "^2.8.5", - "dotenv": "^16.4.5", - "express": "^4.18.3", - "express-form-data": "^2.0.23", - "express-rate-limit": "^7.2.0", - "express-session": "^1.18.0", - "express-validator": "^7.0.1", - "helmet": "^7.1.0", - "jsonwebtoken": "^9.0.2", - "lodash": "^4.17.21", - "moment-jalaali": "^0.10.0", - "mongoose": "^8.2.1", - "mongoose-paginate-v2": "^1.8.0", - "mongoose-timestamp": "^0.6.0", - "multer": "^2.0.2", - "node-cron": "^3.0.3", - "nodemon": "^3.1.0", - "socket.io": "^4.7.5", - "socket.io-client": "^4.7.5" - }, - "devDependencies": { - "cross-env": "^7.0.3", - "eslint": "^8.57.0", - "eslint-config-standard": "^17.1.0", - "eslint-plugin-import": "^2.29.1", - "eslint-plugin-n": "^16.6.2", - "eslint-plugin-promise": "^6.1.1", - "webpack": "^5.90.3", - "webpack-cli": "^5.1.4" - } - }, - "node_modules/@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@discoveryjs/json-ext": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", - "dev": true, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", - "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", - "dev": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", - "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", - "dev": true - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", - "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@mongodb-js/saslprep": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.5.tgz", - "integrity": "sha512-XLNOMH66KhJzUJNwT/qlMnS4WsNDWD5ASdyaSH3EtK+F4r/CFGa3jT4GNi4mfOitGvWXtdLgQJkQjxSVrio+jA==", - "dependencies": { - "sparse-bitfield": "^3.0.3" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@socket.io/component-emitter": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", - "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==" - }, - "node_modules/@types/cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==" - }, - "node_modules/@types/cors": { - "version": "2.8.17", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", - "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/eslint": { - "version": "8.56.5", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.5.tgz", - "integrity": "sha512-u5/YPJHo1tvkSF2CE0USEkxon82Z5DBy2xR+qfyYNszpX9qcs4sT6uq2kBbj4BXY1+DBGDPnrhMZV3pKWGNukw==", - "dev": true, - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/eslint-scope": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", - "dev": true, - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true - }, - "node_modules/@types/node": { - "version": "20.11.25", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.25.tgz", - "integrity": "sha512-TBHyJxk2b7HceLVGFcpAUjsa5zIdsPWlR6XHfyGzd0SFu+/NFgQgMAl96MSDZgQDvJAvV6BKsFOrt6zIL09JDw==", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@types/webidl-conversions": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", - "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==" - }, - "node_modules/@types/whatwg-url": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.4.tgz", - "integrity": "sha512-lXCmTWSHJvf0TRSO58nm978b8HJ/EdsSsEKLd3ODHFjo+3VGAyyTp4v50nWvwtzBxSMQrVOK7tcuN0zGPLICMw==", - "dependencies": { - "@types/webidl-conversions": "*" - } - }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, - "node_modules/@webassemblyjs/ast": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", - "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", - "dev": true, - "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" - } - }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", - "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", - "dev": true, - "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", - "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6" - } - }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", - "dev": true, - "dependencies": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", - "dev": true, - "dependencies": { - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", - "dev": true - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", - "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-opt": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6", - "@webassemblyjs/wast-printer": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", - "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", - "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", - "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", - "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webpack-cli/configtest": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", - "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", - "dev": true, - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - } - }, - "node_modules/@webpack-cli/info": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", - "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", - "dev": true, - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - } - }, - "node_modules/@webpack-cli/serve": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", - "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", - "dev": true, - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - }, - "peerDependenciesMeta": { - "webpack-dev-server": { - "optional": true - } - } - }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true - }, - "node_modules/abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-import-assertions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", - "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", - "dev": true, - "peerDependencies": { - "acorn": "^8" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/append-field": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", - "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==", - "license": "MIT" - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" - }, - "node_modules/array-includes": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", - "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.filter": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array.prototype.filter/-/array.prototype.filter-1.0.3.tgz", - "integrity": "sha512-VizNcj/RGJiUyQBgzwxzE5oHdeuXY5hSbbmKMlphj1cy1Vl7Pn2asCGbSrru6hSQjmCzqTBPVWAF/whmEOVHbw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-array-method-boxes-properly": "^1.0.0", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.findlastindex": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.4.tgz", - "integrity": "sha512-hzvSHUshSpCflDR1QMUBLHGHP1VIEBegT4pix9H/Z92Xw3ySoy6c2qh7lJWTJnRJ8JCZ9bJNCgTyYaJGcJu6xQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.3.0", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", - "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", - "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", - "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", - "dev": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.2.1", - "get-intrinsic": "^1.2.3", - "is-array-buffer": "^3.0.4", - "is-shared-array-buffer": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "dev": true, - "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/axios": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", - "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", - "dependencies": { - "follow-redirects": "^1.15.4", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "node_modules/base64id": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", - "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", - "engines": { - "node": "^4.5.0 || >= 5.9" - } - }, - "node_modules/bcryptjs": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", - "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==" - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", - "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001587", - "electron-to-chromium": "^1.4.668", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/bson": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/bson/-/bson-6.4.0.tgz", - "integrity": "sha512-6/gSSEdbkuFlSb+ufj5jUSU4+wo8xQOwm2bDSqwmxiPE17JTpsP63eAwoN8iF8Oy4gJYj+PAL3zdRCTdaw5Y1g==", - "engines": { - "node": ">=16.20.1" - } - }, - "node_modules/buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" - }, - "node_modules/builtin-modules": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", - "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/builtins": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", - "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", - "dev": true, - "dependencies": { - "semver": "^7.0.0" - } - }, - "node_modules/builtins/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/busboy": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", - "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", - "dependencies": { - "streamsearch": "^1.1.0" - }, - "engines": { - "node": ">=10.16.0" - } - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001596", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001596.tgz", - "integrity": "sha512-zpkZ+kEr6We7w63ORkoJ2pOfBwBkY/bJrG/UZ90qNb45Isblu8wzDgevEOrRL1r9dWayHjYiiyCMEXPn4DweGQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ] - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", - "dev": true, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" - }, - "node_modules/concat-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", - "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", - "engines": [ - "node >= 6.0" - ], - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.0.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/connect-multiparty": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/connect-multiparty/-/connect-multiparty-2.2.0.tgz", - "integrity": "sha512-zKcpA7cuXGEhuw9Pz7JmVCFmp85jzGLGm/iiagXTwyEAJp4ypLPtRS/V4IGuGb9KjjrgHBs6P/gDCpZHnFzksA==", - "dependencies": { - "http-errors": "~1.7.0", - "multiparty": "~4.2.1", - "on-finished": "~2.3.0", - "qs": "~6.5.2", - "type-is": "~1.6.16" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/connect-multiparty/node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/connect-multiparty/node_modules/http-errors": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", - "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/connect-multiparty/node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/connect-multiparty/node_modules/qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/connect-multiparty/node_modules/setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" - }, - "node_modules/connect-multiparty/node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/connect-multiparty/node_modules/toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" - }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "license": "MIT", - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/cross-env": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", - "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.1" - }, - "bin": { - "cross-env": "src/bin/cross-env.js", - "cross-env-shell": "src/bin/cross-env-shell.js" - }, - "engines": { - "node": ">=10.14", - "npm": ">=6", - "yarn": ">=1" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/defaults": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", - "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", - "dependencies": { - "clone": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/dotenv": { - "version": "16.4.5", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", - "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" - } - }, - "node_modules/ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" - }, - "node_modules/electron-to-chromium": { - "version": "1.4.699", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.699.tgz", - "integrity": "sha512-I7q3BbQi6e4tJJN5CRcyvxhK0iJb34TV8eJQcgh+fR2fQ8miMgZcEInckCo1U9exDHbfz7DLDnFn8oqH/VcRKw==", - "dev": true - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/engine.io": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.4.tgz", - "integrity": "sha512-KdVSDKhVKyOi+r5uEabrDLZw2qXStVvCsEB/LN3mw4WFi6Gx50jTyuxYVCwAAC0U46FdnzP/ScKRBTXb/NiEOg==", - "dependencies": { - "@types/cookie": "^0.4.1", - "@types/cors": "^2.8.12", - "@types/node": ">=10.0.0", - "accepts": "~1.3.4", - "base64id": "2.0.0", - "cookie": "~0.4.1", - "cors": "~2.8.5", - "debug": "~4.3.1", - "engine.io-parser": "~5.2.1", - "ws": "~8.11.0" - }, - "engines": { - "node": ">=10.2.0" - } - }, - "node_modules/engine.io-client": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.3.tgz", - "integrity": "sha512-9Z0qLB0NIisTRt1DZ/8U2k12RJn8yls/nXMZLn+/N8hANT3TcYjKFKcwbw5zFQiN4NTde3TSY9zb79e1ij6j9Q==", - "dependencies": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.1", - "engine.io-parser": "~5.2.1", - "ws": "~8.11.0", - "xmlhttprequest-ssl": "~2.0.0" - } - }, - "node_modules/engine.io-parser": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.2.tgz", - "integrity": "sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw==", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/engine.io/node_modules/cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/enhanced-resolve": { - "version": "5.15.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.1.tgz", - "integrity": "sha512-3d3JRbwsCLJsYgvb6NuWEG44jjPSOMuS73L/6+7BZuoKm3W+qXnSoIYVHi8dG7Qcg4inAY4jbzkZ7MnskePeDg==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/envinfo": { - "version": "7.11.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.11.1.tgz", - "integrity": "sha512-8PiZgZNIB4q/Lw4AhOvAfB/ityHAd2bli3lESSWmWSzSsl5dKpy5N1d1Rfkd2teq/g9xN90lc6o98DOjMeYHpg==", - "dev": true, - "bin": { - "envinfo": "dist/cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/es-abstract": { - "version": "1.22.5", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.5.tgz", - "integrity": "sha512-oW69R+4q2wG+Hc3KZePPZxOiisRIqfKBVo/HLx94QcJeWGU/8sZhCvc829rd1kS366vlJbzBfXf9yWwf0+Ko7w==", - "dev": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "arraybuffer.prototype.slice": "^1.0.3", - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "es-set-tostringtag": "^2.0.3", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.4", - "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", - "hasown": "^2.0.1", - "internal-slot": "^1.0.7", - "is-array-buffer": "^3.0.4", - "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.3", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.13", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", - "object-keys": "^1.1.1", - "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.0", - "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.8", - "string.prototype.trimend": "^1.0.7", - "string.prototype.trimstart": "^1.0.7", - "typed-array-buffer": "^1.0.2", - "typed-array-byte-length": "^1.0.1", - "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.5", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.14" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-array-method-boxes-properly": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", - "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", - "dev": true - }, - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-module-lexer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", - "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==", - "dev": true - }, - "node_modules/es-set-tostringtag": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.2.4", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-shim-unscopables": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", - "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", - "dev": true, - "dependencies": { - "hasown": "^2.0.0" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-compat-utils": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.1.2.tgz", - "integrity": "sha512-Jia4JDldWnFNIru1Ehx1H5s9/yxiRHY/TimCuUc0jNexew3cF1gI6CYZil1ociakfWO3rRqFjl1mskBblB3RYg==", - "dev": true, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "eslint": ">=6.0.0" - } - }, - "node_modules/eslint-config-standard": { - "version": "17.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.1.0.tgz", - "integrity": "sha512-IwHwmaBNtDK4zDHQukFDW5u/aTb8+meQWZvNFWkiGmbWjD6bqyuSSBxxXKkCftCUzc1zwCH2m/baCNDLGmuO5Q==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "eslint": "^8.0.1", - "eslint-plugin-import": "^2.25.2", - "eslint-plugin-n": "^15.0.0 || ^16.0.0 ", - "eslint-plugin-promise": "^6.0.0" - } - }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", - "dev": true, - "dependencies": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/eslint-module-utils": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", - "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", - "dev": true, - "dependencies": { - "debug": "^3.2.7" - }, - "engines": { - "node": ">=4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } - } - }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-module-utils/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/eslint-plugin-es-x": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.5.0.tgz", - "integrity": "sha512-ODswlDSO0HJDzXU0XvgZ3lF3lS3XAZEossh15Q2UHjwrJggWeBoKqqEsLTZLXl+dh5eOAozG0zRcYtuE35oTuQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.1.2", - "@eslint-community/regexpp": "^4.6.0", - "eslint-compat-utils": "^0.1.2" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ota-meshi" - }, - "peerDependencies": { - "eslint": ">=8" - } - }, - "node_modules/eslint-plugin-import": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", - "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", - "dev": true, - "dependencies": { - "array-includes": "^3.1.7", - "array.prototype.findlastindex": "^1.2.3", - "array.prototype.flat": "^1.3.2", - "array.prototype.flatmap": "^1.3.2", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.8.0", - "hasown": "^2.0.0", - "is-core-module": "^2.13.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.7", - "object.groupby": "^1.0.1", - "object.values": "^1.1.7", - "semver": "^6.3.1", - "tsconfig-paths": "^3.15.0" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" - } - }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/eslint-plugin-n": { - "version": "16.6.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.6.2.tgz", - "integrity": "sha512-6TyDmZ1HXoFQXnhCTUjVFULReoBPOAjpuiKELMkeP40yffI/1ZRO+d9ug/VC6fqISo2WkuIBk3cvuRPALaWlOQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "builtins": "^5.0.1", - "eslint-plugin-es-x": "^7.5.0", - "get-tsconfig": "^4.7.0", - "globals": "^13.24.0", - "ignore": "^5.2.4", - "is-builtin-module": "^3.2.1", - "is-core-module": "^2.12.1", - "minimatch": "^3.1.2", - "resolve": "^1.22.2", - "semver": "^7.5.3" - }, - "engines": { - "node": ">=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-plugin-n/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint-plugin-promise": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz", - "integrity": "sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - } - }, - "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true, - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/express": { - "version": "4.18.3", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.3.tgz", - "integrity": "sha512-6VyCijWQ+9O7WuVMTRBTl+cjNNIzD5cY5mQ1WM8r/LEkI2u8EYpOotESNwzNlyCn3g+dmjKYI6BmNneSr/FSRw==", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.2", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/express-form-data": { - "version": "2.0.23", - "resolved": "https://registry.npmjs.org/express-form-data/-/express-form-data-2.0.23.tgz", - "integrity": "sha512-Efm2t+xL6vEqUPs4kAyBY9xG/8LGpbSVnnFLZw6HgdxHzSRlg2/sNlA2UdMlcIKMH+LDOn7NKXUDGJK125F4rw==", - "dependencies": { - "connect-multiparty": "^2.2.0", - "fs-extra": "^9.1.0", - "signal-exit": "^3.0.7" - }, - "engines": { - "node": ">=10.7.0" - } - }, - "node_modules/express-rate-limit": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.2.0.tgz", - "integrity": "sha512-T7nul1t4TNyfZMJ7pKRKkdeVJWa2CqB8NA1P8BwYaoDI5QSBZARv5oMS43J7b7I5P+4asjVXjb7ONuwDKucahg==", - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://github.com/sponsors/express-rate-limit" - }, - "peerDependencies": { - "express": "4 || 5 || ^5.0.0-beta.1" - } - }, - "node_modules/express-session": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.18.0.tgz", - "integrity": "sha512-m93QLWr0ju+rOwApSsyso838LQwgfs44QtOP/WBiwtAgPIo/SAh1a5c6nn2BR6mFNZehTpqKDESzP+fRHVbxwQ==", - "dependencies": { - "cookie": "0.6.0", - "cookie-signature": "1.0.7", - "debug": "2.6.9", - "depd": "~2.0.0", - "on-headers": "~1.0.2", - "parseurl": "~1.3.3", - "safe-buffer": "5.2.1", - "uid-safe": "~2.1.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/express-session/node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/express-session/node_modules/cookie-signature": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz", - "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==" - }, - "node_modules/express-session/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/express-session/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/express-validator": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/express-validator/-/express-validator-7.0.1.tgz", - "integrity": "sha512-oB+z9QOzQIE8FnlINqyIFA8eIckahC6qc8KtqLdLJcU3/phVyuhXH3bA4qzcrhme+1RYaCSwrq+TlZ/kAKIARA==", - "dependencies": { - "lodash": "^4.17.21", - "validator": "^13.9.0" - }, - "engines": { - "node": ">= 8.0.0" - } - }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "node_modules/fastest-levenshtein": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", - "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", - "dev": true, - "engines": { - "node": ">= 4.9.1" - } - }, - "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true, - "bin": { - "flat": "cli.js" - } - }, - "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true - }, - "node_modules/follow-redirects": { - "version": "1.15.5", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", - "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "dependencies": { - "is-callable": "^1.1.3" - } - }, - "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-symbol-description": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", - "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.5", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-tsconfig": { - "version": "4.7.3", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.3.tgz", - "integrity": "sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==", - "dev": true, - "dependencies": { - "resolve-pkg-maps": "^1.0.0" - }, - "funding": { - "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true - }, - "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "dev": true, - "dependencies": { - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", - "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/helmet": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/helmet/-/helmet-7.1.0.tgz", - "integrity": "sha512-g+HZqgfbpXdCkme/Cd/mZkV0aV3BZZZSugecH03kl38m/Kmdx8jKjBikpDj2cr+Iynv4KpYEviojNdTJActJAg==", - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/ignore-by-default": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==" - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", - "dev": true, - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/internal-slot": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", - "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", - "dev": true, - "dependencies": { - "es-errors": "^1.3.0", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/interpret": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", - "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", - "dev": true, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-array-buffer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", - "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-builtin-module": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", - "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", - "dev": true, - "dependencies": { - "builtin-modules": "^3.3.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", - "dev": true, - "dependencies": { - "hasown": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-negative-zero": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", - "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", - "dev": true, - "dependencies": { - "which-typed-array": "^1.1.14" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/jalaali-js": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/jalaali-js/-/jalaali-js-1.2.6.tgz", - "integrity": "sha512-io974va+Qyu+UfuVX3UIAgJlxLhAMx9Y8VMfh+IG00Js7hXQo1qNQuwSiSa0xxco0SVgx5HWNkaiCcV+aZ8WPw==" - }, - "node_modules/jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "dev": true, - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/jsonwebtoken": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", - "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", - "dependencies": { - "jws": "^3.2.2", - "lodash.includes": "^4.3.0", - "lodash.isboolean": "^3.0.3", - "lodash.isinteger": "^4.0.4", - "lodash.isnumber": "^3.0.3", - "lodash.isplainobject": "^4.0.6", - "lodash.isstring": "^4.0.1", - "lodash.once": "^4.0.0", - "ms": "^2.1.1", - "semver": "^7.5.4" - }, - "engines": { - "node": ">=12", - "npm": ">=6" - } - }, - "node_modules/jsonwebtoken/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "dependencies": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "dependencies": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/kareem": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.5.1.tgz", - "integrity": "sha512-7jFxRVm+jD+rkq3kY0iZDJfsO2/t4BBPeEb2qKn2lR/9KhuksYk5hxzfRYWMPV8P/x2d0kHD306YyWLzjjH+uA==", - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", - "dev": true, - "engines": { - "node": ">=6.11.5" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/lodash.includes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", - "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" - }, - "node_modules/lodash.isboolean": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", - "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" - }, - "node_modules/lodash.isinteger": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", - "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" - }, - "node_modules/lodash.isnumber": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", - "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" - }, - "node_modules/lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" - }, - "node_modules/lodash.isstring": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/lodash.once": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/memory-pager": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", - "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==" - }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "license": "MIT", - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/moment": { - "version": "2.30.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", - "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", - "engines": { - "node": "*" - } - }, - "node_modules/moment-jalaali": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/moment-jalaali/-/moment-jalaali-0.10.0.tgz", - "integrity": "sha512-XICH1+UHd3zyaE1bXWQBlhoXBqbzEyFfT0TrifNobHxLALRuTSwXn376bX8FmkYg9mZimevwwdd6EB57s5wuFA==", - "dependencies": { - "jalaali-js": "^1.1.0", - "moment": "^2.22.2", - "moment-timezone": "^0.5.21", - "rimraf": "^3.0.2" - } - }, - "node_modules/moment-timezone": { - "version": "0.5.45", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.45.tgz", - "integrity": "sha512-HIWmqA86KcmCAhnMAN0wuDOARV/525R2+lOLotuGFzn4HO+FH+/645z2wx0Dt3iDv6/p61SIvKnDstISainhLQ==", - "dependencies": { - "moment": "^2.29.4" - }, - "engines": { - "node": "*" - } - }, - "node_modules/mongodb": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.3.0.tgz", - "integrity": "sha512-tt0KuGjGtLUhLoU263+xvQmPHEGTw5LbcNC73EoFRYgSHwZt5tsoJC110hDyO1kjQzpgNrpdcSza9PknWN4LrA==", - "dependencies": { - "@mongodb-js/saslprep": "^1.1.0", - "bson": "^6.2.0", - "mongodb-connection-string-url": "^3.0.0" - }, - "engines": { - "node": ">=16.20.1" - }, - "peerDependencies": { - "@aws-sdk/credential-providers": "^3.188.0", - "@mongodb-js/zstd": "^1.1.0", - "gcp-metadata": "^5.2.0", - "kerberos": "^2.0.1", - "mongodb-client-encryption": ">=6.0.0 <7", - "snappy": "^7.2.2", - "socks": "^2.7.1" - }, - "peerDependenciesMeta": { - "@aws-sdk/credential-providers": { - "optional": true - }, - "@mongodb-js/zstd": { - "optional": true - }, - "gcp-metadata": { - "optional": true - }, - "kerberos": { - "optional": true - }, - "mongodb-client-encryption": { - "optional": true - }, - "snappy": { - "optional": true - }, - "socks": { - "optional": true - } - } - }, - "node_modules/mongodb-connection-string-url": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.0.tgz", - "integrity": "sha512-t1Vf+m1I5hC2M5RJx/7AtxgABy1cZmIPQRMXw+gEIPn/cZNF3Oiy+l0UIypUwVB5trcWHq3crg2g3uAR9aAwsQ==", - "dependencies": { - "@types/whatwg-url": "^11.0.2", - "whatwg-url": "^13.0.0" - } - }, - "node_modules/mongoose": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.2.1.tgz", - "integrity": "sha512-UgZZbXSJH0pdU936qj3FyVI+sBsMoGowFnL5R/RYrA50ayn6+ZYdVr8ehsRgNxRcMYwoNld5XzHIfkFRJTePEw==", - "dependencies": { - "bson": "^6.2.0", - "kareem": "2.5.1", - "mongodb": "6.3.0", - "mpath": "0.9.0", - "mquery": "5.0.0", - "ms": "2.1.3", - "sift": "16.0.1" - }, - "engines": { - "node": ">=16.20.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mongoose" - } - }, - "node_modules/mongoose-paginate-v2": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/mongoose-paginate-v2/-/mongoose-paginate-v2-1.8.0.tgz", - "integrity": "sha512-JiGbGxc/ytIA8UL4GaJdCLuxv5i99+XmTdP4v9YXwiJ85tdOxdrc2NQJL+0O+NRbIl+aAhaOnDbL9bJt7o3zIA==", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/mongoose-timestamp": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/mongoose-timestamp/-/mongoose-timestamp-0.6.0.tgz", - "integrity": "sha512-H0f/x2z7yvIiijP3UaE6bsSTP71WqVxn8GR8OOYKUSWmf+U1mD1K+QeEQ5BlYl6zbp/l/19F8sHXA/vUAyDnRg==", - "dependencies": { - "defaults": "^1.0.3" - } - }, - "node_modules/mongoose/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/mpath": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", - "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/mquery": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz", - "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==", - "dependencies": { - "debug": "4.x" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/multer": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/multer/-/multer-2.0.2.tgz", - "integrity": "sha512-u7f2xaZ/UG8oLXHvtF/oWTRvT44p9ecwBBqTwgJVq0+4BW1g8OW01TyMEGWBHbyMOYVHXslaut7qEQ1meATXgw==", - "license": "MIT", - "dependencies": { - "append-field": "^1.0.0", - "busboy": "^1.6.0", - "concat-stream": "^2.0.0", - "mkdirp": "^0.5.6", - "object-assign": "^4.1.1", - "type-is": "^1.6.18", - "xtend": "^4.0.2" - }, - "engines": { - "node": ">= 10.16.0" - } - }, - "node_modules/multiparty": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/multiparty/-/multiparty-4.2.3.tgz", - "integrity": "sha512-Ak6EUJZuhGS8hJ3c2fY6UW5MbkGUPMBEGd13djUzoY/BHqV/gTuFWtC6IuVA7A2+v3yjBS6c4or50xhzTQZImQ==", - "dependencies": { - "http-errors": "~1.8.1", - "safe-buffer": "5.2.1", - "uid-safe": "2.1.5" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/multiparty/node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/multiparty/node_modules/http-errors": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", - "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/multiparty/node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "node_modules/node-cron": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/node-cron/-/node-cron-3.0.3.tgz", - "integrity": "sha512-dOal67//nohNgYWb+nWmg5dkFdIwDm8EpeGYMekPMrngV3637lqnX0lbUcCtgibHTz6SEz7DAIjKvKDFYCnO1A==", - "dependencies": { - "uuid": "8.3.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dev": true - }, - "node_modules/nodemon": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.0.tgz", - "integrity": "sha512-xqlktYlDMCepBJd43ZQhjWwMw2obW/JRvkrLxq5RCNcuDDX1DbcPT+qT1IlIIdf+DhnWs90JpTMe+Y5KxOchvA==", - "dependencies": { - "chokidar": "^3.5.2", - "debug": "^4", - "ignore-by-default": "^1.0.1", - "minimatch": "^3.1.2", - "pstree.remy": "^1.1.8", - "semver": "^7.5.3", - "simple-update-notifier": "^2.0.0", - "supports-color": "^5.5.0", - "touch": "^3.1.0", - "undefsafe": "^2.0.5" - }, - "bin": { - "nodemon": "bin/nodemon.js" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/nodemon" - } - }, - "node_modules/nodemon/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "engines": { - "node": ">=4" - } - }, - "node_modules/nodemon/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/nodemon/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/nopt": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", - "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": "*" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.fromentries": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", - "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.groupby": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.2.tgz", - "integrity": "sha512-bzBq58S+x+uo0VjurFT0UktpKHOZmv4/xePiOA1nbB9pMqpGK7rUPNgf+1YC+7mE+0HzhTMqNUuCqvKhj6FnBw==", - "dev": true, - "dependencies": { - "array.prototype.filter": "^1.0.3", - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.0.0" - } - }, - "node_modules/object.values": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", - "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", - "dev": true, - "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" - }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/possible-typed-array-names": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" - }, - "node_modules/pstree.remy": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", - "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==" - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/random-bytes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", - "integrity": "sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/rechoir": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", - "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", - "dev": true, - "dependencies": { - "resolve": "^1.20.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", - "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.6", - "define-properties": "^1.2.1", - "es-errors": "^1.3.0", - "set-function-name": "^2.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-cwd/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/resolve-pkg-maps": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", - "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", - "dev": true, - "funding": { - "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-array-concat": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", - "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safe-regex-test": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", - "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-regex": "^1.1.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/set-function-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", - "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", - "dev": true, - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/sift": { - "version": "16.0.1", - "resolved": "https://registry.npmjs.org/sift/-/sift-16.0.1.tgz", - "integrity": "sha512-Wv6BjQ5zbhW7VFefWusVP33T/EM0vYikCaQ2qR8yULbsilAT8/wQaXvuQ3ptGLpoKx+lihJE3y2UTgKDyyNHZQ==" - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" - }, - "node_modules/simple-update-notifier": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", - "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/simple-update-notifier/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/socket.io": { - "version": "4.7.5", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.5.tgz", - "integrity": "sha512-DmeAkF6cwM9jSfmp6Dr/5/mfMwb5Z5qRrSXLpo3Fq5SqyU8CMF15jIN4ZhfSwu35ksM1qmHZDQ/DK5XTccSTvA==", - "dependencies": { - "accepts": "~1.3.4", - "base64id": "~2.0.0", - "cors": "~2.8.5", - "debug": "~4.3.2", - "engine.io": "~6.5.2", - "socket.io-adapter": "~2.5.2", - "socket.io-parser": "~4.2.4" - }, - "engines": { - "node": ">=10.2.0" - } - }, - "node_modules/socket.io-adapter": { - "version": "2.5.4", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.4.tgz", - "integrity": "sha512-wDNHGXGewWAjQPt3pyeYBtpWSq9cLE5UW1ZUPL/2eGK9jtse/FpXib7epSTsz0Q0m+6sg6Y4KtcFTlah1bdOVg==", - "dependencies": { - "debug": "~4.3.4", - "ws": "~8.11.0" - } - }, - "node_modules/socket.io-client": { - "version": "4.7.5", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.5.tgz", - "integrity": "sha512-sJ/tqHOCe7Z50JCBCXrsY3I2k03iOiUe+tj1OmKeD2lXPiGH/RUCdTZFoqVyN7l1MnpIzPrGtLcijffmeouNlQ==", - "dependencies": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.2", - "engine.io-client": "~6.5.2", - "socket.io-parser": "~4.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/socket.io-parser": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", - "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", - "dependencies": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/sparse-bitfield": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", - "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", - "dependencies": { - "memory-pager": "^1.0.2" - } - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/streamsearch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", - "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string.prototype.trim": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", - "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", - "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", - "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/terser": { - "version": "5.29.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.29.1.tgz", - "integrity": "sha512-lZQ/fyaIGxsbGxApKmoPTODIzELy3++mXhS5hOqaAWZjQtpq/hFHAc+rm29NND1rYRxRWKcjuARNwULNXa5RtQ==", - "dev": true, - "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/terser-webpack-plugin": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", - "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.20", - "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.1", - "terser": "^5.26.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "uglify-js": { - "optional": true - } - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/touch": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", - "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", - "dependencies": { - "nopt": "~1.0.10" - }, - "bin": { - "nodetouch": "bin/nodetouch.js" - } - }, - "node_modules/tr46": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", - "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", - "dependencies": { - "punycode": "^2.3.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/tsconfig-paths": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", - "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", - "dev": true, - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typed-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", - "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/typed-array-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", - "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", - "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-length": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.5.tgz", - "integrity": "sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "license": "MIT" - }, - "node_modules/uid-safe": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", - "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", - "dependencies": { - "random-bytes": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/undefsafe": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", - "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==" - }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" - }, - "node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "license": "MIT" - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/validator": { - "version": "13.11.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", - "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/watchpack": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", - "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", - "dev": true, - "dependencies": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", - "engines": { - "node": ">=12" - } - }, - "node_modules/webpack": { - "version": "5.90.3", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.90.3.tgz", - "integrity": "sha512-h6uDYlWCctQRuXBs1oYpVe6sFcWedl0dpcVaTf/YF67J9bKvwJajFulMVSYKHrksMB3I/pIagRzDxwxkebuzKA==", - "dev": true, - "dependencies": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.5", - "@webassemblyjs/ast": "^1.11.5", - "@webassemblyjs/wasm-edit": "^1.11.5", - "@webassemblyjs/wasm-parser": "^1.11.5", - "acorn": "^8.7.1", - "acorn-import-assertions": "^1.9.0", - "browserslist": "^4.21.10", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.15.0", - "es-module-lexer": "^1.2.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.2.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.10", - "watchpack": "^2.4.0", - "webpack-sources": "^3.2.3" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-cli": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", - "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", - "dev": true, - "dependencies": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^2.1.1", - "@webpack-cli/info": "^2.0.2", - "@webpack-cli/serve": "^2.0.5", - "colorette": "^2.0.14", - "commander": "^10.0.1", - "cross-spawn": "^7.0.3", - "envinfo": "^7.7.3", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^3.1.1", - "rechoir": "^0.8.0", - "webpack-merge": "^5.7.3" - }, - "bin": { - "webpack-cli": "bin/cli.js" - }, - "engines": { - "node": ">=14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "5.x.x" - }, - "peerDependenciesMeta": { - "@webpack-cli/generators": { - "optional": true - }, - "webpack-bundle-analyzer": { - "optional": true - }, - "webpack-dev-server": { - "optional": true - } - } - }, - "node_modules/webpack-cli/node_modules/commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", - "dev": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/webpack-merge": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", - "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", - "dev": true, - "dependencies": { - "clone-deep": "^4.0.1", - "flat": "^5.0.2", - "wildcard": "^2.0.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", - "dev": true, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/webpack/node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/webpack/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/whatwg-url": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-13.0.0.tgz", - "integrity": "sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==", - "dependencies": { - "tr46": "^4.1.1", - "webidl-conversions": "^7.0.0" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.14.tgz", - "integrity": "sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.6", - "call-bind": "^1.0.5", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/wildcard": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", - "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", - "dev": true - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" - }, - "node_modules/ws": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", - "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xmlhttprequest-ssl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", - "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "license": "MIT", - "engines": { - "node": ">=0.4" - } - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/public/modstagram-back/package.json b/public/modstagram-back/package.json deleted file mode 100644 index f0d6cf4..0000000 --- a/public/modstagram-back/package.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "name": "modstagram-back", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "start": "node server.js", - "dev": "cross-env NODE_ENV=development nodemon index.js", - "build": "webpack", - "prod": "node dist/final.js" - }, - "keywords": [], - "author": "", - "license": "ISC", - "dependencies": { - "axios": "^1.6.7", - "bcryptjs": "^2.4.3", - "body-parser": "^1.20.2", - "cors": "^2.8.5", - "dotenv": "^16.4.5", - "express": "^4.18.3", - "express-form-data": "^2.0.23", - "express-rate-limit": "^7.2.0", - "express-session": "^1.18.0", - "express-validator": "^7.0.1", - "helmet": "^7.1.0", - "jsonwebtoken": "^9.0.2", - "lodash": "^4.17.21", - "moment-jalaali": "^0.10.0", - "mongoose": "^8.2.1", - "mongoose-paginate-v2": "^1.8.0", - "mongoose-timestamp": "^0.6.0", - "multer": "^2.0.2", - "node-cron": "^3.0.3", - "nodemon": "^3.1.0", - "socket.io": "^4.7.5", - "socket.io-client": "^4.7.5" - }, - "devDependencies": { - "cross-env": "^7.0.3", - "eslint": "^8.57.0", - "eslint-config-standard": "^17.1.0", - "eslint-plugin-import": "^2.29.1", - "eslint-plugin-n": "^16.6.2", - "eslint-plugin-promise": "^6.1.1", - "webpack": "^5.90.3", - "webpack-cli": "^5.1.4" - } -} diff --git a/public/modstagram-back/routes/application/academy/index.js b/public/modstagram-back/routes/application/academy/index.js deleted file mode 100644 index a875597..0000000 --- a/public/modstagram-back/routes/application/academy/index.js +++ /dev/null @@ -1,383 +0,0 @@ -const express = require("express"); -const router = express.Router(); -const academyController = require("../../../controllers/application/academy/academyControllers"); -const multer = require("multer"); -const path = require("path"); -const fs = require("fs"); -// const academyCategoryController = require("../../../controllers/application/academy/academyCategoryController"); - -// ========================================== -// ⚙️ تنظیمات اولیه و دایرکتوری‌ها -// ========================================== - -// اطمینان از وجود دایرکتوری‌ها -const ensureDir = (dir) => { - if (!fs.existsSync(dir)) { - fs.mkdirSync(dir, { recursive: true }); - console.log("DEBUG: Created directory:", dir); - } -}; - -const BASE_DIR = process.cwd(); -const courseVideoDir = path.join(BASE_DIR, "storage", "courses", "videos"); -const courseImageDir = path.join(BASE_DIR, "storage", "courses", "images"); - -console.log("DEBUG: BASE_DIR:", BASE_DIR); -console.log("DEBUG: courseVideoDir:", courseVideoDir); -console.log("DEBUG: courseImageDir:", courseImageDir); - -ensureDir(courseVideoDir); -ensureDir(courseImageDir); - -// ========================================== -// 📁 تنظیمات آپلود فایل با Multer -// ========================================== - -// تنظیمات ذخیره‌سازی فایل‌ها -const storage = multer.diskStorage({ - destination: (req, file, cb) => { - console.log("DEBUG: Multer destination - fieldname:", file.fieldname); - // استفاده از دایرکتوری موقت برای آپلود اولیه - const tempDir = "/tmp/modstagram-uploads"; - if (!fs.existsSync(tempDir)) { - fs.mkdirSync(tempDir, { recursive: true }); - } - cb(null, tempDir); - }, - filename: (req, file, cb) => { - const uniqueSuffix = Date.now() + "-" + Math.round(Math.random() * 1e9); - const filename = uniqueSuffix + path.extname(file.originalname); - console.log("DEBUG: Generated filename:", filename); - cb(null, filename); - }, -}); - -// تنظیمات Multer با محدودیت حجم 500 مگابایت -const upload = multer({ - storage: storage, - limits: { - fileSize: 500 * 1024 * 1024, // 500 MB - }, -}); - -// ========================================== -// 🏢 مسیرهای مربوط به آکادمی -// ========================================== - -// دریافت اطلاعات آکادمی کاربر جاری -router.get("/", academyController.findAcademy); - -// یافتن آکادمی با شناسه -router.post("/findAcademyById", academyController.findAcademyById); - -// تکمیل پروفایل آکادمی -router.post("/academy/profile", academyController.academyProfile); - -// ========================================== -// 📚 مسیرهای مدیریت دوره‌ها (Courses) -// ========================================== - -// ایجاد دوره جدید -router.post("/academy/creat/course", academyController.creatCourse); - -// ویرایش دوره -router.patch("/academy/update/course", academyController.updateCourse); - -// حذف دوره (تغییر وضعیت به reject) -router.delete("/academy/delete/course", academyController.deleteCourse); - -// دریافت لیست دوره‌های آکادمی جاری -router.get("/academy/get/course", academyController.getCourse); - -// دریافت لیست همه دوره‌ها با فیلتر و صفحه‌بندی -router.get("/academy/get/curses", academyController.getCourses); - -// دریافت دوره‌های یک آکادمی خاص -router.get("/academy/get/getAcademyCourse/:Id", academyController.getAcademyCourse); - -// ========================================== -// 💳 مسیرهای پرداخت و مالی -// ========================================== - -// پرداخت برای اشتراک پرو -router.post("/academy/course/payment", academyController.proPayment); - -// کال‌بک درگاه پرداخت زرین‌پال (اشتراک پرو) -router.get("/academy/course/pro", academyController.handleCoursePaymentCallback); - -// پرداخت برای خرید دوره -router.post("/academy/course/payment-web", academyController.coursePayment); - -// کال‌بک درگاه پرداخت زرین‌پال (خرید دوره) -router.get("/academy/course/payment/verify", academyController.CoursePaymentCallback); - -// ========================================== -// 🎬 مسیرهای محتوای دوره (ویدیوها و فایل‌ها) -// ========================================== - -// دریافت محتوای دوره (ویدیوها) -router.get("/academy/course/content", academyController.getCourseContent); - -// حذف ویدیو از دوره -router.delete("/academy/course/content/video", academyController.deleteCourseVideo); - -// ========================================== -// 📹 مسیرهای آپلود ویدیو (۳ روش مختلف) -// ========================================== - -// روش 1: آپلود معمولی با Multipart (با استفاده از Multer) -router.post( - "/academy/course/creat/video", - (req, res, next) => { - console.log("===== STEP 1: Route hit ====="); - console.log("Content-Type:", req.headers["content-type"]); - next(); - }, - (req, res, next) => { - console.log("===== STEP 2: Before multer ====="); - next(); - }, - (req, res, next) => { - // اجرای manual multer با try-catch - upload.single("video")(req, res, (err) => { - if (err) { - console.log("===== MULTER ERROR ====="); - console.log("Error name:", err.name); - console.log("Error message:", err.message); - console.log("Full error:", err); - return res.status(400).json({ - success: false, - message: `خطا در آپلود: ${err.message}`, - error: err.toString(), - }); - } - console.log("===== STEP 3: Multer completed successfully ====="); - next(); - }); - }, - (req, res, next) => { - console.log("===== STEP 4: After multer ====="); - console.log("req.file:", req.file); - console.log("req.body:", req.body); - - if (!req.file) { - console.log("ERROR: No file in req.file!"); - return res.status(400).json({ - success: false, - message: "فایلی دریافت نشد", - }); - } - next(); - }, - academyController.creatCourseVideo -); - -// روش 2: آپلود با Base64 (برای فایل‌های کوچک) -router.post( - "/academy/course/creat/video-base64", - academyController.creatCourseVideoBase64 -); - -// روش 3: آپلود تکه‌تکه (Chunk Upload) - مناسب برای فایل‌های بزرگ -// دریافت هر تکه از ویدیو -router.post( - "/academy/course/creat/video-chunk", - academyController.creatCourseVideoChunk -); - -// ادغام تکه‌ها بعد از اتمام آپلود -router.post( - "/academy/course/creat/video-chunk/merge", - academyController.mergeVideoChunks -); - -// بررسی وضعیت آپلود (برای قابلیت Resume) -router.get("/academy/course/upload-status", academyController.getUploadStatus); - -// ========================================== -// ❤️ مسیرهای لایک و تعامل -// ========================================== - -// لایک کردن محتوای دوره -router.post("/academy/course/like", academyController.likeCourseContent); - -// حذف لایک (دیسلایک) -router.post("/academy/course/dislike", academyController.dontLikeCourseContent); - -// بررسی وضعیت لایک کاربر -router.post("/academy/course/is-like", academyController.isLikeCourseContent); - -// دریافت تعداد لایک‌های یک دوره -router.get( - "/academy/course/likes-count/:courseId", - academyController.getCourseLikesCount -); - -// دریافت لیست دوره‌های لایک شده توسط کاربر -router.get( - "/academy/user/liked-courses", - academyController.getUserLikedCourses -); - -// ========================================== -// 💬 مسیرهای کامنت و نظرات -// ========================================== - -// دریافت تعداد کل کامنت‌های یک دوره -router.get( - "/course/:courseId/comments/count", - academyController.getTotalCommentsCount -); - -// دریافت لیست کامنت‌های یک دوره -router.get("/course/:courseId/comments", academyController.getCourseComments); - -// ایجاد کامنت جدید -router.post("/comment/create", academyController.createComment); - -// تغییر وضعیت کامنت (تایید/رد) -router.patch( - "/comment/:commentId/status", - academyController.updateCommentStatus -); - -// حذف کامنت -router.delete("/comment/:commentId/delete", academyController.deleteComment); - -// ========================================== -// 🛒 مسیرهای دوره‌های خریداری شده -// ========================================== - -// دریافت دوره‌های خریداری شده توسط کاربر جاری -router.get( - "/course/getUserPurchasedCourses", - academyController.getUserPurchasedCourses -); - -// دریافت دوره‌های خریداری شده (با populate - روش بهینه) -router.get( - "/course/getUserPurchasedCoursesWithPopulate", - academyController.getUserPurchasedCoursesWithPopulate -); - -// دریافت همه پرداخت‌های آکادمی -router.get( - "/course/getAllAcademyPayments", - academyController.getAllAcademyPayments -); - -// بررسی خرید دوره توسط کاربر -router.get( - "/course/checkCoursePurchase/:courseId", - academyController.checkCoursePurchase -); - -// ========================================== -// 📊 مسیرهای آمار و گزارشات (STATIC) -// ========================================== - -// آمار پرداخت‌ها -router.get("/payments/stats", academyController.getPaymentStats); - -// آمار دوره‌ها -router.get("/courses/stats", academyController.getCourseStats); - -// آمار دوره‌های خریداری شده -router.get("/purchased/stats", academyController.getPurchasedStats); - -// آمار آکادمی‌ها -router.get("/academies/stats", academyController.getAcademyStats); - -// ========================================== -// ⚙️ مسیرهای تنظیمات (Settings) -// ========================================== - -// دریافت همه تنظیمات -router.get("/settings/all", academyController.getAllSettings); -router.get("/settings", academyController.getAllSettings); - -// به‌روزرسانی همه تنظیمات -router.put("/settings/all", academyController.updateAllSettings); -router.put("/settings", academyController.updateAllSettings); - -// دریافت و ویرایش قیمت دوره‌ها -router.get("/settings/course-prices", academyController.getCoursePrices); -router.put("/settings/course-price", academyController.updateCoursePrice); - -// دریافت و ویرایش مالیات -router.get("/settings/tax", academyController.getTax); -router.put("/settings/tax", academyController.updateTax); - -// ========================================== -// 🏷️ مسیرهای دسته‌بندی آکادمی (Categories) -// ========================================== - -// دریافت لیست دسته‌بندی‌ها (با فیلتر و صفحه‌بندی) -router.get('/categories', academyController.getAll); - -// دریافت درخت دسته‌بندی (ساختار سلسله‌مراتبی) -router.get('/categories/tree', academyController.getTree); - -// دریافت دسته‌بندی‌های ویژه (برای نمایش در هوم پیج) -router.get('/categories/featured', academyController.getFeatured); - -// دریافت دسته‌بندی با اسلاگ (برای سئو و لینک‌های زیبا) -router.get('/categories/slug/:slug', academyController.getBySlug); - -// دریافت یک دسته‌بندی با شناسه -router.get('/categories/:id', academyController.getOne); - -// ایجاد دسته‌بندی جدید -router.post('/categories', academyController.create); - -// ویرایش دسته‌بندی (هم PUT و هم PATCH پشتیبانی می‌شود) -router.put('/categories/:id', academyController.update); -router.patch('/categories/:id', academyController.update); - -// حذف دسته‌بندی (سافت دیلیت - فقط غیرفعال می‌شود) -router.delete('/categories/:id', academyController.remove); - -// حذف فیزیکی دسته‌بندی (به همراه query string permanent=true) -router.delete('/categories/:id/permanent', (req, res) => { - req.query.permanent = 'true'; - academyController.remove(req, res); -}); - -// تغییر وضعیت دسته‌بندی (فعال/غیرفعال) -router.patch('/categories/:id/status', academyController.toggleStatus); - -// افزایش تعداد دوره‌های دسته‌بندی (هر بار یک دوره جدید اضافه می‌شود) -router.post('/categories/:id/increment-count', academyController.incrementCourseCount); - -// ========================================== -// 👑 مسیرهای مدیریتی (پنل ادمین) -// ========================================== - -// ------ مدیریت پرداخت‌ها ------ -router.get("/payments", academyController.getAllPayments); -router.put("/payments/status", academyController.updatePaymentStatus); - -// ------ مدیریت دوره‌ها ------ -router.get("/courses", academyController.getAllCourses); -router.get("/courses/:id", academyController.getCourseById); -router.put("/courses/:id", academyController.updateCourse); -router.post("/courses", academyController.createCourse); -router.put("/academy/courses/status", academyController.updateCourseStatus); -router.delete("/courses/:courseId", academyController.admindeleteCourse); - -// ------ مدیریت دوره‌های خریداری شده ------ -router.get("/purchased", academyController.getAllPurchasedCourses); - -// ------ مدیریت آکادمی‌ها ------ -router.get("/academies", academyController.getAllAcademies); -router.get("/academies/:id", academyController.getAcademyById); -router.put("/academies/:id", academyController.updateAcademy); -router.post("/academies", academyController.createAcademy); -router.put("/academies/status", academyController.updateAcademyStatus); -router.delete("/academies/:id", academyController.deleteAcademy); - -// ========================================== -// 📤 خروجی روت‌ها -// ========================================== - -module.exports = router; \ No newline at end of file diff --git a/public/modstagram-back/routes/application/advertising/index.js b/public/modstagram-back/routes/application/advertising/index.js deleted file mode 100644 index 3001fa6..0000000 --- a/public/modstagram-back/routes/application/advertising/index.js +++ /dev/null @@ -1,45 +0,0 @@ -const express = require('express') -const blockCheck = require('../../../middlewares/blockCheck') -const { createAdvertisingValidationRules, createAdvertising, getAdvertisingTypes, getAdvertisingCategory, getSingleAdvertising, getAdvertisingFeatures, getAdvertisings, toggleLike, addComment, getComments, rateAdvertising, getUserAdvertisings, editAdvertising, getUserSingleAdvertising, getUserAdvertisingProfile, updateUserAdvertisingProfile, getAdvertisingsWeb, getSingleAdvertisingWeb, getUserAdvertisingProfileWeb } = require('../../../controllers/application/advertising/advertisingController') -const auth = require('../../../middlewares/auth') -const { initiateAdvertisingPayment, handleAdvertisingPaymentCallback, handleAdvertisingRepublishPaymentCallback, republishAdvertisingPayment, handleSuccessfulAdvertisingPayment, handleFailedAdvertisingPayment, handleFailedAdvertisingRepublishPayment, handleSuccessfulAdvertisingRepublishPayment } = require('../../../controllers/application/payment/paymentController') -const { initiateAdvertisingPaymentWeb, handleAdvertisingPaymentCallbackWeb, republishAdvertisingPaymentWeb, handleAdvertisingRepublishPaymentCallbackWeb } = require('../../../controllers/application/payment/paymentControllerWeb') -const router = express.Router() -router.get('/', [auth], getAdvertisings) -router.get('/web', getAdvertisingsWeb) -router.get('/profile', [auth], getUserAdvertisingProfile) -router.get('/profile-web', getUserAdvertisingProfileWeb) -router.patch('/profile', [auth], [blockCheck], updateUserAdvertisingProfile) -router.get('/user-advertising', [auth], getUserAdvertisings) -router.post('/create', [auth], [blockCheck], createAdvertisingValidationRules(), createAdvertising) -router.get('/types', [auth], getAdvertisingTypes) -router.get('/categories', getAdvertisingCategory) -router.get('/features', [auth], getAdvertisingFeatures) -router.get('/get/:advertisingId', [auth], getSingleAdvertising) -router.get('/get/web/:advertisingId', getSingleAdvertisingWeb) -router.get('/get-detail/:advertisingId', [auth], getUserSingleAdvertising) -router.post('/initiate-payment', [auth], [blockCheck], initiateAdvertisingPayment) -router.post('/initiate-payment-web', [auth], [blockCheck], initiateAdvertisingPaymentWeb) -router.post('/republish-payment', [auth], [blockCheck], republishAdvertisingPayment) -router.post('/republish-payment-web', [auth], [blockCheck], republishAdvertisingPaymentWeb) -router.get('/payment', handleAdvertisingPaymentCallback) -router.get('/payment-web', handleAdvertisingPaymentCallbackWeb) -router.get('/republish-verify-payment', handleAdvertisingRepublishPaymentCallback) -router.get('/republish-verify-payment-web', handleAdvertisingRepublishPaymentCallbackWeb) -router.post('/like', [blockCheck], [auth], toggleLike) -router.post('/comment', [blockCheck], [auth], addComment) -router.get('/comments', getComments) -router.post('/rate', [blockCheck], [auth], rateAdvertising) -router.post('/edit/:id', [blockCheck], [auth], editAdvertising) - -// Route for handling successful payment -router.post('/payment-success', handleSuccessfulAdvertisingPayment) -// Route for handling failed payment -router.post('/payment-failed', handleFailedAdvertisingPayment) -// Route for handling successful payment -router.post('/republish-payment-success', handleSuccessfulAdvertisingRepublishPayment) -// Route for handling failed payment -router.post('/republish-payment-failed', handleFailedAdvertisingRepublishPayment) - -module.exports = router -module.exports = router diff --git a/public/modstagram-back/routes/application/city/index.js b/public/modstagram-back/routes/application/city/index.js deleted file mode 100644 index 084c42d..0000000 --- a/public/modstagram-back/routes/application/city/index.js +++ /dev/null @@ -1,7 +0,0 @@ -const express = require('express') -const router = express.Router() -const citysController = require('../../../controllers/application/citysController') - -router.get('/:id', citysController.getCities) - -module.exports = router diff --git a/public/modstagram-back/routes/application/expertise/index.js b/public/modstagram-back/routes/application/expertise/index.js deleted file mode 100644 index fdf4f1d..0000000 --- a/public/modstagram-back/routes/application/expertise/index.js +++ /dev/null @@ -1,6 +0,0 @@ -const express = require('express') -const { getExpertise } = require('../../../controllers/application/expertise/expertiseController') -const router = express.Router() -router.get('/', getExpertise) - -module.exports = router diff --git a/public/modstagram-back/routes/application/financial/index.js b/public/modstagram-back/routes/application/financial/index.js deleted file mode 100644 index 0123e94..0000000 --- a/public/modstagram-back/routes/application/financial/index.js +++ /dev/null @@ -1,6 +0,0 @@ -const express = require('express') -const { getFinancial } = require('../../../controllers/application/financial/financialController') -const router = express.Router() -router.get('/', getFinancial) - -module.exports = router diff --git a/public/modstagram-back/routes/application/login/index.js b/public/modstagram-back/routes/application/login/index.js deleted file mode 100644 index 6ee30c8..0000000 --- a/public/modstagram-back/routes/application/login/index.js +++ /dev/null @@ -1,14 +0,0 @@ -const express = require('express') -const router = express.Router() -const { loginValidationRules, loginUser } = require('../../../controllers/application/login/loginController') -const { verifyUser } = require('../../../controllers/application/login/verifyController') -const { changePasswordUser, changePasswordValidationRules, editChangePasswordUser } = require('../../../controllers/application/login/changePasswordController') -const { loginWithUserName } = require('../../../controllers/application/login/loginWithUserName') - -router.post('/', loginValidationRules(), loginUser) -router.post('/verify', verifyUser) -router.post('/change_password', changePasswordValidationRules(), changePasswordUser) -router.patch('/change_password', changePasswordValidationRules(), editChangePasswordUser) -router.post('/login_username', loginWithUserName) - -module.exports = router diff --git a/public/modstagram-back/routes/application/messages/index.js b/public/modstagram-back/routes/application/messages/index.js deleted file mode 100644 index c74cc8b..0000000 --- a/public/modstagram-back/routes/application/messages/index.js +++ /dev/null @@ -1,6 +0,0 @@ -const express = require('express') -const { getMessages, getUnreadMessages } = require('../../../controllers/application/messages/messageController') -const router = express.Router() -router.get('/', getMessages) -router.get('/unread', getUnreadMessages) -module.exports = router diff --git a/public/modstagram-back/routes/application/notification/index.js b/public/modstagram-back/routes/application/notification/index.js deleted file mode 100644 index 8ef0a3e..0000000 --- a/public/modstagram-back/routes/application/notification/index.js +++ /dev/null @@ -1,6 +0,0 @@ -const express = require('express') -const { getNotifications, unreadNotifications } = require('../../../controllers/application/notification/notificationController') -const router = express.Router() -router.get('/', getNotifications) -router.get('/unread', unreadNotifications) -module.exports = router diff --git a/public/modstagram-back/routes/application/offers/index.js b/public/modstagram-back/routes/application/offers/index.js deleted file mode 100644 index ebd57e3..0000000 --- a/public/modstagram-back/routes/application/offers/index.js +++ /dev/null @@ -1,18 +0,0 @@ -const express = require('express') -const { getUserOffers, getOfferTypes, handleSuccessfulOfferPayment, handleFailedOfferPayment, updateOfferStatus, createOfferComment } = require('../../../controllers/application/offer/offerController') -const { initiateOfferPaymentWeb, handleOfferPaymentCallback } = require('../../../controllers/application/payment/paymentControllerWeb') -const blockCheck = require('../../../middlewares/blockCheck') -const isRegister = require('../../../middlewares/isRegister') -const auth = require('./../../../middlewares/auth') - -const router = express.Router() -router.get('/', getUserOffers) -router.get('/types', [auth], getOfferTypes) -router.post('/update-status', [auth], updateOfferStatus) -router.post('/payment-success', [auth], handleSuccessfulOfferPayment) -router.post('/payment-failed', [auth], handleFailedOfferPayment) -router.post('/comment', [auth], createOfferComment) -router.post('/initiate-payment-web', [auth], [blockCheck], initiateOfferPaymentWeb) -router.get('/payment-web', handleOfferPaymentCallback) - -module.exports = router diff --git a/public/modstagram-back/routes/application/posts/index.js b/public/modstagram-back/routes/application/posts/index.js deleted file mode 100644 index 2c8ace0..0000000 --- a/public/modstagram-back/routes/application/posts/index.js +++ /dev/null @@ -1,204 +0,0 @@ -const express = require('express'); -const { createPostValidationRules, createPost, getUserPosts, getUserPostsWeb } = require('../../../controllers/application/posts/postController'); -const { toggleLike } = require('../../../controllers/application/posts/likeController'); -const blockCheck = require('../../../middlewares/blockCheck'); -const auth = require('../../../middlewares/auth'); -const isHalfRegister = require('../../../middlewares/isHalfRegister'); -const path = require('path'); -const fs = require('fs'); -const multer = require('multer'); - -console.log('DEBUG: Starting to load routes/posts.js'); - -const ensureDir = (dir) => { - console.log('DEBUG: Ensuring directory exists:', dir); - if (!fs.existsSync(dir)) { - console.log('DEBUG: Directory does not exist, creating:', dir); - fs.mkdirSync(dir, { recursive: true }); - } else { - console.log('DEBUG: Directory already exists:', dir); - } -}; - -const imageDir = path.join(__dirname, '../../../storage/posts/images'); -const videoDir = path.join(__dirname, '../../../storage/posts/videos'); -console.log('DEBUG: imageDir path:', imageDir); -console.log('DEBUG: videoDir path:', videoDir); -ensureDir(imageDir); -ensureDir(videoDir); - -console.log('DEBUG: Setting up multer storage'); - -const storage = multer.diskStorage({ - destination: (req, file, cb) => { - const dir = file.mimetype.startsWith('video/') ? videoDir : imageDir; - console.log('DEBUG: multer destination for file', file.originalname, ':', dir); - cb(null, dir); - }, - filename: (req, file, cb) => { - const filename = `${Date.now()}-${file.originalname}`; - console.log('DEBUG: Generated filename for', file.originalname, ':', filename); - cb(null, filename); - }, -}); - -console.log('DEBUG: Setting up multer instance with limits and filter'); - -const upload = multer({ - storage, - limits: { - fileSize: 100 * 1024 * 1024, // حداکثر 100MB - files: 10, // حداکثر 10 فایل - fieldSize: 1024 * 1024, - fieldNameSize: 100, - }, - fileFilter: (req, file, cb) => { - console.log('DEBUG: Checking file filter for', file.originalname, 'mimetype:', file.mimetype); - if (file.mimetype.startsWith('image/') || file.mimetype.startsWith('video/')) { - console.log('DEBUG: File accepted:', file.originalname); - cb(null, true); - } else { - console.log('DEBUG: File rejected:', file.originalname); - cb(new Error('فقط تصاویر یا ویدئوها مجاز هستند'), false); - } - }, -}).array('post_files', 10); - -const multerErrorHandler = (err, req, res, next) => { - console.log('DEBUG: Request headers:', JSON.stringify(req.headers, null, 2)); - console.log('DEBUG: Request body (raw):', req.body); - console.log('DEBUG: Request files:', req.files || 'No files received'); - if (err instanceof multer.MulterError) { - console.error('DEBUG: Multer error:', err.message, err.code, err.field); - return res.status(400).json({ - error: true, - message: `خطای آپلود: ${err.message} (${err.code})`, - field: err.field, - }); - } else if (err) { - console.error('DEBUG: File filter error:', err.message); - return res.status(400).json({ - error: true, - message: err.message, - }); - } - console.log('DEBUG: Multer processing completed, files:', req.files || 'No files'); - console.log('DEBUG: Request body after multer:', req.body); - next(); -}; - -console.log('DEBUG: Setting up express router'); - -const router = express.Router(); - -// روت اصلی با multipart/form-data -router.post( - '/create', - (req, res, next) => { - console.log('DEBUG: reached auth'); - console.log('DEBUG: Raw request headers:', JSON.stringify(req.headers, null, 2)); - next(); - }, - auth, - (req, res, next) => { - console.log('DEBUG: reached blockCheck'); - next(); - }, - blockCheck, - (req, res, next) => { - console.log('DEBUG: reached isHalfRegister'); - next(); - }, - isHalfRegister, - (req, res, next) => { - console.log('DEBUG: reached multer'); - console.log('DEBUG: Content-Length:', req.headers['content-length']); - console.log('DEBUG: Content-Type:', req.headers['content-type']); - next(); - }, - upload, - multerErrorHandler, - (req, res, next) => { - console.log('DEBUG: reached validation'); - console.log('DEBUG: Parsed files:', req.files || 'No files'); - console.log('DEBUG: Parsed body:', req.body); - next(); - }, - createPostValidationRules(), - (req, res, next) => { - console.log('DEBUG: reached controller'); - next(); - }, - createPost -); - -// روت جدید برای Base64 -router.post( - '/create-base64', - (req, res, next) => { - console.log('DEBUG: reached auth for base64'); - console.log('DEBUG: Raw request headers:', JSON.stringify(req.headers, null, 2)); - next(); - }, - auth, - (req, res, next) => { - console.log('DEBUG: reached blockCheck for base64'); - next(); - }, - blockCheck, - (req, res, next) => { - console.log('DEBUG: reached isHalfRegister for base64'); - next(); - }, - isHalfRegister, - (req, res, next) => { - console.log('DEBUG: Request body (base64):', JSON.stringify(req.body, null, 2)); - next(); - }, - createPostValidationRules(), - async (req, res) => { - try { - const { files, caption } = req.body; - console.log('DEBUG: Received files (base64):', files.length); - console.log('DEBUG: Received caption:', caption); - - // تبدیل Base64 به فایل - const savedFiles = await Promise.all( - files.map(async (file, index) => { - const buffer = Buffer.from(file.data.split(',')[1], 'base64'); - const dir = file.type.startsWith('video/') ? videoDir : imageDir; - const filename = `${Date.now()}-${index}-${file.name}`; - const filePath = path.join(dir, filename); - console.log('DEBUG: Saving file:', filePath); - await fs.promises.writeFile(filePath, buffer); - return { - path: filePath, - filename, - mimetype: file.type, - }; - }) - ); - - // فراخوانی createPost با فرمت مشابه - req.files = savedFiles; - req.body = { caption }; - console.log('DEBUG: Prepared files for createPost:', savedFiles); - console.log('DEBUG: Prepared body for createPost:', req.body); - await createPost(req, res); - } catch (err) { - console.error('DEBUG: Base64 processing error:', err.message); - res.status(400).json({ - error: true, - message: `خطای پردازش فایل‌ها: ${err.message}`, - }); - } - } -); - -router.post('/like', [auth, blockCheck], toggleLike); -router.get('/user-posts', [auth], getUserPosts); -router.get('/user-posts/web', getUserPostsWeb); - -console.log('DEBUG: Finished loading routes/posts.js'); - -module.exports = router; \ No newline at end of file diff --git a/public/modstagram-back/routes/application/profile/index.js b/public/modstagram-back/routes/application/profile/index.js deleted file mode 100644 index 2c7bd31..0000000 --- a/public/modstagram-back/routes/application/profile/index.js +++ /dev/null @@ -1,8 +0,0 @@ -const express = require('express') -const { getProfile , getUserById} = require('../../../controllers/application/profile/profileController') -const auth = require('../../../middlewares/auth') -const router = express.Router() -router.get('/',[auth], getProfile) -router.get('/:id', getUserById) - -module.exports = router diff --git a/public/modstagram-back/routes/application/projects/index.js b/public/modstagram-back/routes/application/projects/index.js deleted file mode 100644 index d432dca..0000000 --- a/public/modstagram-back/routes/application/projects/index.js +++ /dev/null @@ -1,44 +0,0 @@ -const express = require('express') -const { createProject, createProjectValidationRules } = require('../../../controllers/application/projects/createProjectController') -const { getProjects, getSingleProjects, getSingleProjectsWeb, getUserProjects, getUserProjectsWeb } = require('../../../controllers/application/projects/getProjectController') -const { getProjectTypes } = require('../../../controllers/application/projects/projectTypesController') -const { initiatePayment, handlePaymentCallback, paymentRequestStepOne, paymentRequestStepTwo, paymentRequestStepAll, paymentRequestStepOneCallback, paymentRequestStepTwoCallback, paymentRequestStepAllCallback, handleSuccessfulPayment, handleFailedPayment } = require('../../../controllers/application/payment/paymentController') -const auth = require('../../../middlewares/auth') -const { requestProjectValidationRules, requestProject, acceptProject, editRequestProject } = require('../../../controllers/application/projects/requestProjectController') -const { editProject, doneProject, cancleProject, editProjectValidationRules, setRateProject, doneProjectWeb } = require('../../../controllers/application/projects/updateProjectController') -const blockCheck = require('../../../middlewares/blockCheck') -const isRegister = require('../../../middlewares/isRegister') -const { initiatePaymentWeb, handlePaymentCallbackWeb, paymentRequestAcceptWeb } = require('../../../controllers/application/payment/paymentControllerWeb') -const router = express.Router() -router.get('/', getProjects) -router.get('/user-projects', [auth], getUserProjects) -router.get('/user-projects/web', getUserProjectsWeb) -router.get('/types', [auth], getProjectTypes) -router.get('/get/:projectId', [auth], getSingleProjects) -router.get('/get/web/:projectId', getSingleProjectsWeb) -router.get('/payment', handlePaymentCallback) -router.get('/payment-web', handlePaymentCallbackWeb) -router.post('/create', [blockCheck], [auth], [isRegister], createProjectValidationRules(), createProject) -router.post('/edit', [blockCheck], [auth], [isRegister], editProjectValidationRules(), editProject) -router.post('/rate', [blockCheck], [auth], [isRegister], setRateProject) -router.post('/initiate-payment', [blockCheck], [isRegister], [auth], initiatePayment) -router.post('/initiate-payment-web', [blockCheck], [isRegister], [auth], initiatePaymentWeb) -router.post('/request', [blockCheck], [isRegister], [auth], requestProjectValidationRules(), requestProject) -router.post('/edit-request', [isRegister], [blockCheck], [auth], requestProjectValidationRules(), editRequestProject) -router.post('/payment-request-step-one', [isRegister], [blockCheck], [auth], paymentRequestStepOne) -router.post('/payment-request-step-one/web', [isRegister], [blockCheck], [auth], paymentRequestAcceptWeb) -router.post('/payment-request-step-two', [isRegister], [blockCheck], [auth], paymentRequestStepTwo) -router.post('/payment-request-all', [isRegister], [blockCheck], [auth], paymentRequestStepAll) -router.get('/payment-request-step-one-callback', paymentRequestStepOneCallback) -router.get('/payment-request-step-two-callback', paymentRequestStepTwoCallback) -router.get('/payment-request-step-all-callback', paymentRequestStepAllCallback) -router.post('/accept', [isRegister], [blockCheck], [auth], acceptProject) -router.post('/done', [isRegister], [auth], doneProject) -router.post('/done/web', [isRegister], [auth], doneProjectWeb) -router.post('/cancle', [isRegister], [blockCheck], [auth], cancleProject) - -// Route for handling successful payment -router.post('/payment-success', handleSuccessfulPayment) -// Route for handling failed payment -router.post('/payment-failed', handleFailedPayment) -module.exports = router diff --git a/public/modstagram-back/routes/application/provinces/index.js b/public/modstagram-back/routes/application/provinces/index.js deleted file mode 100644 index 1b346c6..0000000 --- a/public/modstagram-back/routes/application/provinces/index.js +++ /dev/null @@ -1,7 +0,0 @@ -const express = require('express') -const router = express.Router() -const provincesController = require('../../../controllers/application/provincesController') - -router.get('/', provincesController.getProvinces) - -module.exports = router diff --git a/public/modstagram-back/routes/application/register/index.js b/public/modstagram-back/routes/application/register/index.js deleted file mode 100644 index 9978c9d..0000000 --- a/public/modstagram-back/routes/application/register/index.js +++ /dev/null @@ -1,16 +0,0 @@ -const express = require('express') -const router = express.Router() -const { registerValidationRules, registerUser } = require('../../../controllers/application/register/registerController') -const { verifyUser } = require('../../../controllers/application/register/verifyController') -const { setUserName, updateUserName } = require('../../../controllers/application/register/usernameController') -const { setUserFullName, setUserFullNameValidationRules } = require('../../../controllers/application/register/userFullNameController') -const { setUserType } = require('../../../controllers/application/register/userTypeController') - -router.post('/', registerValidationRules(), registerUser) -router.post('/verify', verifyUser) -router.post('/username', setUserName) -router.patch('/username', updateUserName) -router.post('/fullname', setUserFullNameValidationRules(), setUserFullName) -router.post('/user_type', setUserType) - -module.exports = router diff --git a/public/modstagram-back/routes/application/search-web/index.js b/public/modstagram-back/routes/application/search-web/index.js deleted file mode 100644 index 54f78f6..0000000 --- a/public/modstagram-back/routes/application/search-web/index.js +++ /dev/null @@ -1,6 +0,0 @@ -const express = require('express') -const { getSearch } = require('../../../controllers/application/search-web/searchController') -const router = express.Router() -router.get('/', getSearch) - -module.exports = router diff --git a/public/modstagram-back/routes/application/search/index.js b/public/modstagram-back/routes/application/search/index.js deleted file mode 100644 index 5db29bc..0000000 --- a/public/modstagram-back/routes/application/search/index.js +++ /dev/null @@ -1,6 +0,0 @@ -const express = require('express') -const { getSearch } = require('../../../controllers/application/search/searchController') -const router = express.Router() -router.get('/', getSearch) - -module.exports = router diff --git a/public/modstagram-back/routes/application/settings/index.js b/public/modstagram-back/routes/application/settings/index.js deleted file mode 100644 index bff48f0..0000000 --- a/public/modstagram-back/routes/application/settings/index.js +++ /dev/null @@ -1,6 +0,0 @@ -const express = require('express') -const { getSetting } = require('../../../controllers/application/settings/settingsController') -const router = express.Router() -router.get('/:key', getSetting) - -module.exports = router diff --git a/public/modstagram-back/routes/application/tickets/index.js b/public/modstagram-back/routes/application/tickets/index.js deleted file mode 100644 index 5174c7e..0000000 --- a/public/modstagram-back/routes/application/tickets/index.js +++ /dev/null @@ -1,9 +0,0 @@ -const express = require('express') -const { getUserTickets, createTicket, addUserMessageToTicket, getTicketMessages } = require('../../../controllers/application/tickets/ticketsController') -const router = express.Router() -router.get('/', getUserTickets) -router.get('/messages', getTicketMessages) -router.post('/create', createTicket) -router.post('/message', addUserMessageToTicket) - -module.exports = router diff --git a/public/modstagram-back/routes/application/users/index.js b/public/modstagram-back/routes/application/users/index.js deleted file mode 100644 index 4442dc9..0000000 --- a/public/modstagram-back/routes/application/users/index.js +++ /dev/null @@ -1,22 +0,0 @@ -const express = require('express') -const { getUsers, getSingleUser, blockUser, unblockUser, getComments,createLicense, getAllLicenses,updateLicenseConfirmation, getLicenseByUserId, inviteEmployer, getUserContactInfo, getPostsWeb, getSingleUserWeb, createUserComment } = require('../../../controllers/application/users/getUserController') -const blockCheck = require('../../../middlewares/blockCheck') -const isRegister = require('../../../middlewares/isRegister') -const auth = require('../../../middlewares/auth') -const router = express.Router() -router.get('/', [auth], getUsers) -router.get('/web', getPostsWeb) -router.get('/get', [auth], getSingleUser) -router.get('/get/web', getSingleUserWeb) -router.post('/block', [auth], [isRegister], [blockCheck], blockUser) -router.post('/unblock', [auth], [isRegister], [blockCheck], unblockUser) -router.get('/comments', [auth], getComments) -router.post('/comments', [auth], [isRegister], [blockCheck], createUserComment) -router.get('/invite-employer', [auth], [isRegister], [blockCheck], inviteEmployer) -router.get('/contact-info', [auth], getUserContactInfo) -router.get('/License', getAllLicenses) -router.get('/License/:userId', getLicenseByUserId) -router.post('/License', createLicense) -router.put('/License/:userId', updateLicenseConfirmation) - -module.exports = router diff --git a/public/modstagram-back/routes/application/verify/index.js b/public/modstagram-back/routes/application/verify/index.js deleted file mode 100644 index 8e7fc8d..0000000 --- a/public/modstagram-back/routes/application/verify/index.js +++ /dev/null @@ -1,38 +0,0 @@ -const express = require('express') -const { setProfileImage, updateProfileImage } = require('../../../controllers/application/verify/setProfileImageController') -const { setExpertise, updateExpertise } = require('../../../controllers/application/verify/expertiseController') -const { setGender } = require('../../../controllers/application/verify/genderController') -const { setSizes, updateSizes } = require('../../../controllers/application/verify/sizesController') -const { setColors, updateColors } = require('../../../controllers/application/verify/colorsController') -const { setCooperationType, updateCooperationType } = require('../../../controllers/application/verify/cooperationTypeController') -const { setConversation, updateConversation } = require('../../../controllers/application/verify/conversationController') -const { saveAuth, saveAuthValidationRules, updateShaba } = require('../../../controllers/application/verify/authController') -const { setAddress, updateAddress } = require('../../../controllers/application/verify/addressController') -const { setNationalCardImage } = require('../../../controllers/application/verify/setNationalCardImageController') -const blockCheck = require('../../../middlewares/blockCheck') -const auth = require('../../../middlewares/auth') -const { setServices, updateServices } = require('../../../controllers/application/verify/servicesController') -const router = express.Router() - -router.post('/profile_image', setProfileImage) -router.patch('/profile_image', [blockCheck], [auth], updateProfileImage) -router.post('/expertise', setExpertise) -router.patch('/expertise', [blockCheck], [auth], updateExpertise) -router.post('/gender', setGender) -router.post('/sizes', setSizes) -router.patch('/sizes', [blockCheck], [auth], updateSizes) -router.post('/services', setServices) -router.patch('/services', [blockCheck], [auth], updateServices) -router.post('/colors', setColors) -router.patch('/colors', [blockCheck], [auth], updateColors) -router.post('/cooperation_type', setCooperationType) -router.patch('/cooperation_type', [blockCheck], [auth], updateCooperationType) -router.post('/conversation', setConversation) -router.patch('/conversation', [blockCheck], [auth], updateConversation) -router.post('/auth', saveAuthValidationRules(), saveAuth) -router.patch('/shaba', [blockCheck], [auth], updateShaba) -router.post('/address', setAddress) -router.patch('/address', [blockCheck], [auth], updateAddress) -router.post('/national_card_image', setNationalCardImage) - -module.exports = router diff --git a/public/modstagram-back/routes/application/version/index.js b/public/modstagram-back/routes/application/version/index.js deleted file mode 100644 index ab8eaec..0000000 --- a/public/modstagram-back/routes/application/version/index.js +++ /dev/null @@ -1,6 +0,0 @@ -const express = require('express') -const { getVersion } = require('../../../controllers/application/version/versionController') -const router = express.Router() -router.get('/', getVersion) - -module.exports = router diff --git a/public/modstagram-back/routes/application/workroom/index.js b/public/modstagram-back/routes/application/workroom/index.js deleted file mode 100644 index f7d6cba..0000000 --- a/public/modstagram-back/routes/application/workroom/index.js +++ /dev/null @@ -1,8 +0,0 @@ -const express = require('express') -const { getProjects, getSingleProject, getProjectRequests } = require('../../../controllers/application/workroom/workroomController') -const router = express.Router() -router.get('/', getProjects) -router.get('/get', getSingleProject) -router.get('/get-requests/:projectId', getProjectRequests) - -module.exports = router diff --git a/public/modstagram-back/routes/index.js b/public/modstagram-back/routes/index.js deleted file mode 100644 index ea419b6..0000000 --- a/public/modstagram-back/routes/index.js +++ /dev/null @@ -1,77 +0,0 @@ -const registerRouter = require('./application/register') -const loginRouter = require('./application/login') -const verifyRouter = require('./application/verify') -const provincesRouter = require('./application/provinces') -const citiesRouter = require('./application/city') -const projectsRouter = require('./application/projects') -const usersRouter = require('./application/users') -const postsRouter = require('./application/posts') -const expertiseRouter = require('./application/expertise') -const profileRouter = require('./application/profile') -const workroomRouter = require('./application/workroom') -const messagesRouter = require('./application/messages') -const searchRouter = require('./application/search') -const searchRouterWeb = require('./application/search-web') -const financialRouter = require('./application/financial') -const notificationRouter = require('./application/notification') -const ticketsRouter = require('./application/tickets') -const advertisingRouter = require('./application/advertising') -const settingsRouter = require('./application/settings') -const versionRouter = require('./application/version') -const offerRouter = require('./application/offers') -const academyRoute = require('./application/academy') - -const projectsPanelRouter = require('./panel/projects') -const postsPanelRouter = require('./panel/posts') -const expertisePanelRouter = require('./panel/expertise') -const loginPanelRouter = require('./panel/login') -const usersPanelRouter = require('./panel/users') -const ticketsPanelRouter = require('./panel/tickets') -const financialPanelRouter = require('./panel/financial') -const commentsPanelRouter = require('./panel/comments') -const advertisingPanelRouter = require('./panel/advertising') -const shopsPanelRouter = require('./panel/shops') -const settingsPanelRouter = require('./panel/settings') -const versionPanelRouter = require('./panel/version') - -const auth = require('../middlewares/auth') -const adminAuth = require('../middlewares/adminAuth') -module.exports = (app) => { - // App - app.use('/api/v1/register', registerRouter) - app.use('/api/v1/login', loginRouter) - app.use('/api/v1/verify', [auth], verifyRouter) - app.use('/api/v1/provinces', provincesRouter) - app.use('/api/v1/cities', citiesRouter) - app.use('/api/v1/projects', projectsRouter) - app.use('/api/v1/users', usersRouter) - app.use('/api/v1/posts', postsRouter) - app.use('/api/v1/expertise', expertiseRouter) - app.use('/api/v1/profile', profileRouter) - app.use('/api/v1/workroom', [auth], workroomRouter) - app.use('/api/v1/messages', [auth], messagesRouter) - app.use('/api/v1/notifications', [auth], notificationRouter) - app.use('/api/v1/search', [auth], searchRouter) - app.use('/api/v1/search-web', searchRouterWeb) - app.use('/api/v1/financial', [auth], financialRouter) - app.use('/api/v1/tickets', [auth], ticketsRouter) - app.use('/api/v1/offers', offerRouter) - app.use('/api/v1/advertising', advertisingRouter) - app.use('/api/v1/settings', settingsRouter) - app.use('/api/v1/version', versionRouter) - app.use('/api/v1/academy', academyRoute) - - // Panel - app.use('/api/v1/panel/login', loginPanelRouter) - app.use('/api/v1/panel/users', usersPanelRouter) - app.use('/api/v1/panel/projects', [adminAuth], projectsPanelRouter) - app.use('/api/v1/panel/posts', [adminAuth], postsPanelRouter) - app.use('/api/v1/panel/expertise', [adminAuth], expertisePanelRouter) - app.use('/api/v1/panel/tickets', [adminAuth], ticketsPanelRouter) - app.use('/api/v1/panel/financial', [adminAuth], financialPanelRouter) - app.use('/api/v1/panel/comments', [adminAuth], commentsPanelRouter) - app.use('/api/v1/panel/advertising', [adminAuth], advertisingPanelRouter) - app.use('/api/v1/panel/shops', [adminAuth], shopsPanelRouter) - app.use('/api/v1/panel/settings', [adminAuth], settingsPanelRouter) - app.use('/api/v1/panel/version', [adminAuth], versionPanelRouter) -} diff --git a/public/modstagram-back/routes/panel/advertising/index.js b/public/modstagram-back/routes/panel/advertising/index.js deleted file mode 100644 index 34a7a0b..0000000 --- a/public/modstagram-back/routes/panel/advertising/index.js +++ /dev/null @@ -1,22 +0,0 @@ -const express = require('express') -const { getAdvertisings, getSingleAdvertising, acceptAdvertising, rejectAdvertising, getAdvertisingCategories, getAdvertisingCategoryById,createAdvertisingCategory , deleteAdvertisingCategory } = require('../../../controllers/panel/advertising/advertisingController') -const { getAdvertisingComments, getAdvertisingCommentDetail, acceptAdvertisingComment } = require('../../../controllers/panel/comments/advertisingCommentController') -const router = express.Router() -router.get('/', getAdvertisings) -router.get('/detail', getSingleAdvertising) -router.post('/accept', acceptAdvertising) -router.post('/reject', rejectAdvertising) - -router.get('/comments', getAdvertisingComments) -router.get('/comments/detail', getAdvertisingCommentDetail) -router.post('/comments/accept', acceptAdvertisingComment) - -router.post('/advertising-categories', createAdvertisingCategory) -router.delete('/advertising-categories/:id', deleteAdvertisingCategory) -// لیست دسته‌بندی‌ها (پشتیبانی از query params) -router.get('/advertising-categories', getAdvertisingCategories); - -// گرفتن یک دسته‌بندی با id -router.get('/advertising-categories/:id', getAdvertisingCategoryById); - -module.exports = router diff --git a/public/modstagram-back/routes/panel/comments/index.js b/public/modstagram-back/routes/panel/comments/index.js deleted file mode 100644 index e64028d..0000000 --- a/public/modstagram-back/routes/panel/comments/index.js +++ /dev/null @@ -1,8 +0,0 @@ -const express = require('express') -const { acceptComment, getComments, getCommentDetail } = require('../../../controllers/panel/comments/commentController') -const router = express.Router() -router.get('/', getComments) -router.get('/detail', getCommentDetail) -router.post('/accept', acceptComment) - -module.exports = router diff --git a/public/modstagram-back/routes/panel/expertise/index.js b/public/modstagram-back/routes/panel/expertise/index.js deleted file mode 100644 index 56e8dfe..0000000 --- a/public/modstagram-back/routes/panel/expertise/index.js +++ /dev/null @@ -1,9 +0,0 @@ -const express = require('express') -const { createExpertise, createSubExpertise, getExpertise, editExpertise } = require('../../../controllers/panel/expertise/expertiseController') -const router = express.Router() -router.get('/', getExpertise) -router.post('/create', createExpertise) -router.post('/create/sub', createSubExpertise) -router.put('/update/:id', editExpertise) - -module.exports = router diff --git a/public/modstagram-back/routes/panel/financial/index.js b/public/modstagram-back/routes/panel/financial/index.js deleted file mode 100644 index 65f8f60..0000000 --- a/public/modstagram-back/routes/panel/financial/index.js +++ /dev/null @@ -1,7 +0,0 @@ -const express = require('express') -const { getFinancial, getFinancialDetail } = require('../../../controllers/panel/financial/financialController') -const router = express.Router() -router.get('/', getFinancial) -router.get('/detail', getFinancialDetail) - -module.exports = router diff --git a/public/modstagram-back/routes/panel/login/index.js b/public/modstagram-back/routes/panel/login/index.js deleted file mode 100644 index 58adb2e..0000000 --- a/public/modstagram-back/routes/panel/login/index.js +++ /dev/null @@ -1,8 +0,0 @@ -const express = require('express') -const router = express.Router() -const { adminLogin, changePassword } = require('../../../controllers/panel/login/loginController') -const adminAuth = require('../../../middlewares/adminAuth') -router.post('/', adminLogin) -router.post('/change-password', [adminAuth], changePassword) - -module.exports = router diff --git a/public/modstagram-back/routes/panel/posts/index.js b/public/modstagram-back/routes/panel/posts/index.js deleted file mode 100644 index 5b8d4f7..0000000 --- a/public/modstagram-back/routes/panel/posts/index.js +++ /dev/null @@ -1,8 +0,0 @@ -const express = require('express') -const { acceptPost, getPosts, getPostDetail } = require('../../../controllers/panel/posts/postController') -const router = express.Router() -router.get('/', getPosts) -router.get('/detail', getPostDetail) -router.post('/accept', acceptPost) - -module.exports = router diff --git a/public/modstagram-back/routes/panel/projects/index.js b/public/modstagram-back/routes/panel/projects/index.js deleted file mode 100644 index 61c9f14..0000000 --- a/public/modstagram-back/routes/panel/projects/index.js +++ /dev/null @@ -1,11 +0,0 @@ -const express = require('express') -const { createProjectTypes, getProjectTypes } = require('../../../controllers/panel/projects/projectTypesController') -const { getProjects, getProjectDetails, acceptProject, rejectProject } = require('../../../controllers/panel/projects/projectController') -const router = express.Router() -router.get('/', getProjects) -router.get('/detail', getProjectDetails) -router.post('/accept', acceptProject) -router.post('/reject', rejectProject) -router.get('/types', getProjectTypes) -router.post('/types/create', createProjectTypes) -module.exports = router diff --git a/public/modstagram-back/routes/panel/settings/index.js b/public/modstagram-back/routes/panel/settings/index.js deleted file mode 100644 index aebc745..0000000 --- a/public/modstagram-back/routes/panel/settings/index.js +++ /dev/null @@ -1,7 +0,0 @@ -const express = require('express') -const { getSetting, updateSetting } = require('../../../controllers/panel/settings/settingsController') -const router = express.Router() -router.get('/:key', getSetting) -router.put('/:key', updateSetting) - -module.exports = router diff --git a/public/modstagram-back/routes/panel/shops/index.js b/public/modstagram-back/routes/panel/shops/index.js deleted file mode 100644 index bbeb7d6..0000000 --- a/public/modstagram-back/routes/panel/shops/index.js +++ /dev/null @@ -1,8 +0,0 @@ -const express = require('express') -const { getShops, getShopDetail, updateShop } = require('../../../controllers/panel/shops/shopsController') -const router = express.Router() -router.get('/', getShops) -router.get('/detail', getShopDetail) -router.put('/update', updateShop) - -module.exports = router diff --git a/public/modstagram-back/routes/panel/tickets/index.js b/public/modstagram-back/routes/panel/tickets/index.js deleted file mode 100644 index 08c12f0..0000000 --- a/public/modstagram-back/routes/panel/tickets/index.js +++ /dev/null @@ -1,9 +0,0 @@ -const express = require('express') -const { addAdminMessageToTicket, getAllTickets, getTicketMessages, closeTicket } = require('../../../controllers/panel/tickets/ticketsController') -const router = express.Router() -router.get('/', getAllTickets) -router.get('/messages', getTicketMessages) -router.post('/message', addAdminMessageToTicket) -router.post('/close', closeTicket) - -module.exports = router diff --git a/public/modstagram-back/routes/panel/users/index.js b/public/modstagram-back/routes/panel/users/index.js deleted file mode 100644 index d353f39..0000000 --- a/public/modstagram-back/routes/panel/users/index.js +++ /dev/null @@ -1,12 +0,0 @@ -const express = require('express') -const { getUsers, getUserDetail,changePass, updateUser, verifyUser, rejectUser, updateUserStatus } = require('../../../controllers/panel/users/usersController') -const router = express.Router() -router.get('/', getUsers) -router.post('/change-password', changePass) -router.get('/detail', getUserDetail) -router.put('/update', updateUser) -router.post('/verify', verifyUser) -router.post('/reject', rejectUser) -router.post('/update-status', updateUserStatus); - -module.exports = router diff --git a/public/modstagram-back/routes/panel/version/index.js b/public/modstagram-back/routes/panel/version/index.js deleted file mode 100644 index c726f6a..0000000 --- a/public/modstagram-back/routes/panel/version/index.js +++ /dev/null @@ -1,7 +0,0 @@ -const express = require('express') -const { getVersion, upsertVersion } = require('../../../controllers/panel/version/versionController') -const router = express.Router() -router.get('/', getVersion) -router.post('/', upsertVersion) - -module.exports = router diff --git a/public/modstagram-back/sample_env b/public/modstagram-back/sample_env deleted file mode 100644 index cc35c85..0000000 --- a/public/modstagram-back/sample_env +++ /dev/null @@ -1,67 +0,0 @@ - - # # App - # APP_PORT = 8000 - # APP_URL=http://localhost:8000/api/v1 - # APP_SITE=http://localhost:3001 - # APP_SECRET=c15a74aaa7dc85814cbe4d84e56e366e0c2025bad8b8b39eefa704b302fa7991 - # SMS_SECRET=eGG6ub8pDcaNWqgt - # SMS_VERIFY_KEY=2JKxGbTzE64t0YTkjip6RYHnm9mq1haMlidF8WWwQunwubHFVW6iaMmfFQbMXEDt - # MERCHENT_CODE=c7c41e8a-918f-4741-bcd5-58f3bc51db73 - # # Mongo - # MONGO_HOST=localhost - # MONGO_DBNAME=modstagram - # MONGO_USERNAME= - # MONGO_PASSWORD= - # MONGO_PORT=27017 - - - # App - APP_PORT=3000 -APP_URL=https://app.modstagram.ir/api/v1 -APP_SITE=https://modstagram.com -APP_SITE_CallBack=https://modstagram.com/api/v1 -APP_SECRET=c15a74aaa7dc85814cbe4d84e56e366e0c2025bad8b8b39eefa704b302fa7991 -DATABASE_URL=mongodb://root:X9vLm2QrT8pS@localhost:27017/modstagram?authSource=admin -SMS_SECRET=eGG6ub8pDcaNWqgt -SMS_VERIFY_KEY=2JKxGbTzE64t0YTkjip6RYHnm9mq1haMlidF8WWwQunwubHFVW6iaMmfFQbMXEDt -MERCHENT_CODE=c7c41e8a-918f-4741-bcd5-58f3bc51db73 -ZARINPAL_MERCHANT_ID=c7c41e8a-918f-4741-bcd5-58f3bc51db73 -MONGO_HOST=localhost -MONGO_DBNAME=modstagram -MONGO_USERNAME=root -MONGO_PASSWORD=X9vLm2QrT8pS -MONGO_PORT=27017 -NODE_ENV=production - - # # App - # APP_PORT = 8000 - # APP_URL=http://localhost:8000/api/v1 - # APP_SECRET=c15a74aaa7dc85814cbe4d84e56e366e0c2025bad8b8b39eefa704b302fa7991 - # SMS_SECRET=eGG6ub8pDcaNWqgt - # SMS_VERIFY_KEY=2JKxGbTzE64t0YTkjip6RYHnm9mq1haMlidF8WWwQunwubHFVW6iaMmfFQbMXEDt - # MERCHENT_CODE=c7c41e8a-918f-4741-bcd5-58f3bc51db73 - # # Mongo - # MONGO_HOST=localhost - # MONGO_DBNAME=modstagram - # MONGO_USERNAME= - # MONGO_PASSWORD= - # MONGO_PORT=27017 - - - # App - # APP_PORT=3000 - # APP_URL=https://app.modstagram.ir/api/v1 - # APP_SITE=https://modstagram.com - # APP_SECRET=c15a74aaa7dc85814cbe4d84e56e366e0c2025bad8b8b39eefa704b302fa7991 - # DATABASE_URL=mongodb://root:KSDfEFklTjjO9KvOmSYlLtjw@modstagramdb:27017/my-app?authSource=admin - # SMS_SECRET=eGG6ub8pDcaNWqgt - # SMS_VERIFY_KEY=2JKxGbTzE64t0YTkjip6RYHnm9mq1haMlidF8WWwQunwubHFVW6iaMmfFQbMXEDt - # MERCHENT_CODE=c7c41e8a-918f-4741-bcd5-58f3bc51db73 - # Mongo - # MONGO_HOST=localhost - # MONGO_DBNAME=modstagram - # MONGO_USERNAME= - # MONGO_PASSWORD= - # MONGO_PORT=27017 - # NODE_ENV=production - \ No newline at end of file diff --git a/public/modstagram-back/server.js b/public/modstagram-back/server.js deleted file mode 100644 index a3abc81..0000000 --- a/public/modstagram-back/server.js +++ /dev/null @@ -1,3 +0,0 @@ -require('dotenv').config() -const bootApplication = require('./index') -bootApplication(process.env.APP_PORT) diff --git a/public/modstagram-back/services/AdvertisingCron.js b/public/modstagram-back/services/AdvertisingCron.js deleted file mode 100644 index 8e51b70..0000000 --- a/public/modstagram-back/services/AdvertisingCron.js +++ /dev/null @@ -1,44 +0,0 @@ -const cron = require('node-cron') -const AdvertisingModel = require('../models/AdvertisingModel') -const NotificationModel = require('../models/NotificationModel') - -// تابع برای به‌روزرسانی تبلیغات منقضی شده -const updateExpiredAdvertisings = async () => { - const now = new Date() - const oneMonthAgo = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000) - - try { - const expiredAds = await AdvertisingModel.find({ - status: 'accepted', - acceptedAt: { $lte: oneMonthAgo } - }) - - for (const ad of expiredAds) { - ad.status = 'expired' - ad.payment_status = null - await ad.save() - - // ایجاد و ذخیره نوتیفیکیشن - const notification = new NotificationModel({ - user_id: ad.creator_id, - project_post_id: ad._id, - type: 'vitrine', - title: 'انقضای ویترین', - description: `ویترین شما با عنوان: ${ad.title} منقضی شد ` - }) - await notification.save() - } - - console.log(`Updated ${expiredAds.length} expired advertisings successfully`) - } catch (error) { - console.error('Error updating expired advertisings:', error) - } -} - -// تنظیم کرون جاب برای اجرای هر ساعت -cron.schedule('0 * * * *', () => { - console.log('Running cron job to update expired advertisings') - updateExpiredAdvertisings() -}) - -module.exports = updateExpiredAdvertisings diff --git a/public/modstagram-back/services/ProjectCron.js b/public/modstagram-back/services/ProjectCron.js deleted file mode 100644 index f2cfedb..0000000 --- a/public/modstagram-back/services/ProjectCron.js +++ /dev/null @@ -1,44 +0,0 @@ -const cron = require('node-cron') -const ProjectModel = require('../models/ProjectModel') -const NotificationModel = require('../models/NotificationModel') - -// تابع برای به‌روزرسانی پروژه‌های منقضی شده -const updateExpiredProjects = async () => { - const now = new Date() - const oneMonthAgo = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000) - - try { - // جستجوی پروژه‌های منقضی شده که هنوز به‌روزرسانی نشده‌اند - const expiredProjects = await ProjectModel.find({ - isExpired: false, // فقط پروژه‌هایی که هنوز منقضی نشده‌اند - acceptedAt: { $lte: oneMonthAgo } // بر اساس تاریخ انقضا - }) - - for (const project of expiredProjects) { - project.isExpired = true // تنظیم وضعیت منقضی شده - await project.save() - - // ایجاد و ذخیره نوتیفیکیشن - const notification = new NotificationModel({ - user_id: project.creator_id, - project_post_id: project._id, - type: 'project', - title: 'انقضای پروژه', - description: `پروژه شما با عنوان: ${project.title} منقضی شد.` - }) - await notification.save() - } - - console.log(`Updated ${expiredProjects.length} expired projects successfully`) - } catch (error) { - console.error('Error updating expired projects:', error) - } -} - -// تنظیم کرون جاب برای اجرای هر ساعت -cron.schedule('0 * * * *', () => { - console.log('Running cron job to update expired projects') - updateExpiredProjects() -}) - -module.exports = updateExpiredProjects diff --git a/public/modstagram-back/services/TokenService.js b/public/modstagram-back/services/TokenService.js deleted file mode 100644 index 49404d5..0000000 --- a/public/modstagram-back/services/TokenService.js +++ /dev/null @@ -1,13 +0,0 @@ -const jwt = require('jsonwebtoken') - -exports.sign = (data) => { - return jwt.sign(data, process.env.APP_SECRET) -} -exports.verify = (token) => { - try { - jwt.verify(token, process.env.APP_SECRET) - return true - } catch (error) { - return false - } -} diff --git a/public/modstagram-back/webpack b/public/modstagram-back/webpack deleted file mode 100644 index e69de29..0000000 diff --git a/public/modstagram-back/webpack.config.js b/public/modstagram-back/webpack.config.js deleted file mode 100644 index 938a0f6..0000000 --- a/public/modstagram-back/webpack.config.js +++ /dev/null @@ -1,12 +0,0 @@ -const path = require('path') - -module.exports = { - mode: 'production', - entry: './server.js', - output: { - path: path.join(__dirname, 'dist'), - publicPath: '/', - filename: 'final.js' - }, - target: 'node' -} diff --git a/public/modstagram_panel/.gitignore b/public/modstagram_panel/.gitignore deleted file mode 100644 index 4d29575..0000000 --- a/public/modstagram_panel/.gitignore +++ /dev/null @@ -1,23 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.js - -# testing -/coverage - -# production -/build - -# misc -.DS_Store -.env.local -.env.development.local -.env.test.local -.env.production.local - -npm-debug.log* -yarn-debug.log* -yarn-error.log* diff --git a/public/modstagram_panel/README.md b/public/modstagram_panel/README.md deleted file mode 100644 index 58beeac..0000000 --- a/public/modstagram_panel/README.md +++ /dev/null @@ -1,70 +0,0 @@ -# Getting Started with Create React App - -This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). - -## Available Scripts - -In the project directory, you can run: - -### `npm start` - -Runs the app in the development mode.\ -Open [http://localhost:3000](http://localhost:3000) to view it in your browser. - -The page will reload when you make changes.\ -You may also see any lint errors in the console. - -### `npm test` - -Launches the test runner in the interactive watch mode.\ -See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. - -### `npm run build` - -Builds the app for production to the `build` folder.\ -It correctly bundles React in production mode and optimizes the build for the best performance. - -The build is minified and the filenames include the hashes.\ -Your app is ready to be deployed! - -See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. - -### `npm run eject` - -**Note: this is a one-way operation. Once you `eject`, you can't go back!** - -If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. - -Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own. - -You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it. - -## Learn More - -You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). - -To learn React, check out the [React documentation](https://reactjs.org/). - -### Code Splitting - -This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting) - -### Analyzing the Bundle Size - -This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size) - -### Making a Progressive Web App - -This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app) - -### Advanced Configuration - -This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration) - -### Deployment - -This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment) - -### `npm run build` fails to minify - -This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify) diff --git a/public/modstagram_panel/package-lock.json b/public/modstagram_panel/package-lock.json deleted file mode 100644 index 0a77ce0..0000000 --- a/public/modstagram_panel/package-lock.json +++ /dev/null @@ -1,19096 +0,0 @@ -{ - "name": "modstagram_panel", - "version": "0.1.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "modstagram_panel", - "version": "0.1.0", - "dependencies": { - "@testing-library/jest-dom": "^5.17.0", - "@testing-library/react": "^13.4.0", - "@testing-library/user-event": "^13.5.0", - "axios": "^1.6.8", - "js-cookie": "^3.0.5", - "moment-jalaali": "^0.10.4", - "react": "^18.3.1", - "react-dom": "^18.3.1", - "react-hot-toast": "^2.4.1", - "react-icons": "^5.5.0", - "react-modal": "^3.16.1", - "react-multi-date-picker": "^4.5.2", - "react-quill": "^2.0.0", - "react-router-dom": "^6.23.1", - "react-scripts": "5.0.1", - "web-vitals": "^2.1.4", - "yup": "^1.4.0" - }, - "devDependencies": { - "@babel/plugin-proposal-private-property-in-object": "^7.21.11", - "tailwindcss": "^3.4.3" - } - }, - "node_modules/@adobe/css-tools": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.4.tgz", - "integrity": "sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==" - }, - "node_modules/@alloc/quick-lru": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", - "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", - "dependencies": { - "@babel/helper-validator-identifier": "^7.27.1", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz", - "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", - "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.5", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-module-transforms": "^7.28.3", - "@babel/helpers": "^7.28.4", - "@babel/parser": "^7.28.5", - "@babel/template": "^7.27.2", - "@babel/traverse": "^7.28.5", - "@babel/types": "^7.28.5", - "@jridgewell/remapping": "^2.3.5", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/eslint-parser": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.28.5.tgz", - "integrity": "sha512-fcdRcWahONYo+JRnJg1/AekOacGvKx12Gu0qXJXFi2WBqQA1i7+O5PaxRB7kxE/Op94dExnCiiar6T09pvdHpA==", - "dependencies": { - "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", - "eslint-visitor-keys": "^2.1.0", - "semver": "^6.3.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || >=14.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.11.0", - "eslint": "^7.5.0 || ^8.0.0 || ^9.0.0" - } - }, - "node_modules/@babel/eslint-parser/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "engines": { - "node": ">=10" - } - }, - "node_modules/@babel/generator": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", - "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", - "dependencies": { - "@babel/parser": "^7.28.5", - "@babel/types": "^7.28.5", - "@jridgewell/gen-mapping": "^0.3.12", - "@jridgewell/trace-mapping": "^0.3.28", - "jsesc": "^3.0.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.27.3", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", - "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", - "dependencies": { - "@babel/types": "^7.27.3" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", - "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", - "dependencies": { - "@babel/compat-data": "^7.27.2", - "@babel/helper-validator-option": "^7.27.1", - "browserslist": "^4.24.0", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.5.tgz", - "integrity": "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.3", - "@babel/helper-member-expression-to-functions": "^7.28.5", - "@babel/helper-optimise-call-expression": "^7.27.1", - "@babel/helper-replace-supers": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", - "@babel/traverse": "^7.28.5", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.28.5.tgz", - "integrity": "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.3", - "regexpu-core": "^6.3.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.5.tgz", - "integrity": "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==", - "dependencies": { - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-plugin-utils": "^7.27.1", - "debug": "^4.4.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.22.10" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/@babel/helper-globals": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", - "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz", - "integrity": "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==", - "dependencies": { - "@babel/traverse": "^7.28.5", - "@babel/types": "^7.28.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", - "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", - "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", - "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", - "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1", - "@babel/traverse": "^7.28.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", - "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", - "dependencies": { - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", - "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz", - "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-wrap-function": "^7.27.1", - "@babel/traverse": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz", - "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==", - "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.27.1", - "@babel/helper-optimise-call-expression": "^7.27.1", - "@babel/traverse": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", - "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", - "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", - "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", - "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-wrap-function": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.3.tgz", - "integrity": "sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g==", - "dependencies": { - "@babel/template": "^7.27.2", - "@babel/traverse": "^7.28.3", - "@babel/types": "^7.28.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", - "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", - "dependencies": { - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", - "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", - "dependencies": { - "@babel/types": "^7.28.5" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.28.5.tgz", - "integrity": "sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/traverse": "^7.28.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz", - "integrity": "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz", - "integrity": "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz", - "integrity": "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", - "@babel/plugin-transform-optional-chaining": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.13.0" - } - }, - "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.3.tgz", - "integrity": "sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/traverse": "^7.28.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-proposal-class-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", - "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", - "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-decorators": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.28.0.tgz", - "integrity": "sha512-zOiZqvANjWDUaUS9xMxbMcK/Zccztbe/6ikvUXaG9nsPH3w6qh5UaPGAnirI/WhIbZ8m3OHU0ReyPrknG+ZKeg==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/plugin-syntax-decorators": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", - "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", - "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-nullish-coalescing-operator instead.", - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-numeric-separator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", - "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", - "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-numeric-separator instead.", - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-optional-chaining": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz", - "integrity": "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==", - "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-chaining instead.", - "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-private-methods": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", - "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", - "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-methods instead.", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.21.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.11.tgz", - "integrity": "sha512-0QZ8qP/3RLDVBwBFoWAwCtgcDZJVwA5LUJRZU8x2YFfKNuFq161wK3cuGrALu5yiPu+vzwTAg/sMWVNeWeNyaw==", - "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-property-in-object instead.", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-create-class-features-plugin": "^7.21.0", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-decorators": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.27.1.tgz", - "integrity": "sha512-YMq8Z87Lhl8EGkmb0MwYkt36QnxC+fzCgrl66ereamPlYToRpIk5nUjKUY3QKLWq8mwUB1BgbeXcTJhZOCDg5A==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-flow": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.27.1.tgz", - "integrity": "sha512-p9OkPbZ5G7UT1MofwYFigGebnrzGJacoBSQM0/6bi/PUMVE+qlWDD/OalvQKbwgQzU6dl0xAv6r4X7Jme0RYxA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.27.1.tgz", - "integrity": "sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz", - "integrity": "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz", - "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", - "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-unicode-sets-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", - "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz", - "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.28.0.tgz", - "integrity": "sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-remap-async-to-generator": "^7.27.1", - "@babel/traverse": "^7.28.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.27.1.tgz", - "integrity": "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==", - "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-remap-async-to-generator": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz", - "integrity": "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.5.tgz", - "integrity": "sha512-45DmULpySVvmq9Pj3X9B+62Xe+DJGov27QravQJU1LLcapR6/10i+gYVAucGGJpHBp5mYxIMK4nDAT/QDLr47g==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz", - "integrity": "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.3.tgz", - "integrity": "sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.28.3", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0" - } - }, - "node_modules/@babel/plugin-transform-classes": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.4.tgz", - "integrity": "sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.3", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-globals": "^7.28.0", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-replace-supers": "^7.27.1", - "@babel/traverse": "^7.28.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.27.1.tgz", - "integrity": "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/template": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz", - "integrity": "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/traverse": "^7.28.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.27.1.tgz", - "integrity": "sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz", - "integrity": "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.27.1.tgz", - "integrity": "sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz", - "integrity": "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-explicit-resource-management": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.0.tgz", - "integrity": "sha512-K8nhUcn3f6iB+P3gwCv/no7OdzOZQcKchW6N389V6PD8NUWKZHzndOd9sPDVbMoBsbmjMqlB4L9fm+fEFNVlwQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/plugin-transform-destructuring": "^7.28.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.5.tgz", - "integrity": "sha512-D4WIMaFtwa2NizOp+dnoFjRez/ClKiC2BqqImwKd1X28nqBtZEyCYJ2ozQrrzlxAFrcrjxo39S6khe9RNDlGzw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz", - "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-flow-strip-types": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.27.1.tgz", - "integrity": "sha512-G5eDKsu50udECw7DL2AcsysXiQyB7Nfg521t2OAJ4tbfTJ27doHLeF/vlI1NZGlLdbb/v+ibvtL1YBQqYOwJGg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/plugin-syntax-flow": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-for-of": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz", - "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-function-name": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz", - "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==", - "dependencies": { - "@babel/helper-compilation-targets": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/traverse": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.27.1.tgz", - "integrity": "sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-literals": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz", - "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.5.tgz", - "integrity": "sha512-axUuqnUTBuXyHGcJEVVh9pORaN6wC5bYfE7FGzPiaWa3syib9m7g+/IT/4VgCOe2Upef43PHzeAvcrVek6QuuA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz", - "integrity": "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz", - "integrity": "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==", - "dependencies": { - "@babel/helper-module-transforms": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz", - "integrity": "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==", - "dependencies": { - "@babel/helper-module-transforms": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.28.5.tgz", - "integrity": "sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew==", - "dependencies": { - "@babel/helper-module-transforms": "^7.28.3", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-validator-identifier": "^7.28.5", - "@babel/traverse": "^7.28.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz", - "integrity": "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==", - "dependencies": { - "@babel/helper-module-transforms": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.27.1.tgz", - "integrity": "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-new-target": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz", - "integrity": "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz", - "integrity": "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.27.1.tgz", - "integrity": "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.4.tgz", - "integrity": "sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew==", - "dependencies": { - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/plugin-transform-destructuring": "^7.28.0", - "@babel/plugin-transform-parameters": "^7.27.7", - "@babel/traverse": "^7.28.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-object-super": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz", - "integrity": "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-replace-supers": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.27.1.tgz", - "integrity": "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.5.tgz", - "integrity": "sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-parameters": { - "version": "7.27.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz", - "integrity": "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.27.1.tgz", - "integrity": "sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.27.1.tgz", - "integrity": "sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz", - "integrity": "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-constant-elements": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.27.1.tgz", - "integrity": "sha512-edoidOjl/ZxvYo4lSBOQGDSyToYVkTAwyVoa2tkuYTSmjrB1+uAedoL5iROVLXkxH+vRgA7uP4tMg2pUJpZ3Ug==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-display-name": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.28.0.tgz", - "integrity": "sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.27.1.tgz", - "integrity": "sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/plugin-syntax-jsx": "^7.27.1", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx-development": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.27.1.tgz", - "integrity": "sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q==", - "dependencies": { - "@babel/plugin-transform-react-jsx": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-pure-annotations": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.27.1.tgz", - "integrity": "sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.4.tgz", - "integrity": "sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-regexp-modifiers": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.27.1.tgz", - "integrity": "sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz", - "integrity": "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-runtime": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.28.5.tgz", - "integrity": "sha512-20NUVgOrinudkIBzQ2bNxP08YpKprUkRTiRSd2/Z5GOdPImJGkoN4Z7IQe1T5AdyKI1i5L6RBmluqdSzvaq9/w==", - "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "babel-plugin-polyfill-corejs2": "^0.4.14", - "babel-plugin-polyfill-corejs3": "^0.13.0", - "babel-plugin-polyfill-regenerator": "^0.6.5", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz", - "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-spread": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.27.1.tgz", - "integrity": "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz", - "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz", - "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz", - "integrity": "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-typescript": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.5.tgz", - "integrity": "sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.3", - "@babel/helper-create-class-features-plugin": "^7.28.5", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", - "@babel/plugin-syntax-typescript": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz", - "integrity": "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-property-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.27.1.tgz", - "integrity": "sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz", - "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.27.1.tgz", - "integrity": "sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/preset-env": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.28.5.tgz", - "integrity": "sha512-S36mOoi1Sb6Fz98fBfE+UZSpYw5mJm0NUHtIKrOuNcqeFauy1J6dIvXm2KRVKobOSaGq4t/hBXdN4HGU3wL9Wg==", - "dependencies": { - "@babel/compat-data": "^7.28.5", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-validator-option": "^7.27.1", - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.28.5", - "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.3", - "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", - "@babel/plugin-syntax-import-assertions": "^7.27.1", - "@babel/plugin-syntax-import-attributes": "^7.27.1", - "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.27.1", - "@babel/plugin-transform-async-generator-functions": "^7.28.0", - "@babel/plugin-transform-async-to-generator": "^7.27.1", - "@babel/plugin-transform-block-scoped-functions": "^7.27.1", - "@babel/plugin-transform-block-scoping": "^7.28.5", - "@babel/plugin-transform-class-properties": "^7.27.1", - "@babel/plugin-transform-class-static-block": "^7.28.3", - "@babel/plugin-transform-classes": "^7.28.4", - "@babel/plugin-transform-computed-properties": "^7.27.1", - "@babel/plugin-transform-destructuring": "^7.28.5", - "@babel/plugin-transform-dotall-regex": "^7.27.1", - "@babel/plugin-transform-duplicate-keys": "^7.27.1", - "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.27.1", - "@babel/plugin-transform-dynamic-import": "^7.27.1", - "@babel/plugin-transform-explicit-resource-management": "^7.28.0", - "@babel/plugin-transform-exponentiation-operator": "^7.28.5", - "@babel/plugin-transform-export-namespace-from": "^7.27.1", - "@babel/plugin-transform-for-of": "^7.27.1", - "@babel/plugin-transform-function-name": "^7.27.1", - "@babel/plugin-transform-json-strings": "^7.27.1", - "@babel/plugin-transform-literals": "^7.27.1", - "@babel/plugin-transform-logical-assignment-operators": "^7.28.5", - "@babel/plugin-transform-member-expression-literals": "^7.27.1", - "@babel/plugin-transform-modules-amd": "^7.27.1", - "@babel/plugin-transform-modules-commonjs": "^7.27.1", - "@babel/plugin-transform-modules-systemjs": "^7.28.5", - "@babel/plugin-transform-modules-umd": "^7.27.1", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1", - "@babel/plugin-transform-new-target": "^7.27.1", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1", - "@babel/plugin-transform-numeric-separator": "^7.27.1", - "@babel/plugin-transform-object-rest-spread": "^7.28.4", - "@babel/plugin-transform-object-super": "^7.27.1", - "@babel/plugin-transform-optional-catch-binding": "^7.27.1", - "@babel/plugin-transform-optional-chaining": "^7.28.5", - "@babel/plugin-transform-parameters": "^7.27.7", - "@babel/plugin-transform-private-methods": "^7.27.1", - "@babel/plugin-transform-private-property-in-object": "^7.27.1", - "@babel/plugin-transform-property-literals": "^7.27.1", - "@babel/plugin-transform-regenerator": "^7.28.4", - "@babel/plugin-transform-regexp-modifiers": "^7.27.1", - "@babel/plugin-transform-reserved-words": "^7.27.1", - "@babel/plugin-transform-shorthand-properties": "^7.27.1", - "@babel/plugin-transform-spread": "^7.27.1", - "@babel/plugin-transform-sticky-regex": "^7.27.1", - "@babel/plugin-transform-template-literals": "^7.27.1", - "@babel/plugin-transform-typeof-symbol": "^7.27.1", - "@babel/plugin-transform-unicode-escapes": "^7.27.1", - "@babel/plugin-transform-unicode-property-regex": "^7.27.1", - "@babel/plugin-transform-unicode-regex": "^7.27.1", - "@babel/plugin-transform-unicode-sets-regex": "^7.27.1", - "@babel/preset-modules": "0.1.6-no-external-plugins", - "babel-plugin-polyfill-corejs2": "^0.4.14", - "babel-plugin-polyfill-corejs3": "^0.13.0", - "babel-plugin-polyfill-regenerator": "^0.6.5", - "core-js-compat": "^3.43.0", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-env/node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.21.0-placeholder-for-preset-env.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", - "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-modules": { - "version": "0.1.6-no-external-plugins", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", - "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/@babel/preset-react": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.28.5.tgz", - "integrity": "sha512-Z3J8vhRq7CeLjdC58jLv4lnZ5RKFUJWqH5emvxmv9Hv3BD1T9R/Im713R4MTKwvFaV74ejZ3sM01LyEKk4ugNQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-validator-option": "^7.27.1", - "@babel/plugin-transform-react-display-name": "^7.28.0", - "@babel/plugin-transform-react-jsx": "^7.27.1", - "@babel/plugin-transform-react-jsx-development": "^7.27.1", - "@babel/plugin-transform-react-pure-annotations": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-typescript": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.28.5.tgz", - "integrity": "sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-validator-option": "^7.27.1", - "@babel/plugin-syntax-jsx": "^7.27.1", - "@babel/plugin-transform-modules-commonjs": "^7.27.1", - "@babel/plugin-transform-typescript": "^7.28.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/runtime": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", - "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/template": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", - "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.2", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", - "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.5", - "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.5", - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.5", - "debug": "^4.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", - "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", - "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.28.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==" - }, - "node_modules/@csstools/normalize.css": { - "version": "12.1.1", - "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-12.1.1.tgz", - "integrity": "sha512-YAYeJ+Xqh7fUou1d1j9XHl44BmsuThiTr4iNrgCQ3J27IbhXsxXDGZ1cXv8Qvs99d4rBbLiSKy3+WZiet32PcQ==" - }, - "node_modules/@csstools/postcss-cascade-layers": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-1.1.1.tgz", - "integrity": "sha512-+KdYrpKC5TgomQr2DlZF4lDEpHcoxnj5IGddYYfBWJAKfj1JtuHUIqMa+E1pJJ+z3kvDViWMqyqPlG4Ja7amQA==", - "dependencies": { - "@csstools/selector-specificity": "^2.0.2", - "postcss-selector-parser": "^6.0.10" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/@csstools/postcss-color-function": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-1.1.1.tgz", - "integrity": "sha512-Bc0f62WmHdtRDjf5f3e2STwRAl89N2CLb+9iAwzrv4L2hncrbDwnQD9PCq0gtAt7pOI2leIV08HIBUd4jxD8cw==", - "dependencies": { - "@csstools/postcss-progressive-custom-properties": "^1.1.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/@csstools/postcss-font-format-keywords": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-1.0.1.tgz", - "integrity": "sha512-ZgrlzuUAjXIOc2JueK0X5sZDjCtgimVp/O5CEqTcs5ShWBa6smhWYbS0x5cVc/+rycTDbjjzoP0KTDnUneZGOg==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/@csstools/postcss-hwb-function": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@csstools/postcss-hwb-function/-/postcss-hwb-function-1.0.2.tgz", - "integrity": "sha512-YHdEru4o3Rsbjmu6vHy4UKOXZD+Rn2zmkAmLRfPet6+Jz4Ojw8cbWxe1n42VaXQhD3CQUXXTooIy8OkVbUcL+w==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/@csstools/postcss-ic-unit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-ic-unit/-/postcss-ic-unit-1.0.1.tgz", - "integrity": "sha512-Ot1rcwRAaRHNKC9tAqoqNZhjdYBzKk1POgWfhN4uCOE47ebGcLRqXjKkApVDpjifL6u2/55ekkpnFcp+s/OZUw==", - "dependencies": { - "@csstools/postcss-progressive-custom-properties": "^1.1.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/@csstools/postcss-is-pseudo-class": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-2.0.7.tgz", - "integrity": "sha512-7JPeVVZHd+jxYdULl87lvjgvWldYu+Bc62s9vD/ED6/QTGjy0jy0US/f6BG53sVMTBJ1lzKZFpYmofBN9eaRiA==", - "dependencies": { - "@csstools/selector-specificity": "^2.0.0", - "postcss-selector-parser": "^6.0.10" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/@csstools/postcss-nested-calc": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-nested-calc/-/postcss-nested-calc-1.0.0.tgz", - "integrity": "sha512-JCsQsw1wjYwv1bJmgjKSoZNvf7R6+wuHDAbi5f/7MbFhl2d/+v+TvBTU4BJH3G1X1H87dHl0mh6TfYogbT/dJQ==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/@csstools/postcss-normalize-display-values": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-1.0.1.tgz", - "integrity": "sha512-jcOanIbv55OFKQ3sYeFD/T0Ti7AMXc9nM1hZWu8m/2722gOTxFg7xYu4RDLJLeZmPUVQlGzo4jhzvTUq3x4ZUw==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/@csstools/postcss-oklab-function": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-1.1.1.tgz", - "integrity": "sha512-nJpJgsdA3dA9y5pgyb/UfEzE7W5Ka7u0CX0/HIMVBNWzWemdcTH3XwANECU6anWv/ao4vVNLTMxhiPNZsTK6iA==", - "dependencies": { - "@csstools/postcss-progressive-custom-properties": "^1.1.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/@csstools/postcss-progressive-custom-properties": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-1.3.0.tgz", - "integrity": "sha512-ASA9W1aIy5ygskZYuWams4BzafD12ULvSypmaLJT2jvQ8G0M3I8PRQhC0h7mG0Z3LI05+agZjqSR9+K9yaQQjA==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "peerDependencies": { - "postcss": "^8.3" - } - }, - "node_modules/@csstools/postcss-stepped-value-functions": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-1.0.1.tgz", - "integrity": "sha512-dz0LNoo3ijpTOQqEJLY8nyaapl6umbmDcgj4AD0lgVQ572b2eqA1iGZYTTWhrcrHztWDDRAX2DGYyw2VBjvCvQ==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/@csstools/postcss-text-decoration-shorthand": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-1.0.0.tgz", - "integrity": "sha512-c1XwKJ2eMIWrzQenN0XbcfzckOLLJiczqy+YvfGmzoVXd7pT9FfObiSEfzs84bpE/VqfpEuAZ9tCRbZkZxxbdw==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/@csstools/postcss-trigonometric-functions": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-1.0.2.tgz", - "integrity": "sha512-woKaLO///4bb+zZC2s80l+7cm07M7268MsyG3M0ActXXEFi6SuhvriQYcb58iiKGbjwwIU7n45iRLEHypB47Og==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/@csstools/postcss-unset-value": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@csstools/postcss-unset-value/-/postcss-unset-value-1.0.2.tgz", - "integrity": "sha512-c8J4roPBILnelAsdLr4XOAR/GsTm0GJi4XpcfvoWk3U6KiTCqiFYc63KhRMQQX35jYMp4Ao8Ij9+IZRgMfJp1g==", - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/@csstools/selector-specificity": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz", - "integrity": "sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw==", - "engines": { - "node": "^14 || ^16 || >=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss-selector-parser": "^6.0.10" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.9.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", - "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", - "dependencies": { - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", - "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "node_modules/@eslint/eslintrc/node_modules/js-yaml": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@eslint/js": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", - "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", - "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", - "deprecated": "Use @eslint/config-array instead", - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.3", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead" - }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/console": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.5.1.tgz", - "integrity": "sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^27.5.1", - "jest-util": "^27.5.1", - "slash": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/console/node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/console/node_modules/@types/yargs": { - "version": "16.0.11", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.11.tgz", - "integrity": "sha512-sbtvk8wDN+JvEdabmZExoW/HNr1cB7D/j4LT08rMiuikfA7m/JNJg7ATQcgzs34zHnoScDkY0ZRSl29Fkmk36g==", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@jest/console/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/console/node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/console/node_modules/jest-message-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", - "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.5.1", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/console/node_modules/jest-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", - "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/console/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/@jest/core": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.5.1.tgz", - "integrity": "sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==", - "dependencies": { - "@jest/console": "^27.5.1", - "@jest/reporters": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^27.5.1", - "jest-config": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-resolve-dependencies": "^27.5.1", - "jest-runner": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "jest-watcher": "^27.5.1", - "micromatch": "^4.0.4", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/core/node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/core/node_modules/@types/yargs": { - "version": "16.0.11", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.11.tgz", - "integrity": "sha512-sbtvk8wDN+JvEdabmZExoW/HNr1cB7D/j4LT08rMiuikfA7m/JNJg7ATQcgzs34zHnoScDkY0ZRSl29Fkmk36g==", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@jest/core/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/core/node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/core/node_modules/jest-message-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", - "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.5.1", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/core/node_modules/jest-regex-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", - "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/core/node_modules/jest-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", - "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/core/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/@jest/diff-sequences": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.0.1.tgz", - "integrity": "sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/environment": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", - "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", - "dependencies": { - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/environment/node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/environment/node_modules/@types/yargs": { - "version": "16.0.11", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.11.tgz", - "integrity": "sha512-sbtvk8wDN+JvEdabmZExoW/HNr1cB7D/j4LT08rMiuikfA7m/JNJg7ATQcgzs34zHnoScDkY0ZRSl29Fkmk36g==", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@jest/environment/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/environment/node_modules/jest-mock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", - "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/expect-utils": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.2.0.tgz", - "integrity": "sha512-1JnRfhqpD8HGpOmQp180Fo9Zt69zNtC+9lR+kT7NVL05tNXIi+QC8Csz7lfidMoVLPD3FnOtcmp0CEFnxExGEA==", - "dependencies": { - "@jest/get-type": "30.1.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/fake-timers": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", - "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", - "dependencies": { - "@jest/types": "^27.5.1", - "@sinonjs/fake-timers": "^8.0.1", - "@types/node": "*", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/fake-timers/node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/fake-timers/node_modules/@types/yargs": { - "version": "16.0.11", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.11.tgz", - "integrity": "sha512-sbtvk8wDN+JvEdabmZExoW/HNr1cB7D/j4LT08rMiuikfA7m/JNJg7ATQcgzs34zHnoScDkY0ZRSl29Fkmk36g==", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@jest/fake-timers/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/fake-timers/node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/fake-timers/node_modules/jest-message-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", - "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.5.1", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/fake-timers/node_modules/jest-mock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", - "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/fake-timers/node_modules/jest-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", - "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/fake-timers/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/@jest/get-type": { - "version": "30.1.0", - "resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.1.0.tgz", - "integrity": "sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/globals": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz", - "integrity": "sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==", - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/types": "^27.5.1", - "expect": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/globals/node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/globals/node_modules/@types/yargs": { - "version": "16.0.11", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.11.tgz", - "integrity": "sha512-sbtvk8wDN+JvEdabmZExoW/HNr1cB7D/j4LT08rMiuikfA7m/JNJg7ATQcgzs34zHnoScDkY0ZRSl29Fkmk36g==", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@jest/globals/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/globals/node_modules/expect": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", - "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", - "dependencies": { - "@jest/types": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/globals/node_modules/jest-diff": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", - "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/globals/node_modules/jest-matcher-utils": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", - "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/globals/node_modules/jest-message-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", - "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.5.1", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/pattern": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.0.1.tgz", - "integrity": "sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==", - "dependencies": { - "@types/node": "*", - "jest-regex-util": "30.0.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/reporters": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.5.1.tgz", - "integrity": "sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==", - "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^5.1.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-haste-map": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^8.1.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/reporters/node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/reporters/node_modules/@types/yargs": { - "version": "16.0.11", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.11.tgz", - "integrity": "sha512-sbtvk8wDN+JvEdabmZExoW/HNr1cB7D/j4LT08rMiuikfA7m/JNJg7ATQcgzs34zHnoScDkY0ZRSl29Fkmk36g==", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@jest/reporters/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/reporters/node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/reporters/node_modules/jest-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", - "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/reporters/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/@jest/reporters/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@jest/schemas": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", - "dependencies": { - "@sinclair/typebox": "^0.34.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/source-map": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz", - "integrity": "sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==", - "dependencies": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9", - "source-map": "^0.6.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/source-map/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@jest/test-result": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.5.1.tgz", - "integrity": "sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==", - "dependencies": { - "@jest/console": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/test-result/node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/test-result/node_modules/@types/yargs": { - "version": "16.0.11", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.11.tgz", - "integrity": "sha512-sbtvk8wDN+JvEdabmZExoW/HNr1cB7D/j4LT08rMiuikfA7m/JNJg7ATQcgzs34zHnoScDkY0ZRSl29Fkmk36g==", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@jest/test-result/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/test-sequencer": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", - "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", - "dependencies": { - "@jest/test-result": "^27.5.1", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-runtime": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/transform": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", - "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", - "dependencies": { - "@babel/core": "^7.1.0", - "@jest/types": "^27.5.1", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-util": "^27.5.1", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/transform/node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/transform/node_modules/@types/yargs": { - "version": "16.0.11", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.11.tgz", - "integrity": "sha512-sbtvk8wDN+JvEdabmZExoW/HNr1cB7D/j4LT08rMiuikfA7m/JNJg7ATQcgzs34zHnoScDkY0ZRSl29Fkmk36g==", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@jest/transform/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/transform/node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/transform/node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" - }, - "node_modules/@jest/transform/node_modules/jest-regex-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", - "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/transform/node_modules/jest-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", - "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/transform/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/@jest/transform/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@jest/types": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", - "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", - "dependencies": { - "@jest/pattern": "30.0.1", - "@jest/schemas": "30.0.5", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", - "@types/node": "*", - "@types/yargs": "^17.0.33", - "chalk": "^4.1.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/types/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", - "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/remapping": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", - "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.11", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", - "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@leichtgewicht/ip-codec": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", - "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==" - }, - "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { - "version": "5.1.1-v1", - "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", - "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", - "dependencies": { - "eslint-scope": "5.1.1" - } - }, - "node_modules/@nicolo-ribaudo/eslint-scope-5-internals/node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@nicolo-ribaudo/eslint-scope-5-internals/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@pmmmwh/react-refresh-webpack-plugin": { - "version": "0.5.17", - "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.17.tgz", - "integrity": "sha512-tXDyE1/jzFsHXjhRZQ3hMl0IVhYe5qula43LDWIhVfjp9G/nT5OQY5AORVOrkEGAUltBJOfOWeETbmhm6kHhuQ==", - "dependencies": { - "ansi-html": "^0.0.9", - "core-js-pure": "^3.23.3", - "error-stack-parser": "^2.0.6", - "html-entities": "^2.1.0", - "loader-utils": "^2.0.4", - "schema-utils": "^4.2.0", - "source-map": "^0.7.3" - }, - "engines": { - "node": ">= 10.13" - }, - "peerDependencies": { - "@types/webpack": "4.x || 5.x", - "react-refresh": ">=0.10.0 <1.0.0", - "sockjs-client": "^1.4.0", - "type-fest": ">=0.17.0 <5.0.0", - "webpack": ">=4.43.0 <6.0.0", - "webpack-dev-server": "3.x || 4.x || 5.x", - "webpack-hot-middleware": "2.x", - "webpack-plugin-serve": "0.x || 1.x" - }, - "peerDependenciesMeta": { - "@types/webpack": { - "optional": true - }, - "sockjs-client": { - "optional": true - }, - "type-fest": { - "optional": true - }, - "webpack-dev-server": { - "optional": true - }, - "webpack-hot-middleware": { - "optional": true - }, - "webpack-plugin-serve": { - "optional": true - } - } - }, - "node_modules/@remix-run/router": { - "version": "1.23.1", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.1.tgz", - "integrity": "sha512-vDbaOzF7yT2Qs4vO6XV1MHcJv+3dgR1sT+l3B8xxOVhUC336prMvqrvsLL/9Dnw2xr6Qhz4J0dmS0llNAbnUmQ==", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@rollup/plugin-babel": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", - "integrity": "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==", - "dependencies": { - "@babel/helper-module-imports": "^7.10.4", - "@rollup/pluginutils": "^3.1.0" - }, - "engines": { - "node": ">= 10.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0", - "@types/babel__core": "^7.1.9", - "rollup": "^1.20.0||^2.0.0" - }, - "peerDependenciesMeta": { - "@types/babel__core": { - "optional": true - } - } - }, - "node_modules/@rollup/plugin-node-resolve": { - "version": "11.2.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz", - "integrity": "sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==", - "dependencies": { - "@rollup/pluginutils": "^3.1.0", - "@types/resolve": "1.17.1", - "builtin-modules": "^3.1.0", - "deepmerge": "^4.2.2", - "is-module": "^1.0.0", - "resolve": "^1.19.0" - }, - "engines": { - "node": ">= 10.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0" - } - }, - "node_modules/@rollup/plugin-replace": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz", - "integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==", - "dependencies": { - "@rollup/pluginutils": "^3.1.0", - "magic-string": "^0.25.7" - }, - "peerDependencies": { - "rollup": "^1.20.0 || ^2.0.0" - } - }, - "node_modules/@rollup/pluginutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", - "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", - "dependencies": { - "@types/estree": "0.0.39", - "estree-walker": "^1.0.1", - "picomatch": "^2.2.2" - }, - "engines": { - "node": ">= 8.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0" - } - }, - "node_modules/@rollup/pluginutils/node_modules/@types/estree": { - "version": "0.0.39", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", - "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==" - }, - "node_modules/@rollup/pluginutils/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/@rtsao/scc": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", - "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==" - }, - "node_modules/@rushstack/eslint-patch": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.15.0.tgz", - "integrity": "sha512-ojSshQPKwVvSMR8yT2L/QtUkV5SXi/IfDiJ4/8d6UbTPjiHVmxZzUAzGD8Tzks1b9+qQkZa0isUOvYObedITaw==" - }, - "node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==" - }, - "node_modules/@sinonjs/commons": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", - "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", - "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", - "dependencies": { - "@sinonjs/commons": "^1.7.0" - } - }, - "node_modules/@surma/rollup-plugin-off-main-thread": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz", - "integrity": "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==", - "dependencies": { - "ejs": "^3.1.6", - "json5": "^2.2.0", - "magic-string": "^0.25.0", - "string.prototype.matchall": "^4.0.6" - } - }, - "node_modules/@svgr/babel-plugin-add-jsx-attribute": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-5.4.0.tgz", - "integrity": "sha512-ZFf2gs/8/6B8PnSofI0inYXr2SDNTDScPXhN7k5EqD4aZ3gi6u+rbmZHVB8IM3wDyx8ntKACZbtXSm7oZGRqVg==", - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-5.4.0.tgz", - "integrity": "sha512-yaS4o2PgUtwLFGTKbsiAy6D0o3ugcUhWK0Z45umJ66EPWunAz9fuFw2gJuje6wqQvQWOTJvIahUwndOXb7QCPg==", - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-5.0.1.tgz", - "integrity": "sha512-LA72+88A11ND/yFIMzyuLRSMJ+tRKeYKeQ+mR3DcAZ5I4h5CPWN9AHyUzJbWSYp/u2u0xhmgOe0+E41+GjEueA==", - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-5.0.1.tgz", - "integrity": "sha512-PoiE6ZD2Eiy5mK+fjHqwGOS+IXX0wq/YDtNyIgOrc6ejFnxN4b13pRpiIPbtPwHEc+NT2KCjteAcq33/F1Y9KQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/babel-plugin-svg-dynamic-title": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-5.4.0.tgz", - "integrity": "sha512-zSOZH8PdZOpuG1ZVx/cLVePB2ibo3WPpqo7gFIjLV9a0QsuQAzJiwwqmuEdTaW2pegyBE17Uu15mOgOcgabQZg==", - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/babel-plugin-svg-em-dimensions": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-5.4.0.tgz", - "integrity": "sha512-cPzDbDA5oT/sPXDCUYoVXEmm3VIoAWAPT6mSPTJNbQaBNUuEKVKyGH93oDY4e42PYHRW67N5alJx/eEol20abw==", - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/babel-plugin-transform-react-native-svg": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-5.4.0.tgz", - "integrity": "sha512-3eYP/SaopZ41GHwXma7Rmxcv9uRslRDTY1estspeB1w1ueZWd/tPlMfEOoccYpEMZU3jD4OU7YitnXcF5hLW2Q==", - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/babel-plugin-transform-svg-component": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-5.5.0.tgz", - "integrity": "sha512-q4jSH1UUvbrsOtlo/tKcgSeiCHRSBdXoIoqX1pgcKK/aU3JD27wmMKwGtpB8qRYUYoyXvfGxUVKchLuR5pB3rQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/babel-preset": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-5.5.0.tgz", - "integrity": "sha512-4FiXBjvQ+z2j7yASeGPEi8VD/5rrGQk4Xrq3EdJmoZgz/tpqChpo5hgXDvmEauwtvOc52q8ghhZK4Oy7qph4ig==", - "dependencies": { - "@svgr/babel-plugin-add-jsx-attribute": "^5.4.0", - "@svgr/babel-plugin-remove-jsx-attribute": "^5.4.0", - "@svgr/babel-plugin-remove-jsx-empty-expression": "^5.0.1", - "@svgr/babel-plugin-replace-jsx-attribute-value": "^5.0.1", - "@svgr/babel-plugin-svg-dynamic-title": "^5.4.0", - "@svgr/babel-plugin-svg-em-dimensions": "^5.4.0", - "@svgr/babel-plugin-transform-react-native-svg": "^5.4.0", - "@svgr/babel-plugin-transform-svg-component": "^5.5.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/core": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/core/-/core-5.5.0.tgz", - "integrity": "sha512-q52VOcsJPvV3jO1wkPtzTuKlvX7Y3xIcWRpCMtBF3MrteZJtBfQw/+u0B1BHy5ColpQc1/YVTrPEtSYIMNZlrQ==", - "dependencies": { - "@svgr/plugin-jsx": "^5.5.0", - "camelcase": "^6.2.0", - "cosmiconfig": "^7.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/hast-util-to-babel-ast": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-5.5.0.tgz", - "integrity": "sha512-cAaR/CAiZRB8GP32N+1jocovUtvlj0+e65TB50/6Lcime+EA49m/8l+P2ko+XPJ4dw3xaPS3jOL4F2X4KWxoeQ==", - "dependencies": { - "@babel/types": "^7.12.6" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/plugin-jsx": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-5.5.0.tgz", - "integrity": "sha512-V/wVh33j12hGh05IDg8GpIUXbjAPnTdPTKuP4VNLggnwaHMPNQNae2pRnyTAILWCQdz5GyMqtO488g7CKM8CBA==", - "dependencies": { - "@babel/core": "^7.12.3", - "@svgr/babel-preset": "^5.5.0", - "@svgr/hast-util-to-babel-ast": "^5.5.0", - "svg-parser": "^2.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/plugin-svgo": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-5.5.0.tgz", - "integrity": "sha512-r5swKk46GuQl4RrVejVwpeeJaydoxkdwkM1mBKOgJLBUJPGaLci6ylg/IjhrRsREKDkr4kbMWdgOtbXEh0fyLQ==", - "dependencies": { - "cosmiconfig": "^7.0.0", - "deepmerge": "^4.2.2", - "svgo": "^1.2.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/webpack": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-5.5.0.tgz", - "integrity": "sha512-DOBOK255wfQxguUta2INKkzPj6AIS6iafZYiYmHn6W3pHlycSRRlvWKCfLDG10fXfLWqE3DJHgRUOyJYmARa7g==", - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/plugin-transform-react-constant-elements": "^7.12.1", - "@babel/preset-env": "^7.12.1", - "@babel/preset-react": "^7.12.5", - "@svgr/core": "^5.5.0", - "@svgr/plugin-jsx": "^5.5.0", - "@svgr/plugin-svgo": "^5.5.0", - "loader-utils": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@testing-library/dom": { - "version": "10.4.1", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", - "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", - "peer": true, - "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/runtime": "^7.12.5", - "@types/aria-query": "^5.0.1", - "aria-query": "5.3.0", - "dom-accessibility-api": "^0.5.9", - "lz-string": "^1.5.0", - "picocolors": "1.1.1", - "pretty-format": "^27.0.2" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@testing-library/jest-dom": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz", - "integrity": "sha512-ynmNeT7asXyH3aSVv4vvX4Rb+0qjOhdNHnO/3vuZNqPmhDpV/+rCSGwQ7bLcmU2cJ4dvoheIO85LQj0IbJHEtg==", - "dependencies": { - "@adobe/css-tools": "^4.0.1", - "@babel/runtime": "^7.9.2", - "@types/testing-library__jest-dom": "^5.9.1", - "aria-query": "^5.0.0", - "chalk": "^3.0.0", - "css.escape": "^1.5.1", - "dom-accessibility-api": "^0.5.6", - "lodash": "^4.17.15", - "redent": "^3.0.0" - }, - "engines": { - "node": ">=8", - "npm": ">=6", - "yarn": ">=1" - } - }, - "node_modules/@testing-library/react": { - "version": "13.4.0", - "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-13.4.0.tgz", - "integrity": "sha512-sXOGON+WNTh3MLE9rve97ftaZukN3oNf2KjDy7YTx6hcTO2uuLHuCGynMDhFwGw/jYf4OJ2Qk0i4i79qMNNkyw==", - "dependencies": { - "@babel/runtime": "^7.12.5", - "@testing-library/dom": "^8.5.0", - "@types/react-dom": "^18.0.0" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@testing-library/react/node_modules/@testing-library/dom": { - "version": "8.20.1", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.20.1.tgz", - "integrity": "sha512-/DiOQ5xBxgdYRC8LNk7U+RWat0S3qRLeIw3ZIkMQ9kkVlRmwD/Eg8k8CqIpD6GW7u20JIUOfMKbxtiLutpjQ4g==", - "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/runtime": "^7.12.5", - "@types/aria-query": "^5.0.1", - "aria-query": "5.1.3", - "chalk": "^4.1.0", - "dom-accessibility-api": "^0.5.9", - "lz-string": "^1.5.0", - "pretty-format": "^27.0.2" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@testing-library/react/node_modules/aria-query": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", - "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", - "dependencies": { - "deep-equal": "^2.0.5" - } - }, - "node_modules/@testing-library/react/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@testing-library/react/node_modules/deep-equal": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", - "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.5", - "es-get-iterator": "^1.1.3", - "get-intrinsic": "^1.2.2", - "is-arguments": "^1.1.1", - "is-array-buffer": "^3.0.2", - "is-date-object": "^1.0.5", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "isarray": "^2.0.5", - "object-is": "^1.1.5", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.1", - "side-channel": "^1.0.4", - "which-boxed-primitive": "^1.0.2", - "which-collection": "^1.0.1", - "which-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/@testing-library/user-event": { - "version": "13.5.0", - "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-13.5.0.tgz", - "integrity": "sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg==", - "dependencies": { - "@babel/runtime": "^7.12.5" - }, - "engines": { - "node": ">=10", - "npm": ">=6" - }, - "peerDependencies": { - "@testing-library/dom": ">=7.21.4" - } - }, - "node_modules/@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/@trysound/sax": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", - "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/@types/aria-query": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", - "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==" - }, - "node_modules/@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", - "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", - "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", - "dependencies": { - "@babel/types": "^7.28.2" - } - }, - "node_modules/@types/body-parser": { - "version": "1.19.6", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", - "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "node_modules/@types/bonjour": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", - "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/connect-history-api-fallback": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", - "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", - "dependencies": { - "@types/express-serve-static-core": "*", - "@types/node": "*" - } - }, - "node_modules/@types/eslint": { - "version": "8.56.12", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.12.tgz", - "integrity": "sha512-03ruubjWyOHlmljCVoxSuNDdmfZDzsrrz0P2LeJsOXr+ZwFQ+0yQIwNCwt/GYhV7Z31fgtXJTAEs+FYlEL851g==", - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/eslint-scope": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==" - }, - "node_modules/@types/express": { - "version": "4.17.25", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.25.tgz", - "integrity": "sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==", - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "^1" - } - }, - "node_modules/@types/express-serve-static-core": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.1.0.tgz", - "integrity": "sha512-jnHMsrd0Mwa9Cf4IdOzbz543y4XJepXrbia2T4b6+spXC2We3t1y6K44D3mR8XMFSXMCf3/l7rCgddfx7UNVBA==", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, - "node_modules/@types/express/node_modules/@types/express-serve-static-core": { - "version": "4.19.7", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.7.tgz", - "integrity": "sha512-FvPtiIf1LfhzsaIXhv/PHan/2FeQBbtBDtfX2QfvPxdUelMDEckK08SM6nqo1MIZY3RUlfA+HV8+hFUSio78qg==", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, - "node_modules/@types/graceful-fs": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", - "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==" - }, - "node_modules/@types/http-errors": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", - "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==" - }, - "node_modules/@types/http-proxy": { - "version": "1.17.17", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.17.tgz", - "integrity": "sha512-ED6LB+Z1AVylNTu7hdzuBqOgMnvG/ld6wGCG8wFnAzKX5uyW2K3WD52v0gnLCTK/VLpXtKckgWuyScYK6cSPaw==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==" - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", - "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", - "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@types/jest": { - "version": "30.0.0", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-30.0.0.tgz", - "integrity": "sha512-XTYugzhuwqWjws0CVz8QpM36+T+Dz5mTEBKhNs/esGLnCIlGdRy+Dq78NRjd7ls7r8BC8ZRMOrKlkO1hU0JOwA==", - "dependencies": { - "expect": "^30.0.0", - "pretty-format": "^30.0.0" - } - }, - "node_modules/@types/jest/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@types/jest/node_modules/pretty-format": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", - "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", - "dependencies": { - "@jest/schemas": "30.0.5", - "ansi-styles": "^5.2.0", - "react-is": "^18.3.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@types/jest/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" - }, - "node_modules/@types/mime": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" - }, - "node_modules/@types/node": { - "version": "25.0.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.1.tgz", - "integrity": "sha512-czWPzKIAXucn9PtsttxmumiQ9N0ok9FrBwgRWrwmVLlp86BrMExzvXRLFYRJ+Ex3g6yqj+KuaxfX1JTgV2lpfg==", - "dependencies": { - "undici-types": "~7.16.0" - } - }, - "node_modules/@types/node-forge": { - "version": "1.3.14", - "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.14.tgz", - "integrity": "sha512-mhVF2BnD4BO+jtOp7z1CdzaK4mbuK0LLQYAvdOLqHTavxFNq4zA1EmYkpnFjP8HOUzedfQkRnp0E2ulSAYSzAw==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/parse-json": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", - "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" - }, - "node_modules/@types/prettier": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", - "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==" - }, - "node_modules/@types/prop-types": { - "version": "15.7.15", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", - "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", - "peer": true - }, - "node_modules/@types/q": { - "version": "1.5.8", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.8.tgz", - "integrity": "sha512-hroOstUScF6zhIi+5+x0dzqrHA1EJi+Irri6b1fxolMTqqHIV/Cg77EtnQcZqZCu8hR3mX2BzIxN4/GzI68Kfw==" - }, - "node_modules/@types/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==" - }, - "node_modules/@types/quill": { - "version": "1.3.10", - "resolved": "https://registry.npmjs.org/@types/quill/-/quill-1.3.10.tgz", - "integrity": "sha512-IhW3fPW+bkt9MLNlycw8u8fWb7oO7W5URC9MfZYHBlA24rex9rs23D5DETChu1zvgVdc5ka64ICjJOgQMr6Shw==", - "dependencies": { - "parchment": "^1.1.2" - } - }, - "node_modules/@types/range-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" - }, - "node_modules/@types/react": { - "version": "18.3.27", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.27.tgz", - "integrity": "sha512-cisd7gxkzjBKU2GgdYrTdtQx1SORymWyaAFhaxQPK9bYO9ot3Y5OikQRvY0VYQtvwjeQnizCINJAenh/V7MK2w==", - "peer": true, - "dependencies": { - "@types/prop-types": "*", - "csstype": "^3.2.2" - } - }, - "node_modules/@types/react-dom": { - "version": "18.3.7", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", - "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", - "peerDependencies": { - "@types/react": "^18.0.0" - } - }, - "node_modules/@types/resolve": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", - "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" - }, - "node_modules/@types/semver": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.1.tgz", - "integrity": "sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==" - }, - "node_modules/@types/send": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.1.tgz", - "integrity": "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/serve-index": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", - "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", - "dependencies": { - "@types/express": "*" - } - }, - "node_modules/@types/serve-static": { - "version": "1.15.10", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.10.tgz", - "integrity": "sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==", - "dependencies": { - "@types/http-errors": "*", - "@types/node": "*", - "@types/send": "<1" - } - }, - "node_modules/@types/serve-static/node_modules/@types/send": { - "version": "0.17.6", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.6.tgz", - "integrity": "sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==", - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "node_modules/@types/sockjs": { - "version": "0.3.36", - "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", - "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==" - }, - "node_modules/@types/testing-library__jest-dom": { - "version": "5.14.9", - "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.9.tgz", - "integrity": "sha512-FSYhIjFlfOpGSRyVoMBMuS3ws5ehFQODymf3vlI7U1K8c7PHwWwFY7VREfmsuzHSOnoKs/9/Y983ayOs7eRzqw==", - "dependencies": { - "@types/jest": "*" - } - }, - "node_modules/@types/trusted-types": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", - "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==" - }, - "node_modules/@types/ws": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", - "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/yargs": { - "version": "17.0.35", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz", - "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==" - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", - "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", - "dependencies": { - "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/type-utils": "5.62.0", - "@typescript-eslint/utils": "5.62.0", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@typescript-eslint/experimental-utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.62.0.tgz", - "integrity": "sha512-RTXpeB3eMkpoclG3ZHft6vG/Z30azNHuqY6wKPBHlVMZFuEvrtlEDe8gMqDb+SO+9hjC/pLekeSCryf9vMZlCw==", - "dependencies": { - "@typescript-eslint/utils": "5.62.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", - "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", - "dependencies": { - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", - "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", - "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", - "dependencies": { - "@typescript-eslint/typescript-estree": "5.62.0", - "@typescript-eslint/utils": "5.62.0", - "debug": "^4.3.4", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/types": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", - "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", - "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", - "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", - "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@ungap/structured-clone": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", - "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==" - }, - "node_modules/@webassemblyjs/ast": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", - "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", - "dependencies": { - "@webassemblyjs/helper-numbers": "1.13.2", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2" - } - }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", - "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==" - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", - "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==" - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", - "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==" - }, - "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", - "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", - "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.13.2", - "@webassemblyjs/helper-api-error": "1.13.2", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", - "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==" - }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", - "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/wasm-gen": "1.14.1" - } - }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", - "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", - "dependencies": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", - "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", - "dependencies": { - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", - "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==" - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", - "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/helper-wasm-section": "1.14.1", - "@webassemblyjs/wasm-gen": "1.14.1", - "@webassemblyjs/wasm-opt": "1.14.1", - "@webassemblyjs/wasm-parser": "1.14.1", - "@webassemblyjs/wast-printer": "1.14.1" - } - }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", - "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/ieee754": "1.13.2", - "@webassemblyjs/leb128": "1.13.2", - "@webassemblyjs/utf8": "1.13.2" - } - }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", - "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/wasm-gen": "1.14.1", - "@webassemblyjs/wasm-parser": "1.14.1" - } - }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", - "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-api-error": "1.13.2", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/ieee754": "1.13.2", - "@webassemblyjs/leb128": "1.13.2", - "@webassemblyjs/utf8": "1.13.2" - } - }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", - "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" - }, - "node_modules/abab": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", - "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", - "deprecated": "Use your platform's native atob() and btoa() methods instead" - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/accepts/node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", - "dependencies": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - } - }, - "node_modules/acorn-globals/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-import-phases": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", - "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", - "engines": { - "node": ">=10.13.0" - }, - "peerDependencies": { - "acorn": "^8.14.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/address": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", - "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/adjust-sourcemap-loader": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", - "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==", - "dependencies": { - "loader-utils": "^2.0.0", - "regex-parser": "^2.2.11" - }, - "engines": { - "node": ">=8.9" - } - }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-html": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.9.tgz", - "integrity": "sha512-ozbS3LuenHVxNRh/wdnN16QapUHzauqSomAl1jwwJRRsGwFwtj644lIhxfWu0Fy0acCij2+AEgHvjscq3dlVXg==", - "engines": [ - "node >= 0.8.0" - ], - "bin": { - "ansi-html": "bin/ansi-html" - } - }, - "node_modules/ansi-html-community": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", - "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", - "engines": [ - "node >= 0.8.0" - ], - "bin": { - "ansi-html": "bin/ansi-html" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/anymatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/aria-query": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", - "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", - "dependencies": { - "dequal": "^2.0.3" - } - }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", - "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", - "dependencies": { - "call-bound": "^1.0.3", - "is-array-buffer": "^3.0.5" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" - }, - "node_modules/array-includes": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", - "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "define-properties": "^1.2.1", - "es-abstract": "^1.24.0", - "es-object-atoms": "^1.1.1", - "get-intrinsic": "^1.3.0", - "is-string": "^1.1.1", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/array.prototype.findlast": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", - "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.findlastindex": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", - "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", - "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" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", - "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", - "dependencies": { - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.5", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", - "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", - "dependencies": { - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.5", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.reduce": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.8.tgz", - "integrity": "sha512-DwuEqgXFBwbmZSRqt3BpQigWNUoqw9Ml2dTWdF3B2zQlQX4OeUE0zyuzX0fX0IbTvjdkZbcBTU3idgpO78qkTw==", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.9", - "es-array-method-boxes-properly": "^1.0.0", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "is-string": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.tosorted": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", - "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.3", - "es-errors": "^1.3.0", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", - "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.5", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "is-array-buffer": "^3.0.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" - }, - "node_modules/ast-types-flow": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", - "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==" - }, - "node_modules/async": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", - "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==" - }, - "node_modules/async-function": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", - "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/autoprefixer": { - "version": "10.4.22", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.22.tgz", - "integrity": "sha512-ARe0v/t9gO28Bznv6GgqARmVqcWOV3mfgUPn9becPHMiD3o9BwlRgaeccZnwTpZ7Zwqrm+c1sUSsMxIzQzc8Xg==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "browserslist": "^4.27.0", - "caniuse-lite": "^1.0.30001754", - "fraction.js": "^5.3.4", - "normalize-range": "^0.1.2", - "picocolors": "^1.1.1", - "postcss-value-parser": "^4.2.0" - }, - "bin": { - "autoprefixer": "bin/autoprefixer" - }, - "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/axe-core": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.11.0.tgz", - "integrity": "sha512-ilYanEU8vxxBexpJd8cWM4ElSQq4QctCLKih0TSfjIfCQTeyH/6zVrmIJfLPrKTKJRbiG+cfnZbQIjAlJmF1jQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/axios": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz", - "integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==", - "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.4", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/axobject-query": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", - "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/babel-jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", - "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", - "dependencies": { - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^27.5.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.8.0" - } - }, - "node_modules/babel-jest/node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/babel-jest/node_modules/@types/yargs": { - "version": "16.0.11", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.11.tgz", - "integrity": "sha512-sbtvk8wDN+JvEdabmZExoW/HNr1cB7D/j4LT08rMiuikfA7m/JNJg7ATQcgzs34zHnoScDkY0ZRSl29Fkmk36g==", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/babel-jest/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/babel-loader": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.4.1.tgz", - "integrity": "sha512-nXzRChX+Z1GoE6yWavBQg6jDslyFF3SDjl2paADuoQtQW10JqShJt62R6eJQ5m/pjJFDT8xgKIWSP85OY8eXeA==", - "dependencies": { - "find-cache-dir": "^3.3.1", - "loader-utils": "^2.0.4", - "make-dir": "^3.1.0", - "schema-utils": "^2.6.5" - }, - "engines": { - "node": ">= 8.9" - }, - "peerDependencies": { - "@babel/core": "^7.0.0", - "webpack": ">=2" - } - }, - "node_modules/babel-loader/node_modules/schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", - "dependencies": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 8.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-jest-hoist": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", - "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", - "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", - "@types/babel__traverse": "^7.0.6" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/babel-plugin-macros": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", - "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", - "dependencies": { - "@babel/runtime": "^7.12.5", - "cosmiconfig": "^7.0.0", - "resolve": "^1.19.0" - }, - "engines": { - "node": ">=10", - "npm": ">=6" - } - }, - "node_modules/babel-plugin-named-asset-import": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.8.tgz", - "integrity": "sha512-WXiAc++qo7XcJ1ZnTYGtLxmBCVbddAml3CEXgWaBzNzLNoxtQ8AiGEFDMOhot9XjTCQbvP5E77Fj9Gk924f00Q==", - "peerDependencies": { - "@babel/core": "^7.1.0" - } - }, - "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz", - "integrity": "sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==", - "dependencies": { - "@babel/compat-data": "^7.27.7", - "@babel/helper-define-polyfill-provider": "^0.6.5", - "semver": "^6.3.1" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz", - "integrity": "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.5", - "core-js-compat": "^3.43.0" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz", - "integrity": "sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.5" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-transform-react-remove-prop-types": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz", - "integrity": "sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==" - }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz", - "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==", - "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-import-attributes": "^7.24.7", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5" - }, - "peerDependencies": { - "@babel/core": "^7.0.0 || ^8.0.0-0" - } - }, - "node_modules/babel-preset-jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", - "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", - "dependencies": { - "babel-plugin-jest-hoist": "^27.5.1", - "babel-preset-current-node-syntax": "^1.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/babel-preset-react-app": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/babel-preset-react-app/-/babel-preset-react-app-10.1.0.tgz", - "integrity": "sha512-f9B1xMdnkCIqe+2dHrJsoQFRz7reChaAHE/65SdaykPklQqhme2WaC08oD3is77x9ff98/9EazAKFDZv5rFEQg==", - "dependencies": { - "@babel/core": "^7.16.0", - "@babel/plugin-proposal-class-properties": "^7.16.0", - "@babel/plugin-proposal-decorators": "^7.16.4", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.0", - "@babel/plugin-proposal-numeric-separator": "^7.16.0", - "@babel/plugin-proposal-optional-chaining": "^7.16.0", - "@babel/plugin-proposal-private-methods": "^7.16.0", - "@babel/plugin-proposal-private-property-in-object": "^7.16.7", - "@babel/plugin-transform-flow-strip-types": "^7.16.0", - "@babel/plugin-transform-react-display-name": "^7.16.0", - "@babel/plugin-transform-runtime": "^7.16.4", - "@babel/preset-env": "^7.16.4", - "@babel/preset-react": "^7.16.0", - "@babel/preset-typescript": "^7.16.0", - "@babel/runtime": "^7.16.3", - "babel-plugin-macros": "^3.1.0", - "babel-plugin-transform-react-remove-prop-types": "^0.4.24" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "node_modules/baseline-browser-mapping": { - "version": "2.9.7", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.7.tgz", - "integrity": "sha512-k9xFKplee6KIio3IDbwj+uaCLpqzOwakOgmqzPezM0sFJlFKcg30vk2wOiAJtkTSfx0SSQDSe8q+mWA/fSH5Zg==", - "bin": { - "baseline-browser-mapping": "dist/cli.js" - } - }, - "node_modules/batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==" - }, - "node_modules/bfj": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/bfj/-/bfj-7.1.0.tgz", - "integrity": "sha512-I6MMLkn+anzNdCUp9hMRyui1HaNEUCco50lxbvNS4+EyXg8lN3nJ48PjPWtbH8UVS9CuMoaKE9U2V3l29DaRQw==", - "dependencies": { - "bluebird": "^3.7.2", - "check-types": "^11.2.3", - "hoopy": "^0.1.4", - "jsonpath": "^1.1.1", - "tryer": "^1.0.1" - }, - "engines": { - "node": ">= 8.0.0" - } - }, - "node_modules/big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "engines": { - "node": "*" - } - }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, - "node_modules/body-parser": { - "version": "1.20.4", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.4.tgz", - "integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==", - "dependencies": { - "bytes": "~3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "~1.2.0", - "http-errors": "~2.0.1", - "iconv-lite": "~0.4.24", - "on-finished": "~2.4.1", - "qs": "~6.14.0", - "raw-body": "~2.5.3", - "type-is": "~1.6.18", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/bonjour-service": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.3.0.tgz", - "integrity": "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "multicast-dns": "^7.2.5" - } - }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" - }, - "node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==" - }, - "node_modules/browserslist": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", - "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "baseline-browser-mapping": "^2.9.0", - "caniuse-lite": "^1.0.30001759", - "electron-to-chromium": "^1.5.263", - "node-releases": "^2.0.27", - "update-browserslist-db": "^1.2.0" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dependencies": { - "node-int64": "^0.4.0" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" - }, - "node_modules/builtin-modules": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", - "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/call-bind": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", - "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", - "dependencies": { - "call-bind-apply-helpers": "^1.0.0", - "es-define-property": "^1.0.0", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/call-bound": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/camel-case": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", - "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", - "dependencies": { - "pascal-case": "^3.1.2", - "tslib": "^2.0.3" - } - }, - "node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/camelcase-css": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", - "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/caniuse-api": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", - "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", - "dependencies": { - "browserslist": "^4.0.0", - "caniuse-lite": "^1.0.0", - "lodash.memoize": "^4.1.2", - "lodash.uniq": "^4.5.0" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001760", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001760.tgz", - "integrity": "sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ] - }, - "node_modules/case-sensitive-paths-webpack-plugin": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz", - "integrity": "sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==", - "engines": { - "node": ">=4" - } - }, - "node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "engines": { - "node": ">=10" - } - }, - "node_modules/check-types": { - "version": "11.2.3", - "resolved": "https://registry.npmjs.org/check-types/-/check-types-11.2.3.tgz", - "integrity": "sha512-+67P1GkJRaxQD6PKK0Et9DhwQB+vGg3PM5+aavopCpZT1lj9jeqfvpgTLAWErNj8qApkkmXlu/Ug74kmhagkXg==" - }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/chrome-trace-event": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", - "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", - "engines": { - "node": ">=6.0" - } - }, - "node_modules/ci-info": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", - "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, - "node_modules/cjs-module-lexer": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", - "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==" - }, - "node_modules/clean-css": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", - "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==", - "dependencies": { - "source-map": "~0.6.0" - }, - "engines": { - "node": ">= 10.0" - } - }, - "node_modules/clean-css/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" - } - }, - "node_modules/coa": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", - "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", - "dependencies": { - "@types/q": "^1.5.1", - "chalk": "^2.4.1", - "q": "^1.1.2" - }, - "engines": { - "node": ">= 4.0" - } - }, - "node_modules/coa/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/coa/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/coa/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/coa/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "node_modules/coa/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/coa/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "engines": { - "node": ">=4" - } - }, - "node_modules/coa/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/collect-v8-coverage": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz", - "integrity": "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==" - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/colord": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", - "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==" - }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==" - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "engines": { - "node": ">= 12" - } - }, - "node_modules/common-tags": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", - "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" - }, - "node_modules/compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "dependencies": { - "mime-db": ">= 1.43.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/compression": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz", - "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==", - "dependencies": { - "bytes": "3.1.2", - "compressible": "~2.0.18", - "debug": "2.6.9", - "negotiator": "~0.6.4", - "on-headers": "~1.1.0", - "safe-buffer": "5.2.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/compression/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/compression/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" - }, - "node_modules/confusing-browser-globals": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", - "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==" - }, - "node_modules/connect-history-api-fallback": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", - "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" - }, - "node_modules/cookie": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", - "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz", - "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==" - }, - "node_modules/core-js": { - "version": "3.47.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.47.0.tgz", - "integrity": "sha512-c3Q2VVkGAUyupsjRnaNX6u8Dq2vAdzm9iuPj5FW0fRxzlxgq9Q39MDq10IvmQSpLgHQNyQzQmOo6bgGHmH3NNg==", - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-js-compat": { - "version": "3.47.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.47.0.tgz", - "integrity": "sha512-IGfuznZ/n7Kp9+nypamBhvwdwLsW6KC8IOaURw2doAK5e98AG3acVLdh0woOnEqCfUtS+Vu882JE4k/DAm3ItQ==", - "dependencies": { - "browserslist": "^4.28.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-js-pure": { - "version": "3.47.0", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.47.0.tgz", - "integrity": "sha512-BcxeDbzUrRnXGYIVAGFtcGQVNpFcUhVjr6W7F8XktvQW2iJP9e66GP6xdKotCRFlrxBvNIBrhwKteRXqMV86Nw==", - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" - }, - "node_modules/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/crypto-random-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/css-blank-pseudo": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-3.0.3.tgz", - "integrity": "sha512-VS90XWtsHGqoM0t4KpH053c4ehxZ2E6HtGI7x68YFV0pTo/QmkV/YFA+NnlvK8guxZVNWGQhVNJGC39Q8XF4OQ==", - "dependencies": { - "postcss-selector-parser": "^6.0.9" - }, - "bin": { - "css-blank-pseudo": "dist/cli.cjs" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/css-declaration-sorter": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz", - "integrity": "sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==", - "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.0.9" - } - }, - "node_modules/css-has-pseudo": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-3.0.4.tgz", - "integrity": "sha512-Vse0xpR1K9MNlp2j5w1pgWIJtm1a8qS0JwS9goFYcImjlHEmywP9VUF05aGBXzGpDJF86QXk4L0ypBmwPhGArw==", - "dependencies": { - "postcss-selector-parser": "^6.0.9" - }, - "bin": { - "css-has-pseudo": "dist/cli.cjs" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/css-loader": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.11.0.tgz", - "integrity": "sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==", - "dependencies": { - "icss-utils": "^5.1.0", - "postcss": "^8.4.33", - "postcss-modules-extract-imports": "^3.1.0", - "postcss-modules-local-by-default": "^4.0.5", - "postcss-modules-scope": "^3.2.0", - "postcss-modules-values": "^4.0.0", - "postcss-value-parser": "^4.2.0", - "semver": "^7.5.4" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "@rspack/core": "0.x || 1.x", - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "@rspack/core": { - "optional": true - }, - "webpack": { - "optional": true - } - } - }, - "node_modules/css-loader/node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/css-minimizer-webpack-plugin": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.4.1.tgz", - "integrity": "sha512-1u6D71zeIfgngN2XNRJefc/hY7Ybsxd74Jm4qngIXyUEk7fss3VUzuHxLAq/R8NAba4QU9OUSaMZlbpRc7bM4Q==", - "dependencies": { - "cssnano": "^5.0.6", - "jest-worker": "^27.0.2", - "postcss": "^8.3.5", - "schema-utils": "^4.0.0", - "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "@parcel/css": { - "optional": true - }, - "clean-css": { - "optional": true - }, - "csso": { - "optional": true - }, - "esbuild": { - "optional": true - } - } - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/css-prefers-color-scheme": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz", - "integrity": "sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA==", - "bin": { - "css-prefers-color-scheme": "dist/cli.cjs" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/css-select": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css-select-base-adapter": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", - "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==" - }, - "node_modules/css-tree": { - "version": "1.0.0-alpha.37", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", - "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", - "dependencies": { - "mdn-data": "2.0.4", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/css-tree/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/css-what": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", - "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css.escape": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", - "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==" - }, - "node_modules/cssdb": { - "version": "7.11.2", - "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.11.2.tgz", - "integrity": "sha512-lhQ32TFkc1X4eTefGfYPvgovRSzIMofHkigfH8nWtyRL4XJLsRhJFreRvEgKzept7x1rjBuy3J/MurXLaFxW/A==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - } - ] - }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cssnano": { - "version": "5.1.15", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.15.tgz", - "integrity": "sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==", - "dependencies": { - "cssnano-preset-default": "^5.2.14", - "lilconfig": "^2.0.3", - "yaml": "^1.10.2" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/cssnano" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/cssnano-preset-default": { - "version": "5.2.14", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz", - "integrity": "sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==", - "dependencies": { - "css-declaration-sorter": "^6.3.1", - "cssnano-utils": "^3.1.0", - "postcss-calc": "^8.2.3", - "postcss-colormin": "^5.3.1", - "postcss-convert-values": "^5.1.3", - "postcss-discard-comments": "^5.1.2", - "postcss-discard-duplicates": "^5.1.0", - "postcss-discard-empty": "^5.1.1", - "postcss-discard-overridden": "^5.1.0", - "postcss-merge-longhand": "^5.1.7", - "postcss-merge-rules": "^5.1.4", - "postcss-minify-font-values": "^5.1.0", - "postcss-minify-gradients": "^5.1.1", - "postcss-minify-params": "^5.1.4", - "postcss-minify-selectors": "^5.2.1", - "postcss-normalize-charset": "^5.1.0", - "postcss-normalize-display-values": "^5.1.0", - "postcss-normalize-positions": "^5.1.1", - "postcss-normalize-repeat-style": "^5.1.1", - "postcss-normalize-string": "^5.1.0", - "postcss-normalize-timing-functions": "^5.1.0", - "postcss-normalize-unicode": "^5.1.1", - "postcss-normalize-url": "^5.1.0", - "postcss-normalize-whitespace": "^5.1.1", - "postcss-ordered-values": "^5.1.3", - "postcss-reduce-initial": "^5.1.2", - "postcss-reduce-transforms": "^5.1.0", - "postcss-svgo": "^5.1.0", - "postcss-unique-selectors": "^5.1.1" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/cssnano-utils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", - "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/csso": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", - "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", - "dependencies": { - "css-tree": "^1.1.2" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/csso/node_modules/css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", - "dependencies": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/csso/node_modules/mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" - }, - "node_modules/csso/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==" - }, - "node_modules/cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", - "dependencies": { - "cssom": "~0.3.6" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cssstyle/node_modules/cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" - }, - "node_modules/csstype": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", - "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==" - }, - "node_modules/damerau-levenshtein": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", - "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==" - }, - "node_modules/data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", - "dependencies": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/data-view-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", - "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", - "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/data-view-byte-length": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", - "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", - "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/inspect-js" - } - }, - "node_modules/data-view-byte-offset": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", - "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decimal.js": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", - "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==" - }, - "node_modules/dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==" - }, - "node_modules/deep-equal": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.2.tgz", - "integrity": "sha512-5tdhKF6DbU7iIzrIOa1AOUt39ZRm13cmL1cGEh//aqR8x9+tNfbywRf0n5FD/18OKMdo7DNEtrX2t22ZAkI+eg==", - "dependencies": { - "is-arguments": "^1.1.1", - "is-date-object": "^1.0.5", - "is-regex": "^1.1.4", - "object-is": "^1.1.5", - "object-keys": "^1.1.1", - "regexp.prototype.flags": "^1.5.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" - }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/default-gateway": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", - "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", - "dependencies": { - "execa": "^5.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", - "engines": { - "node": ">=8" - } - }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" - }, - "node_modules/detect-port-alt": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz", - "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==", - "dependencies": { - "address": "^1.0.1", - "debug": "^2.6.0" - }, - "bin": { - "detect": "bin/detect-port", - "detect-port": "bin/detect-port" - }, - "engines": { - "node": ">= 4.2.1" - } - }, - "node_modules/detect-port-alt/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/detect-port-alt/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/didyoumean": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", - "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" - }, - "node_modules/diff-sequences": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", - "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/dlv": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" - }, - "node_modules/dns-packet": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", - "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", - "dependencies": { - "@leichtgewicht/ip-codec": "^2.0.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/dom-accessibility-api": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", - "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==" - }, - "node_modules/dom-converter": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", - "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", - "dependencies": { - "utila": "~0.4" - } - }, - "node_modules/dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ] - }, - "node_modules/domexception": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", - "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", - "deprecated": "Use your platform's native DOMException instead", - "dependencies": { - "webidl-conversions": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/domexception/node_modules/webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "dependencies": { - "domelementtype": "^2.2.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/dot-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/dotenv": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", - "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", - "engines": { - "node": ">=10" - } - }, - "node_modules/dotenv-expand": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", - "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==" - }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" - }, - "node_modules/ejs": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", - "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", - "dependencies": { - "jake": "^10.8.5" - }, - "bin": { - "ejs": "bin/cli.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.5.267", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz", - "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==" - }, - "node_modules/emittery": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", - "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" - } - }, - "node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" - }, - "node_modules/emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/enhanced-resolve": { - "version": "5.18.4", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.4.tgz", - "integrity": "sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==", - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/error-ex": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", - "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/error-stack-parser": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", - "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", - "dependencies": { - "stackframe": "^1.3.4" - } - }, - "node_modules/es-abstract": { - "version": "1.24.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", - "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==", - "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-negative-zero": "^2.0.3", - "is-regex": "^1.2.1", - "is-set": "^2.0.3", - "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", - "stop-iteration-iterator": "^1.1.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" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-array-method-boxes-properly": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", - "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==" - }, - "node_modules/es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-get-iterator": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", - "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "has-symbols": "^1.0.3", - "is-arguments": "^1.1.1", - "is-map": "^2.0.2", - "is-set": "^2.0.2", - "is-string": "^1.0.7", - "isarray": "^2.0.5", - "stop-iteration-iterator": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-iterator-helpers": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz", - "integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.6", - "es-errors": "^1.3.0", - "es-set-tostringtag": "^2.0.3", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.6", - "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.4", - "safe-array-concat": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-module-lexer": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", - "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==" - }, - "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", - "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "dependencies": { - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-shim-unscopables": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", - "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-to-primitive": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", - "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", - "dependencies": { - "is-callable": "^1.2.7", - "is-date-object": "^1.0.5", - "is-symbol": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/escodegen": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", - "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", - "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=6.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, - "node_modules/escodegen/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", - "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", - "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.1", - "@humanwhocodes/config-array": "^0.13.0", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-react-app": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-7.0.1.tgz", - "integrity": "sha512-K6rNzvkIeHaTd8m/QEh1Zko0KI7BACWkkneSs6s9cKZC/J27X3eZR6Upt1jkmZ/4FK+XUOPPxMEN7+lbUXfSlA==", - "dependencies": { - "@babel/core": "^7.16.0", - "@babel/eslint-parser": "^7.16.3", - "@rushstack/eslint-patch": "^1.1.0", - "@typescript-eslint/eslint-plugin": "^5.5.0", - "@typescript-eslint/parser": "^5.5.0", - "babel-preset-react-app": "^10.0.1", - "confusing-browser-globals": "^1.0.11", - "eslint-plugin-flowtype": "^8.0.3", - "eslint-plugin-import": "^2.25.3", - "eslint-plugin-jest": "^25.3.0", - "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-react": "^7.27.1", - "eslint-plugin-react-hooks": "^4.3.0", - "eslint-plugin-testing-library": "^5.0.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "eslint": "^8.0.0" - } - }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", - "dependencies": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-module-utils": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz", - "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==", - "dependencies": { - "debug": "^3.2.7" - }, - "engines": { - "node": ">=4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } - } - }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-flowtype": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-8.0.3.tgz", - "integrity": "sha512-dX8l6qUL6O+fYPtpNRideCFSpmWOUVx5QcaGLVqe/vlDiBSe4vYljDWDETwnyFzpl7By/WVIu6rcrniCgH9BqQ==", - "dependencies": { - "lodash": "^4.17.21", - "string-natural-compare": "^3.0.1" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "@babel/plugin-syntax-flow": "^7.14.5", - "@babel/plugin-transform-react-jsx": "^7.14.9", - "eslint": "^8.1.0" - } - }, - "node_modules/eslint-plugin-import": { - "version": "2.32.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", - "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", - "dependencies": { - "@rtsao/scc": "^1.1.0", - "array-includes": "^3.1.9", - "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-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.12.1", - "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" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" - } - }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-jest": { - "version": "25.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-25.7.0.tgz", - "integrity": "sha512-PWLUEXeeF7C9QGKqvdSbzLOiLTx+bno7/HC9eefePfEb257QFHg7ye3dh80AZVkaa/RQsBB1Q/ORQvg2X7F0NQ==", - "dependencies": { - "@typescript-eslint/experimental-utils": "^5.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - }, - "peerDependencies": { - "@typescript-eslint/eslint-plugin": "^4.0.0 || ^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "@typescript-eslint/eslint-plugin": { - "optional": true - }, - "jest": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-jsx-a11y": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz", - "integrity": "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==", - "dependencies": { - "aria-query": "^5.3.2", - "array-includes": "^3.1.8", - "array.prototype.flatmap": "^1.3.2", - "ast-types-flow": "^0.0.8", - "axe-core": "^4.10.0", - "axobject-query": "^4.1.0", - "damerau-levenshtein": "^1.0.8", - "emoji-regex": "^9.2.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.0.3", - "string.prototype.includes": "^2.0.1" - }, - "engines": { - "node": ">=4.0" - }, - "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" - } - }, - "node_modules/eslint-plugin-jsx-a11y/node_modules/aria-query": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", - "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/eslint-plugin-react": { - "version": "7.37.5", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz", - "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==", - "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", - "estraverse": "^5.3.0", - "hasown": "^2.0.2", - "jsx-ast-utils": "^2.4.1 || ^3.0.0", - "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" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" - } - }, - "node_modules/eslint-plugin-react-hooks": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", - "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" - } - }, - "node_modules/eslint-plugin-react/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-react/node_modules/resolve": { - "version": "2.0.0-next.5", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", - "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/eslint-plugin-testing-library": { - "version": "5.11.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.11.1.tgz", - "integrity": "sha512-5eX9e1Kc2PqVRed3taaLnAAqPZGEX75C+M/rXzUAI3wIg/ZxzUm1OVAwfe/O+vE+6YXOLetSe9g5GKD2ecXipw==", - "dependencies": { - "@typescript-eslint/utils": "^5.58.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0", - "npm": ">=6" - }, - "peerDependencies": { - "eslint": "^7.5.0 || ^8.0.0" - } - }, - "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-webpack-plugin": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-3.2.0.tgz", - "integrity": "sha512-avrKcGncpPbPSUHX6B3stNGzkKFto3eL+DKM4+VyMrVnhPc3vRczVlCq3uhuFOdRvDHTVXuzwk1ZKUrqDQHQ9w==", - "dependencies": { - "@types/eslint": "^7.29.0 || ^8.4.1", - "jest-worker": "^28.0.2", - "micromatch": "^4.0.5", - "normalize-path": "^3.0.0", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0", - "webpack": "^5.0.0" - } - }, - "node_modules/eslint-webpack-plugin/node_modules/jest-worker": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz", - "integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==", - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/eslint-webpack-plugin/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/eslint/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "node_modules/eslint/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/eslint/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/js-yaml": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/eslint/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estree-walker": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", - "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==" - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/eventemitter3": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz", - "integrity": "sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg==" - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/exenv": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz", - "integrity": "sha512-Z+ktTxTwv9ILfgKCk32OX3n/doe+OcLTRtqK9pcL+JsP3J1/VW8Uvl4ZjLlKqeW4rzK4oesDOGMEMRIZqtP4Iw==" - }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/expect": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-30.2.0.tgz", - "integrity": "sha512-u/feCi0GPsI+988gU2FLcsHyAHTU0MX1Wg68NhAnN7z/+C5wqG+CY8J53N9ioe8RXgaoz0nBR/TYMf3AycUuPw==", - "dependencies": { - "@jest/expect-utils": "30.2.0", - "@jest/get-type": "30.1.0", - "jest-matcher-utils": "30.2.0", - "jest-message-util": "30.2.0", - "jest-mock": "30.2.0", - "jest-util": "30.2.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/express": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz", - "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "~1.20.3", - "content-disposition": "~0.5.4", - "content-type": "~1.0.4", - "cookie": "~0.7.1", - "cookie-signature": "~1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.3.1", - "fresh": "~0.5.2", - "http-errors": "~2.0.0", - "merge-descriptors": "1.0.3", - "methods": "~1.1.2", - "on-finished": "~2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "~0.1.12", - "proxy-addr": "~2.0.7", - "qs": "~6.14.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "~0.19.0", - "serve-static": "~1.16.2", - "setprototypeof": "1.2.0", - "statuses": "~2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "node_modules/fast-diff": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.1.2.tgz", - "integrity": "sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig==" - }, - "node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" - }, - "node_modules/fast-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", - "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ] - }, - "node_modules/fastq": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", - "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/faye-websocket": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", - "dependencies": { - "websocket-driver": ">=0.5.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/fb-watchman": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", - "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", - "dependencies": { - "bser": "2.1.1" - } - }, - "node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/file-loader": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", - "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", - "dependencies": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/file-loader/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/filelist": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", - "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", - "dependencies": { - "minimatch": "^5.0.1" - } - }, - "node_modules/filelist/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/filelist/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/filesize": { - "version": "8.0.7", - "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", - "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/finalhandler": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz", - "integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "on-finished": "~2.4.1", - "parseurl": "~1.3.3", - "statuses": "~2.0.2", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/find-cache-dir": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/avajs/find-cache-dir?sponsor=1" - } - }, - "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==" - }, - "node_modules/follow-redirects": { - "version": "1.15.11", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", - "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/for-each": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", - "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", - "dependencies": { - "is-callable": "^1.2.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/fork-ts-checker-webpack-plugin": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz", - "integrity": "sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ==", - "dependencies": { - "@babel/code-frame": "^7.8.3", - "@types/json-schema": "^7.0.5", - "chalk": "^4.1.0", - "chokidar": "^3.4.2", - "cosmiconfig": "^6.0.0", - "deepmerge": "^4.2.2", - "fs-extra": "^9.0.0", - "glob": "^7.1.6", - "memfs": "^3.1.2", - "minimatch": "^3.0.4", - "schema-utils": "2.7.0", - "semver": "^7.3.2", - "tapable": "^1.0.0" - }, - "engines": { - "node": ">=10", - "yarn": ">=1.0.0" - }, - "peerDependencies": { - "eslint": ">= 6", - "typescript": ">= 2.7", - "vue-template-compiler": "*", - "webpack": ">= 4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - }, - "vue-template-compiler": { - "optional": true - } - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/cosmiconfig": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", - "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.7.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/schema-utils": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", - "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", - "dependencies": { - "@types/json-schema": "^7.0.4", - "ajv": "^6.12.2", - "ajv-keywords": "^3.4.1" - }, - "engines": { - "node": ">= 8.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/form-data": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", - "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.2", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fraction.js": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz", - "integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==", - "engines": { - "node": "*" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/rawify" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/fs-monkey": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.1.0.tgz", - "integrity": "sha512-QMUezzXWII9EV5aTFXW1UBVUO77wYPpjqIF8/AviUCThNeSYZykpoTixUeaNNBwmCev0AMDWMAni+f8Hxb1IFw==" - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/function.prototype.name": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", - "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "functions-have-names": "^1.2.3", - "hasown": "^2.0.2", - "is-callable": "^1.2.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/generator-function": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", - "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "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" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-own-enumerable-property-symbols": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", - "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" - }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/get-symbol-description": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", - "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", - "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" - }, - "node_modules/global-modules": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", - "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", - "dependencies": { - "global-prefix": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/global-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", - "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", - "dependencies": { - "ini": "^1.3.5", - "kind-of": "^6.0.2", - "which": "^1.3.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/global-prefix/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globalthis": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "dependencies": { - "define-properties": "^1.2.1", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/goober": { - "version": "2.1.18", - "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.18.tgz", - "integrity": "sha512-2vFqsaDVIT9Gz7N6kAL++pLpp41l3PfDuusHcjnGLfR6+huZkl6ziX+zgVC3ZxpqWhzH6pyDdGrCeDhMIvwaxw==", - "peerDependencies": { - "csstype": "^3.0.10" - } - }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" - }, - "node_modules/gzip-size": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", - "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", - "dependencies": { - "duplexer": "^0.1.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/handle-thing": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", - "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==" - }, - "node_modules/harmony-reflect": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.2.tgz", - "integrity": "sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==" - }, - "node_modules/has-bigints": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", - "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", - "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", - "dependencies": { - "dunder-proto": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "bin": { - "he": "bin/he" - } - }, - "node_modules/hoopy": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", - "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==", - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", - "dependencies": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" - } - }, - "node_modules/hpack.js/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" - }, - "node_modules/hpack.js/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/hpack.js/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/hpack.js/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", - "dependencies": { - "whatwg-encoding": "^1.0.5" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/html-entities": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.6.0.tgz", - "integrity": "sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/mdevils" - }, - { - "type": "patreon", - "url": "https://patreon.com/mdevils" - } - ] - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" - }, - "node_modules/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", - "dependencies": { - "camel-case": "^4.1.2", - "clean-css": "^5.2.2", - "commander": "^8.3.0", - "he": "^1.2.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.10.0" - }, - "bin": { - "html-minifier-terser": "cli.js" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/html-webpack-plugin": { - "version": "5.6.5", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.5.tgz", - "integrity": "sha512-4xynFbKNNk+WlzXeQQ+6YYsH2g7mpfPszQZUi3ovKlj+pDmngQ7vRXjrrmGROabmKwyQkcgcX5hqfOwHbFmK5g==", - "dependencies": { - "@types/html-minifier-terser": "^6.0.0", - "html-minifier-terser": "^6.0.2", - "lodash": "^4.17.21", - "pretty-error": "^4.0.0", - "tapable": "^2.0.0" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/html-webpack-plugin" - }, - "peerDependencies": { - "@rspack/core": "0.x || 1.x", - "webpack": "^5.20.0" - }, - "peerDependenciesMeta": { - "@rspack/core": { - "optional": true - }, - "webpack": { - "optional": true - } - } - }, - "node_modules/htmlparser2": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", - "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.0.0", - "domutils": "^2.5.2", - "entities": "^2.0.0" - } - }, - "node_modules/http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==" - }, - "node_modules/http-errors": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", - "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", - "dependencies": { - "depd": "~2.0.0", - "inherits": "~2.0.4", - "setprototypeof": "~1.2.0", - "statuses": "~2.0.2", - "toidentifier": "~1.0.1" - }, - "engines": { - "node": ">= 0.8" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/http-parser-js": { - "version": "0.5.10", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz", - "integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==" - }, - "node_modules/http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "dependencies": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "dependencies": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/http-proxy-middleware": { - "version": "2.0.9", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.9.tgz", - "integrity": "sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q==", - "dependencies": { - "@types/http-proxy": "^1.17.8", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.2" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "@types/express": "^4.17.13" - }, - "peerDependenciesMeta": { - "@types/express": { - "optional": true - } - } - }, - "node_modules/http-proxy/node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" - }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "engines": { - "node": ">=10.17.0" - } - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/icss-utils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", - "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/idb": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", - "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==" - }, - "node_modules/identity-obj-proxy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz", - "integrity": "sha512-00n6YnVHKrinT9t0d9+5yZC6UBNJANpYEQvL2LlX6Ab9lnmxzIRcEmTPuyGScvl1+jKuCICX1Z0Ab1pPKKdikA==", - "dependencies": { - "harmony-reflect": "^1.4.6" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/immer": { - "version": "9.0.21", - "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", - "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/immer" - } - }, - "node_modules/import-fresh": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-fresh/node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "engines": { - "node": ">=4" - } - }, - "node_modules/import-local": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", - "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" - }, - "node_modules/internal-slot": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", - "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", - "dependencies": { - "es-errors": "^1.3.0", - "hasown": "^2.0.2", - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/ipaddr.js": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.3.0.tgz", - "integrity": "sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/is-arguments": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz", - "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==", - "dependencies": { - "call-bound": "^1.0.2", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-array-buffer": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", - "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "get-intrinsic": "^1.2.6" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" - }, - "node_modules/is-async-function": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", - "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", - "dependencies": { - "async-function": "^1.0.0", - "call-bound": "^1.0.3", - "get-proto": "^1.0.1", - "has-tostringtag": "^1.0.2", - "safe-regex-test": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-bigint": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", - "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", - "dependencies": { - "has-bigints": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-boolean-object": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", - "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", - "dependencies": { - "call-bound": "^1.0.3", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-core-module": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", - "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-data-view": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", - "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", - "dependencies": { - "call-bound": "^1.0.2", - "get-intrinsic": "^1.2.6", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", - "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", - "dependencies": { - "call-bound": "^1.0.2", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-finalizationregistry": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", - "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", - "dependencies": { - "call-bound": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/is-generator-function": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", - "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", - "dependencies": { - "call-bound": "^1.0.4", - "generator-function": "^2.0.0", - "get-proto": "^1.0.1", - "has-tostringtag": "^1.0.2", - "safe-regex-test": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", - "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==" - }, - "node_modules/is-negative-zero": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-number-object": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", - "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", - "dependencies": { - "call-bound": "^1.0.3", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-obj": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", - "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" - }, - "node_modules/is-regex": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", - "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", - "dependencies": { - "call-bound": "^1.0.2", - "gopd": "^1.2.0", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-root": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", - "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/is-set": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", - "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", - "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", - "dependencies": { - "call-bound": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-string": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", - "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", - "dependencies": { - "call-bound": "^1.0.3", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", - "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", - "dependencies": { - "call-bound": "^1.0.2", - "has-symbols": "^1.1.0", - "safe-regex-test": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", - "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", - "dependencies": { - "which-typed-array": "^1.1.16" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" - }, - "node_modules/is-weakmap": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", - "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakref": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", - "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", - "dependencies": { - "call-bound": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakset": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", - "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", - "dependencies": { - "call-bound": "^1.0.3", - "get-intrinsic": "^1.2.6" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-report/node_modules/make-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/istanbul-lib-report/node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-source-maps/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/istanbul-reports": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", - "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/iterator.prototype": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", - "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", - "dependencies": { - "define-data-property": "^1.1.4", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.6", - "get-proto": "^1.0.0", - "has-symbols": "^1.1.0", - "set-function-name": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/jake": { - "version": "10.9.4", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz", - "integrity": "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==", - "dependencies": { - "async": "^3.2.6", - "filelist": "^1.0.4", - "picocolors": "^1.1.1" - }, - "bin": { - "jake": "bin/cli.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jalaali-js": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/jalaali-js/-/jalaali-js-1.2.8.tgz", - "integrity": "sha512-Jl/EwY84JwjW2wsWqeU4pNd22VNQ7EkjI36bDuLw31wH98WQW4fPjD0+mG7cdCK+Y8D6s9R3zLiQ3LaKu6bD8A==" - }, - "node_modules/jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", - "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", - "dependencies": { - "@jest/core": "^27.5.1", - "import-local": "^3.0.2", - "jest-cli": "^27.5.1" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-changed-files": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz", - "integrity": "sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==", - "dependencies": { - "@jest/types": "^27.5.1", - "execa": "^5.0.0", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-changed-files/node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-changed-files/node_modules/@types/yargs": { - "version": "16.0.11", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.11.tgz", - "integrity": "sha512-sbtvk8wDN+JvEdabmZExoW/HNr1cB7D/j4LT08rMiuikfA7m/JNJg7ATQcgzs34zHnoScDkY0ZRSl29Fkmk36g==", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/jest-changed-files/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-circus": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.5.1.tgz", - "integrity": "sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==", - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "expect": "^27.5.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-circus/node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-circus/node_modules/@types/yargs": { - "version": "16.0.11", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.11.tgz", - "integrity": "sha512-sbtvk8wDN+JvEdabmZExoW/HNr1cB7D/j4LT08rMiuikfA7m/JNJg7ATQcgzs34zHnoScDkY0ZRSl29Fkmk36g==", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/jest-circus/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-circus/node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-circus/node_modules/expect": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", - "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", - "dependencies": { - "@jest/types": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-circus/node_modules/jest-diff": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", - "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-circus/node_modules/jest-matcher-utils": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", - "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-circus/node_modules/jest-message-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", - "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.5.1", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-circus/node_modules/jest-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", - "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-circus/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/jest-cli": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.5.1.tgz", - "integrity": "sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==", - "dependencies": { - "@jest/core": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "import-local": "^3.0.2", - "jest-config": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "prompts": "^2.0.1", - "yargs": "^16.2.0" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-cli/node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-cli/node_modules/@types/yargs": { - "version": "16.0.11", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.11.tgz", - "integrity": "sha512-sbtvk8wDN+JvEdabmZExoW/HNr1cB7D/j4LT08rMiuikfA7m/JNJg7ATQcgzs34zHnoScDkY0ZRSl29Fkmk36g==", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/jest-cli/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-cli/node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-cli/node_modules/jest-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", - "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-cli/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/jest-config": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", - "integrity": "sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==", - "dependencies": { - "@babel/core": "^7.8.0", - "@jest/test-sequencer": "^27.5.1", - "@jest/types": "^27.5.1", - "babel-jest": "^27.5.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.9", - "jest-circus": "^27.5.1", - "jest-environment-jsdom": "^27.5.1", - "jest-environment-node": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-jasmine2": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-runner": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "ts-node": { - "optional": true - } - } - }, - "node_modules/jest-config/node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-config/node_modules/@types/yargs": { - "version": "16.0.11", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.11.tgz", - "integrity": "sha512-sbtvk8wDN+JvEdabmZExoW/HNr1cB7D/j4LT08rMiuikfA7m/JNJg7ATQcgzs34zHnoScDkY0ZRSl29Fkmk36g==", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/jest-config/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-config/node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-config/node_modules/jest-regex-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", - "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-config/node_modules/jest-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", - "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-config/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/jest-diff": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.2.0.tgz", - "integrity": "sha512-dQHFo3Pt4/NLlG5z4PxZ/3yZTZ1C7s9hveiOj+GCN+uT109NC2QgsoVZsVOAvbJ3RgKkvyLGXZV9+piDpWbm6A==", - "dependencies": { - "@jest/diff-sequences": "30.0.1", - "@jest/get-type": "30.1.0", - "chalk": "^4.1.2", - "pretty-format": "30.2.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-diff/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-diff/node_modules/pretty-format": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", - "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", - "dependencies": { - "@jest/schemas": "30.0.5", - "ansi-styles": "^5.2.0", - "react-is": "^18.3.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-diff/node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-diff/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" - }, - "node_modules/jest-docblock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.5.1.tgz", - "integrity": "sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==", - "dependencies": { - "detect-newline": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-each": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.5.1.tgz", - "integrity": "sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==", - "dependencies": { - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "jest-get-type": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-each/node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-each/node_modules/@types/yargs": { - "version": "16.0.11", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.11.tgz", - "integrity": "sha512-sbtvk8wDN+JvEdabmZExoW/HNr1cB7D/j4LT08rMiuikfA7m/JNJg7ATQcgzs34zHnoScDkY0ZRSl29Fkmk36g==", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/jest-each/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-each/node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-each/node_modules/jest-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", - "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-each/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/jest-environment-jsdom": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz", - "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==", - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1", - "jsdom": "^16.6.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-environment-jsdom/node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-environment-jsdom/node_modules/@types/yargs": { - "version": "16.0.11", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.11.tgz", - "integrity": "sha512-sbtvk8wDN+JvEdabmZExoW/HNr1cB7D/j4LT08rMiuikfA7m/JNJg7ATQcgzs34zHnoScDkY0ZRSl29Fkmk36g==", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/jest-environment-jsdom/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-environment-jsdom/node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-environment-jsdom/node_modules/jest-mock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", - "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-environment-jsdom/node_modules/jest-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", - "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-environment-jsdom/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/jest-environment-node": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz", - "integrity": "sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==", - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-environment-node/node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-environment-node/node_modules/@types/yargs": { - "version": "16.0.11", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.11.tgz", - "integrity": "sha512-sbtvk8wDN+JvEdabmZExoW/HNr1cB7D/j4LT08rMiuikfA7m/JNJg7ATQcgzs34zHnoScDkY0ZRSl29Fkmk36g==", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/jest-environment-node/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-environment-node/node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-environment-node/node_modules/jest-mock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", - "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-environment-node/node_modules/jest-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", - "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-environment-node/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/jest-get-type": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", - "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-haste-map": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", - "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/graceful-fs": "^4.1.2", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^27.5.1", - "jest-serializer": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "micromatch": "^4.0.4", - "walker": "^1.0.7" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.2" - } - }, - "node_modules/jest-haste-map/node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-haste-map/node_modules/@types/yargs": { - "version": "16.0.11", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.11.tgz", - "integrity": "sha512-sbtvk8wDN+JvEdabmZExoW/HNr1cB7D/j4LT08rMiuikfA7m/JNJg7ATQcgzs34zHnoScDkY0ZRSl29Fkmk36g==", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/jest-haste-map/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-haste-map/node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-haste-map/node_modules/jest-regex-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", - "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-haste-map/node_modules/jest-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", - "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-haste-map/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/jest-jasmine2": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz", - "integrity": "sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==", - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/source-map": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^27.5.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-jasmine2/node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-jasmine2/node_modules/@types/yargs": { - "version": "16.0.11", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.11.tgz", - "integrity": "sha512-sbtvk8wDN+JvEdabmZExoW/HNr1cB7D/j4LT08rMiuikfA7m/JNJg7ATQcgzs34zHnoScDkY0ZRSl29Fkmk36g==", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/jest-jasmine2/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-jasmine2/node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-jasmine2/node_modules/expect": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", - "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", - "dependencies": { - "@jest/types": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-jasmine2/node_modules/jest-diff": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", - "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-jasmine2/node_modules/jest-matcher-utils": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", - "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-jasmine2/node_modules/jest-message-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", - "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.5.1", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-jasmine2/node_modules/jest-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", - "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-jasmine2/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/jest-leak-detector": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", - "integrity": "sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==", - "dependencies": { - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-matcher-utils": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.2.0.tgz", - "integrity": "sha512-dQ94Nq4dbzmUWkQ0ANAWS9tBRfqCrn0bV9AMYdOi/MHW726xn7eQmMeRTpX2ViC00bpNaWXq+7o4lIQ3AX13Hg==", - "dependencies": { - "@jest/get-type": "30.1.0", - "chalk": "^4.1.2", - "jest-diff": "30.2.0", - "pretty-format": "30.2.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-matcher-utils/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-matcher-utils/node_modules/pretty-format": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", - "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", - "dependencies": { - "@jest/schemas": "30.0.5", - "ansi-styles": "^5.2.0", - "react-is": "^18.3.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-matcher-utils/node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-matcher-utils/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" - }, - "node_modules/jest-message-util": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.2.0.tgz", - "integrity": "sha512-y4DKFLZ2y6DxTWD4cDe07RglV88ZiNEdlRfGtqahfbIjfsw1nMCPx49Uev4IA/hWn3sDKyAnSPwoYSsAEdcimw==", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@jest/types": "30.2.0", - "@types/stack-utils": "^2.0.3", - "chalk": "^4.1.2", - "graceful-fs": "^4.2.11", - "micromatch": "^4.0.8", - "pretty-format": "30.2.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.6" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-message-util/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-message-util/node_modules/pretty-format": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", - "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", - "dependencies": { - "@jest/schemas": "30.0.5", - "ansi-styles": "^5.2.0", - "react-is": "^18.3.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-message-util/node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-message-util/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" - }, - "node_modules/jest-mock": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.2.0.tgz", - "integrity": "sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw==", - "dependencies": { - "@jest/types": "30.2.0", - "@types/node": "*", - "jest-util": "30.2.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-pnp-resolver": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", - "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "jest-resolve": "*" - }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } - } - }, - "node_modules/jest-regex-util": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.0.1.tgz", - "integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-resolve": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.5.1.tgz", - "integrity": "sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==", - "dependencies": { - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "resolve": "^1.20.0", - "resolve.exports": "^1.1.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-resolve-dependencies": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz", - "integrity": "sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==", - "dependencies": { - "@jest/types": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-snapshot": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-resolve-dependencies/node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-resolve-dependencies/node_modules/@types/yargs": { - "version": "16.0.11", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.11.tgz", - "integrity": "sha512-sbtvk8wDN+JvEdabmZExoW/HNr1cB7D/j4LT08rMiuikfA7m/JNJg7ATQcgzs34zHnoScDkY0ZRSl29Fkmk36g==", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/jest-resolve-dependencies/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-resolve-dependencies/node_modules/jest-regex-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", - "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-resolve/node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-resolve/node_modules/@types/yargs": { - "version": "16.0.11", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.11.tgz", - "integrity": "sha512-sbtvk8wDN+JvEdabmZExoW/HNr1cB7D/j4LT08rMiuikfA7m/JNJg7ATQcgzs34zHnoScDkY0ZRSl29Fkmk36g==", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/jest-resolve/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-resolve/node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-resolve/node_modules/jest-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", - "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-resolve/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/jest-runner": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.5.1.tgz", - "integrity": "sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==", - "dependencies": { - "@jest/console": "^27.5.1", - "@jest/environment": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^27.5.1", - "jest-environment-jsdom": "^27.5.1", - "jest-environment-node": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-leak-detector": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "source-map-support": "^0.5.6", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-runner/node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-runner/node_modules/@types/yargs": { - "version": "16.0.11", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.11.tgz", - "integrity": "sha512-sbtvk8wDN+JvEdabmZExoW/HNr1cB7D/j4LT08rMiuikfA7m/JNJg7ATQcgzs34zHnoScDkY0ZRSl29Fkmk36g==", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/jest-runner/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-runner/node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runner/node_modules/jest-message-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", - "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.5.1", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-runner/node_modules/jest-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", - "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-runner/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/jest-runtime": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz", - "integrity": "sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==", - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/globals": "^27.5.1", - "@jest/source-map": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "execa": "^5.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-runtime/node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-runtime/node_modules/@types/yargs": { - "version": "16.0.11", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.11.tgz", - "integrity": "sha512-sbtvk8wDN+JvEdabmZExoW/HNr1cB7D/j4LT08rMiuikfA7m/JNJg7ATQcgzs34zHnoScDkY0ZRSl29Fkmk36g==", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/jest-runtime/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-runtime/node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runtime/node_modules/jest-message-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", - "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.5.1", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-runtime/node_modules/jest-mock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", - "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-runtime/node_modules/jest-regex-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", - "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-runtime/node_modules/jest-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", - "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-runtime/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/jest-serializer": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", - "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", - "dependencies": { - "@types/node": "*", - "graceful-fs": "^4.2.9" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-snapshot": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.5.1.tgz", - "integrity": "sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==", - "dependencies": { - "@babel/core": "^7.7.2", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.0.0", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^27.5.1", - "graceful-fs": "^4.2.9", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-util": "^27.5.1", - "natural-compare": "^1.4.0", - "pretty-format": "^27.5.1", - "semver": "^7.3.2" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-snapshot/node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-snapshot/node_modules/@types/yargs": { - "version": "16.0.11", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.11.tgz", - "integrity": "sha512-sbtvk8wDN+JvEdabmZExoW/HNr1cB7D/j4LT08rMiuikfA7m/JNJg7ATQcgzs34zHnoScDkY0ZRSl29Fkmk36g==", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/jest-snapshot/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-snapshot/node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-snapshot/node_modules/expect": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", - "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", - "dependencies": { - "@jest/types": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-snapshot/node_modules/jest-diff": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", - "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-snapshot/node_modules/jest-matcher-utils": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", - "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-snapshot/node_modules/jest-message-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", - "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.5.1", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-snapshot/node_modules/jest-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", - "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-snapshot/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/jest-snapshot/node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-util": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", - "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", - "dependencies": { - "@jest/types": "30.2.0", - "@types/node": "*", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "graceful-fs": "^4.2.11", - "picomatch": "^4.0.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-util/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-validate": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.5.1.tgz", - "integrity": "sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==", - "dependencies": { - "@jest/types": "^27.5.1", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^27.5.1", - "leven": "^3.1.0", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-validate/node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-validate/node_modules/@types/yargs": { - "version": "16.0.11", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.11.tgz", - "integrity": "sha512-sbtvk8wDN+JvEdabmZExoW/HNr1cB7D/j4LT08rMiuikfA7m/JNJg7ATQcgzs34zHnoScDkY0ZRSl29Fkmk36g==", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/jest-validate/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-watch-typeahead": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/jest-watch-typeahead/-/jest-watch-typeahead-1.1.0.tgz", - "integrity": "sha512-Va5nLSJTN7YFtC2jd+7wsoe1pNe5K4ShLux/E5iHEwlB9AxaxmggY7to9KUqKojhaJw3aXqt5WAb4jGPOolpEw==", - "dependencies": { - "ansi-escapes": "^4.3.1", - "chalk": "^4.0.0", - "jest-regex-util": "^28.0.0", - "jest-watcher": "^28.0.0", - "slash": "^4.0.0", - "string-length": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "jest": "^27.0.0 || ^28.0.0" - } - }, - "node_modules/jest-watch-typeahead/node_modules/@jest/console": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-28.1.3.tgz", - "integrity": "sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==", - "dependencies": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^28.1.3", - "jest-util": "^28.1.3", - "slash": "^3.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-watch-typeahead/node_modules/@jest/console/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-watch-typeahead/node_modules/@jest/schemas": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz", - "integrity": "sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==", - "dependencies": { - "@sinclair/typebox": "^0.24.1" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-watch-typeahead/node_modules/@jest/test-result": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.3.tgz", - "integrity": "sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==", - "dependencies": { - "@jest/console": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-watch-typeahead/node_modules/@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dependencies": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-watch-typeahead/node_modules/@sinclair/typebox": { - "version": "0.24.51", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", - "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==" - }, - "node_modules/jest-watch-typeahead/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-watch-typeahead/node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-watch-typeahead/node_modules/emittery": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz", - "integrity": "sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" - } - }, - "node_modules/jest-watch-typeahead/node_modules/jest-message-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", - "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^28.1.3", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-watch-typeahead/node_modules/jest-message-util/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-watch-typeahead/node_modules/jest-regex-util": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-28.0.2.tgz", - "integrity": "sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==", - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-watch-typeahead/node_modules/jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", - "dependencies": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-watch-typeahead/node_modules/jest-watcher": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.3.tgz", - "integrity": "sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==", - "dependencies": { - "@jest/test-result": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.10.2", - "jest-util": "^28.1.3", - "string-length": "^4.0.1" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-watch-typeahead/node_modules/jest-watcher/node_modules/string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-watch-typeahead/node_modules/jest-watcher/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-watch-typeahead/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/jest-watch-typeahead/node_modules/pretty-format": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", - "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", - "dependencies": { - "@jest/schemas": "^28.1.3", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-watch-typeahead/node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-watch-typeahead/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" - }, - "node_modules/jest-watch-typeahead/node_modules/slash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", - "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-watch-typeahead/node_modules/string-length": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-5.0.1.tgz", - "integrity": "sha512-9Ep08KAMUn0OadnVaBuRdE2l615CQ508kr0XMadjClfYpdCyvrbFp6Taebo8yyxokQ4viUd/xPPUA4FGgUa0ow==", - "dependencies": { - "char-regex": "^2.0.0", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-watch-typeahead/node_modules/string-length/node_modules/char-regex": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-2.0.2.tgz", - "integrity": "sha512-cbGOjAptfM2LVmWhwRFHEKTPkLwNddVmuqYZQt895yXwAsWsXObCG+YN4DGQ/JBtT4GP1a1lPPdio2z413LmTg==", - "engines": { - "node": ">=12.20" - } - }, - "node_modules/jest-watch-typeahead/node_modules/strip-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/jest-watch-typeahead/node_modules/strip-ansi/node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/jest-watcher": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.5.1.tgz", - "integrity": "sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==", - "dependencies": { - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "jest-util": "^27.5.1", - "string-length": "^4.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-watcher/node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-watcher/node_modules/@types/yargs": { - "version": "16.0.11", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.11.tgz", - "integrity": "sha512-sbtvk8wDN+JvEdabmZExoW/HNr1cB7D/j4LT08rMiuikfA7m/JNJg7ATQcgzs34zHnoScDkY0ZRSl29Fkmk36g==", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/jest-watcher/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-watcher/node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-watcher/node_modules/jest-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", - "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-watcher/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/jiti": { - "version": "1.21.7", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", - "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", - "bin": { - "jiti": "bin/jiti.js" - } - }, - "node_modules/js-cookie": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz", - "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==", - "engines": { - "node": ">=14" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "node_modules/js-yaml": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", - "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsdom": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", - "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", - "dependencies": { - "abab": "^2.0.5", - "acorn": "^8.2.4", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.3.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.1", - "domexception": "^2.0.1", - "escodegen": "^2.0.0", - "form-data": "^3.0.0", - "html-encoding-sniffer": "^2.0.1", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "6.0.1", - "saxes": "^5.0.1", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.1.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.5.0", - "ws": "^7.4.6", - "xml-name-validator": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "canvas": "^2.5.0" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } - } - }, - "node_modules/jsdom/node_modules/form-data": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.4.tgz", - "integrity": "sha512-f0cRzm6dkyVYV3nPoooP8XlccPQukegwhAnpoLcXy+X+A8KfpGOoXwDr9FLZd3wzgLaBGQBE3lY93Zm/i1JvIQ==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.2", - "mime-types": "^2.1.35" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/jsesc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" - }, - "node_modules/json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonfile": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", - "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/jsonpath": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-1.1.1.tgz", - "integrity": "sha512-l6Cg7jRpixfbgoWgkrl77dgEj8RPvND0wMH6TwQmi9Qs4TFfS9u5cUFnbeKTwj5ga5Y3BTGGNI28k117LJ009w==", - "dependencies": { - "esprima": "1.2.2", - "static-eval": "2.0.2", - "underscore": "1.12.1" - } - }, - "node_modules/jsonpath/node_modules/esprima": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.2.2.tgz", - "integrity": "sha512-+JpPZam9w5DuJ3Q67SqsMGtiHKENSMRVoxvArfJZK01/BfLEObtZ6orJa/MtoGNR/rfMgp5837T41PAmTwAv/A==", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/jsonpointer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", - "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/jsx-ast-utils": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", - "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", - "dependencies": { - "array-includes": "^3.1.6", - "array.prototype.flat": "^1.3.1", - "object.assign": "^4.1.4", - "object.values": "^1.1.6" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "engines": { - "node": ">=6" - } - }, - "node_modules/klona": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz", - "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/language-subtag-registry": { - "version": "0.3.23", - "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", - "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==" - }, - "node_modules/language-tags": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", - "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", - "dependencies": { - "language-subtag-registry": "^0.3.20" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/launch-editor": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.12.0.tgz", - "integrity": "sha512-giOHXoOtifjdHqUamwKq6c49GzBdLjvxrd2D+Q4V6uOHopJv7p9VJxikDsQ/CBXZbEITgUqSVHXLTG3VhPP1Dg==", - "dependencies": { - "picocolors": "^1.1.1", - "shell-quote": "^1.8.3" - } - }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "engines": { - "node": ">=6" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/lilconfig": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", - "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", - "engines": { - "node": ">=10" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" - }, - "node_modules/loader-runner": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz", - "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==", - "engines": { - "node": ">=6.11.5" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/loader-utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, - "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" - }, - "node_modules/lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" - }, - "node_modules/lodash.sortby": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==" - }, - "node_modules/lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "dependencies": { - "tslib": "^2.0.3" - } - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/lz-string": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", - "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", - "bin": { - "lz-string": "bin/bin.js" - } - }, - "node_modules/magic-string": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", - "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", - "dependencies": { - "sourcemap-codec": "^1.4.8" - } - }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "dependencies": { - "tmpl": "1.0.5" - } - }, - "node_modules/math-intrinsics": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/mdn-data": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", - "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==" - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/memfs": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", - "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", - "dependencies": { - "fs-monkey": "^1.0.4" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", - "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/micromatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/min-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", - "engines": { - "node": ">=4" - } - }, - "node_modules/mini-css-extract-plugin": { - "version": "2.9.4", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.4.tgz", - "integrity": "sha512-ZWYT7ln73Hptxqxk2DxPU9MmapXRhxkJD6tkSR04dnQxm8BGu2hzgKLugK5yySD97u/8yy7Ma7E76k9ZdvtjkQ==", - "dependencies": { - "schema-utils": "^4.0.0", - "tapable": "^2.2.1" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - } - }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/moment": { - "version": "2.30.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", - "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", - "engines": { - "node": "*" - } - }, - "node_modules/moment-jalaali": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/moment-jalaali/-/moment-jalaali-0.10.4.tgz", - "integrity": "sha512-/eD0HeyvATznb5iE0G1BHjKRZAFEpJ9ZNUkcHwXhNgt1WJJVVzHD7+uDmqzZWVFLdbGme2gvIXKb3ezDYOXcZA==", - "dependencies": { - "jalaali-js": "^1.2.7", - "moment": "^2.29.4", - "moment-timezone": "^0.5.46" - } - }, - "node_modules/moment-timezone": { - "version": "0.5.48", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.48.tgz", - "integrity": "sha512-f22b8LV1gbTO2ms2j2z13MuPogNoh5UzxL3nzNAYKGraILnbGc9NEE6dyiiiLv46DGRb8A4kg8UKWLjPthxBHw==", - "dependencies": { - "moment": "^2.29.4" - }, - "engines": { - "node": "*" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/multicast-dns": { - "version": "7.2.5", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", - "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", - "dependencies": { - "dns-packet": "^5.2.2", - "thunky": "^1.0.2" - }, - "bin": { - "multicast-dns": "cli.js" - } - }, - "node_modules/mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dependencies": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" - } - }, - "node_modules/nanoid": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" - }, - "node_modules/natural-compare-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==" - }, - "node_modules/negotiator": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", - "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" - }, - "node_modules/no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "dependencies": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, - "node_modules/node-forge": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.3.tgz", - "integrity": "sha512-rLvcdSyRCyouf6jcOIPe/BgwG/d7hKjzMKOas33/pHEr6gbq18IK9zV7DiPvzsz0oBJPme6qr6H6kGZuI9/DZg==", - "engines": { - "node": ">= 6.13.0" - } - }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==" - }, - "node_modules/node-releases": { - "version": "2.0.27", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", - "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==" - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, - "node_modules/nwsapi": { - "version": "2.2.23", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.23.tgz", - "integrity": "sha512-7wfH4sLbt4M0gCDzGE6vzQBo0bfTKjU7Sfpqy/7gs1qBfYz2vEJH6vXcBKpO3+6Yu1telwd0t9HpyOoLEQQbIQ==" - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-hash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", - "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-is": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", - "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", - "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0", - "has-symbols": "^1.1.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.entries": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", - "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.fromentries": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", - "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.getownpropertydescriptors": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.9.tgz", - "integrity": "sha512-mt8YM6XwsTTovI+kdZdHSxoyF2DI59up034orlC9NfweclcWOt7CVascNNLp6U+bjFVCVCIh9PwS76tDM/rH8g==", - "dependencies": { - "array.prototype.reduce": "^1.0.8", - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-abstract": "^1.24.0", - "es-object-atoms": "^1.1.1", - "gopd": "^1.2.0", - "safe-array-concat": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.groupby": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", - "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.values": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", - "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/obuf": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/on-headers": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", - "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/open": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", - "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", - "dependencies": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/own-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", - "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", - "dependencies": { - "get-intrinsic": "^1.2.6", - "object-keys": "^1.1.1", - "safe-push-apply": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-retry": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", - "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", - "dependencies": { - "@types/retry": "0.12.0", - "retry": "^0.13.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/param-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", - "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", - "dependencies": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/parchment": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/parchment/-/parchment-1.1.4.tgz", - "integrity": "sha512-J5FBQt/pM2inLzg4hEWmzQx/8h8D0CiDxaG3vyp9rKrQRSDgBlhjdP5jQGgosEajXPSQouXGHOmVdgo7QmJuOg==" - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/pascal-case": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", - "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, - "node_modules/path-to-regexp": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", - "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==" - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" - }, - "node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pirates": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", - "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-up": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", - "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", - "dependencies": { - "find-up": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-up/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/possible-typed-array-names": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", - "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/postcss": { - "version": "8.5.6", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", - "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "nanoid": "^3.3.11", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/postcss-attribute-case-insensitive": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-5.0.2.tgz", - "integrity": "sha512-XIidXV8fDr0kKt28vqki84fRK8VW8eTuIa4PChv2MqKuT6C9UjmSKzen6KaWhWEoYvwxFCa7n/tC1SZ3tyq4SQ==", - "dependencies": { - "postcss-selector-parser": "^6.0.10" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-browser-comments": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-browser-comments/-/postcss-browser-comments-4.0.0.tgz", - "integrity": "sha512-X9X9/WN3KIvY9+hNERUqX9gncsgBA25XaeR+jshHz2j8+sYyHktHw1JdKuMjeLpGktXidqDhA7b/qm1mrBDmgg==", - "engines": { - "node": ">=8" - }, - "peerDependencies": { - "browserslist": ">=4", - "postcss": ">=8" - } - }, - "node_modules/postcss-calc": { - "version": "8.2.4", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz", - "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==", - "dependencies": { - "postcss-selector-parser": "^6.0.9", - "postcss-value-parser": "^4.2.0" - }, - "peerDependencies": { - "postcss": "^8.2.2" - } - }, - "node_modules/postcss-clamp": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-clamp/-/postcss-clamp-4.1.0.tgz", - "integrity": "sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": ">=7.6.0" - }, - "peerDependencies": { - "postcss": "^8.4.6" - } - }, - "node_modules/postcss-color-functional-notation": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-4.2.4.tgz", - "integrity": "sha512-2yrTAUZUab9s6CpxkxC4rVgFEVaR6/2Pipvi6qcgvnYiVqZcbDHEoBDhrXzyb7Efh2CCfHQNtcqWcIruDTIUeg==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-color-hex-alpha": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-8.0.4.tgz", - "integrity": "sha512-nLo2DCRC9eE4w2JmuKgVA3fGL3d01kGq752pVALF68qpGLmx2Qrk91QTKkdUqqp45T1K1XV8IhQpcu1hoAQflQ==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-color-rebeccapurple": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-7.1.1.tgz", - "integrity": "sha512-pGxkuVEInwLHgkNxUc4sdg4g3py7zUeCQ9sMfwyHAT+Ezk8a4OaaVZ8lIY5+oNqA/BXXgLyXv0+5wHP68R79hg==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-colormin": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.1.tgz", - "integrity": "sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==", - "dependencies": { - "browserslist": "^4.21.4", - "caniuse-api": "^3.0.0", - "colord": "^2.9.1", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-convert-values": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz", - "integrity": "sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==", - "dependencies": { - "browserslist": "^4.21.4", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-custom-media": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-8.0.2.tgz", - "integrity": "sha512-7yi25vDAoHAkbhAzX9dHx2yc6ntS4jQvejrNcC+csQJAXjj15e7VcWfMgLqBNAbOvqi5uIa9huOVwdHbf+sKqg==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.3" - } - }, - "node_modules/postcss-custom-properties": { - "version": "12.1.11", - "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-12.1.11.tgz", - "integrity": "sha512-0IDJYhgU8xDv1KY6+VgUwuQkVtmYzRwu+dMjnmdMafXYv86SWqfxkc7qdDvWS38vsjaEtv8e0vGOUQrAiMBLpQ==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-custom-selectors": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-6.0.3.tgz", - "integrity": "sha512-fgVkmyiWDwmD3JbpCmB45SvvlCD6z9CG6Ie6Iere22W5aHea6oWa7EM2bpnv2Fj3I94L3VbtvX9KqwSi5aFzSg==", - "dependencies": { - "postcss-selector-parser": "^6.0.4" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.3" - } - }, - "node_modules/postcss-dir-pseudo-class": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-6.0.5.tgz", - "integrity": "sha512-eqn4m70P031PF7ZQIvSgy9RSJ5uI2171O/OO/zcRNYpJbvaeKFUlar1aJ7rmgiQtbm0FSPsRewjpdS0Oew7MPA==", - "dependencies": { - "postcss-selector-parser": "^6.0.10" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-discard-comments": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz", - "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==", - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-discard-duplicates": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", - "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-discard-empty": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", - "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-discard-overridden": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", - "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-double-position-gradients": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-3.1.2.tgz", - "integrity": "sha512-GX+FuE/uBR6eskOK+4vkXgT6pDkexLokPaz/AbJna9s5Kzp/yl488pKPjhy0obB475ovfT1Wv8ho7U/cHNaRgQ==", - "dependencies": { - "@csstools/postcss-progressive-custom-properties": "^1.1.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-env-function": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-4.0.6.tgz", - "integrity": "sha512-kpA6FsLra+NqcFnL81TnsU+Z7orGtDTxcOhl6pwXeEq1yFPpRMkCDpHhrz8CFQDr/Wfm0jLiNQ1OsGGPjlqPwA==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-flexbugs-fixes": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-5.0.2.tgz", - "integrity": "sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ==", - "peerDependencies": { - "postcss": "^8.1.4" - } - }, - "node_modules/postcss-focus-visible": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-6.0.4.tgz", - "integrity": "sha512-QcKuUU/dgNsstIK6HELFRT5Y3lbrMLEOwG+A4s5cA+fx3A3y/JTq3X9LaOj3OC3ALH0XqyrgQIgey/MIZ8Wczw==", - "dependencies": { - "postcss-selector-parser": "^6.0.9" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-focus-within": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-5.0.4.tgz", - "integrity": "sha512-vvjDN++C0mu8jz4af5d52CB184ogg/sSxAFS+oUJQq2SuCe7T5U2iIsVJtsCp2d6R4j0jr5+q3rPkBVZkXD9fQ==", - "dependencies": { - "postcss-selector-parser": "^6.0.9" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-font-variant": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz", - "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==", - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-gap-properties": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-3.0.5.tgz", - "integrity": "sha512-IuE6gKSdoUNcvkGIqdtjtcMtZIFyXZhmFd5RUlg97iVEvp1BZKV5ngsAjCjrVy+14uhGBQl9tzmi1Qwq4kqVOg==", - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-image-set-function": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-4.0.7.tgz", - "integrity": "sha512-9T2r9rsvYzm5ndsBE8WgtrMlIT7VbtTfE7b3BQnudUqnBcBo7L758oc+o+pdj/dUV0l5wjwSdjeOH2DZtfv8qw==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-import": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", - "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", - "dependencies": { - "postcss-value-parser": "^4.0.0", - "read-cache": "^1.0.0", - "resolve": "^1.1.7" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "postcss": "^8.0.0" - } - }, - "node_modules/postcss-initial": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-4.0.1.tgz", - "integrity": "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==", - "peerDependencies": { - "postcss": "^8.0.0" - } - }, - "node_modules/postcss-js": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.1.0.tgz", - "integrity": "sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "camelcase-css": "^2.0.1" - }, - "engines": { - "node": "^12 || ^14 || >= 16" - }, - "peerDependencies": { - "postcss": "^8.4.21" - } - }, - "node_modules/postcss-lab-function": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-4.2.1.tgz", - "integrity": "sha512-xuXll4isR03CrQsmxyz92LJB2xX9n+pZJ5jE9JgcnmsCammLyKdlzrBin+25dy6wIjfhJpKBAN80gsTlCgRk2w==", - "dependencies": { - "@csstools/postcss-progressive-custom-properties": "^1.1.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-loader": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-6.2.1.tgz", - "integrity": "sha512-WbbYpmAaKcux/P66bZ40bpWsBucjx/TTgVVzRZ9yUO8yQfVBlameJ0ZGVaPfH64hNSBh63a+ICP5nqOpBA0w+Q==", - "dependencies": { - "cosmiconfig": "^7.0.0", - "klona": "^2.0.5", - "semver": "^7.3.5" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "postcss": "^7.0.0 || ^8.0.1", - "webpack": "^5.0.0" - } - }, - "node_modules/postcss-loader/node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/postcss-logical": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.4.tgz", - "integrity": "sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==", - "engines": { - "node": "^12 || ^14 || >=16" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-media-minmax": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz", - "integrity": "sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-merge-longhand": { - "version": "5.1.7", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz", - "integrity": "sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==", - "dependencies": { - "postcss-value-parser": "^4.2.0", - "stylehacks": "^5.1.1" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-merge-rules": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz", - "integrity": "sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==", - "dependencies": { - "browserslist": "^4.21.4", - "caniuse-api": "^3.0.0", - "cssnano-utils": "^3.1.0", - "postcss-selector-parser": "^6.0.5" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-minify-font-values": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz", - "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-minify-gradients": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz", - "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==", - "dependencies": { - "colord": "^2.9.1", - "cssnano-utils": "^3.1.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-minify-params": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz", - "integrity": "sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==", - "dependencies": { - "browserslist": "^4.21.4", - "cssnano-utils": "^3.1.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-minify-selectors": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz", - "integrity": "sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==", - "dependencies": { - "postcss-selector-parser": "^6.0.5" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-modules-extract-imports": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", - "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-local-by-default": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz", - "integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==", - "dependencies": { - "icss-utils": "^5.0.0", - "postcss-selector-parser": "^7.0.0", - "postcss-value-parser": "^4.1.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-local-by-default/node_modules/postcss-selector-parser": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", - "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-modules-scope": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz", - "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==", - "dependencies": { - "postcss-selector-parser": "^7.0.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-scope/node_modules/postcss-selector-parser": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", - "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-modules-values": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", - "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", - "dependencies": { - "icss-utils": "^5.0.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-nested": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", - "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "postcss-selector-parser": "^6.1.1" - }, - "engines": { - "node": ">=12.0" - }, - "peerDependencies": { - "postcss": "^8.2.14" - } - }, - "node_modules/postcss-nesting": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-10.2.0.tgz", - "integrity": "sha512-EwMkYchxiDiKUhlJGzWsD9b2zvq/r2SSubcRrgP+jujMXFzqvANLt16lJANC+5uZ6hjI7lpRmI6O8JIl+8l1KA==", - "dependencies": { - "@csstools/selector-specificity": "^2.0.0", - "postcss-selector-parser": "^6.0.10" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-normalize": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize/-/postcss-normalize-10.0.1.tgz", - "integrity": "sha512-+5w18/rDev5mqERcG3W5GZNMJa1eoYYNGo8gB7tEwaos0ajk3ZXAI4mHGcNT47NE+ZnZD1pEpUOFLvltIwmeJA==", - "dependencies": { - "@csstools/normalize.css": "*", - "postcss-browser-comments": "^4", - "sanitize.css": "*" - }, - "engines": { - "node": ">= 12" - }, - "peerDependencies": { - "browserslist": ">= 4", - "postcss": ">= 8" - } - }, - "node_modules/postcss-normalize-charset": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", - "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-display-values": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz", - "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-positions": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz", - "integrity": "sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-repeat-style": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz", - "integrity": "sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-string": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz", - "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-timing-functions": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz", - "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-unicode": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz", - "integrity": "sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==", - "dependencies": { - "browserslist": "^4.21.4", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-url": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz", - "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==", - "dependencies": { - "normalize-url": "^6.0.1", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-whitespace": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz", - "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-opacity-percentage": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.3.tgz", - "integrity": "sha512-An6Ba4pHBiDtyVpSLymUUERMo2cU7s+Obz6BTrS+gxkbnSBNKSuD0AVUc+CpBMrpVPKKfoVz0WQCX+Tnst0i4A==", - "funding": [ - { - "type": "kofi", - "url": "https://ko-fi.com/mrcgrtz" - }, - { - "type": "liberapay", - "url": "https://liberapay.com/mrcgrtz" - } - ], - "engines": { - "node": "^12 || ^14 || >=16" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-ordered-values": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz", - "integrity": "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==", - "dependencies": { - "cssnano-utils": "^3.1.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-overflow-shorthand": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.4.tgz", - "integrity": "sha512-otYl/ylHK8Y9bcBnPLo3foYFLL6a6Ak+3EQBPOTR7luMYCOsiVTUk1iLvNf6tVPNGXcoL9Hoz37kpfriRIFb4A==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-page-break": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-3.0.4.tgz", - "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==", - "peerDependencies": { - "postcss": "^8" - } - }, - "node_modules/postcss-place": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-7.0.5.tgz", - "integrity": "sha512-wR8igaZROA6Z4pv0d+bvVrvGY4GVHihBCBQieXFY3kuSuMyOmEnnfFzHl/tQuqHZkfkIVBEbDvYcFfHmpSet9g==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-preset-env": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-7.8.3.tgz", - "integrity": "sha512-T1LgRm5uEVFSEF83vHZJV2z19lHg4yJuZ6gXZZkqVsqv63nlr6zabMH3l4Pc01FQCyfWVrh2GaUeCVy9Po+Aag==", - "dependencies": { - "@csstools/postcss-cascade-layers": "^1.1.1", - "@csstools/postcss-color-function": "^1.1.1", - "@csstools/postcss-font-format-keywords": "^1.0.1", - "@csstools/postcss-hwb-function": "^1.0.2", - "@csstools/postcss-ic-unit": "^1.0.1", - "@csstools/postcss-is-pseudo-class": "^2.0.7", - "@csstools/postcss-nested-calc": "^1.0.0", - "@csstools/postcss-normalize-display-values": "^1.0.1", - "@csstools/postcss-oklab-function": "^1.1.1", - "@csstools/postcss-progressive-custom-properties": "^1.3.0", - "@csstools/postcss-stepped-value-functions": "^1.0.1", - "@csstools/postcss-text-decoration-shorthand": "^1.0.0", - "@csstools/postcss-trigonometric-functions": "^1.0.2", - "@csstools/postcss-unset-value": "^1.0.2", - "autoprefixer": "^10.4.13", - "browserslist": "^4.21.4", - "css-blank-pseudo": "^3.0.3", - "css-has-pseudo": "^3.0.4", - "css-prefers-color-scheme": "^6.0.3", - "cssdb": "^7.1.0", - "postcss-attribute-case-insensitive": "^5.0.2", - "postcss-clamp": "^4.1.0", - "postcss-color-functional-notation": "^4.2.4", - "postcss-color-hex-alpha": "^8.0.4", - "postcss-color-rebeccapurple": "^7.1.1", - "postcss-custom-media": "^8.0.2", - "postcss-custom-properties": "^12.1.10", - "postcss-custom-selectors": "^6.0.3", - "postcss-dir-pseudo-class": "^6.0.5", - "postcss-double-position-gradients": "^3.1.2", - "postcss-env-function": "^4.0.6", - "postcss-focus-visible": "^6.0.4", - "postcss-focus-within": "^5.0.4", - "postcss-font-variant": "^5.0.0", - "postcss-gap-properties": "^3.0.5", - "postcss-image-set-function": "^4.0.7", - "postcss-initial": "^4.0.1", - "postcss-lab-function": "^4.2.1", - "postcss-logical": "^5.0.4", - "postcss-media-minmax": "^5.0.0", - "postcss-nesting": "^10.2.0", - "postcss-opacity-percentage": "^1.1.2", - "postcss-overflow-shorthand": "^3.0.4", - "postcss-page-break": "^3.0.4", - "postcss-place": "^7.0.5", - "postcss-pseudo-class-any-link": "^7.1.6", - "postcss-replace-overflow-wrap": "^4.0.0", - "postcss-selector-not": "^6.0.1", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-pseudo-class-any-link": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.1.6.tgz", - "integrity": "sha512-9sCtZkO6f/5ML9WcTLcIyV1yz9D1rf0tWc+ulKcvV30s0iZKS/ONyETvoWsr6vnrmW+X+KmuK3gV/w5EWnT37w==", - "dependencies": { - "postcss-selector-parser": "^6.0.10" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-reduce-initial": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz", - "integrity": "sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==", - "dependencies": { - "browserslist": "^4.21.4", - "caniuse-api": "^3.0.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-reduce-transforms": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz", - "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-replace-overflow-wrap": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz", - "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==", - "peerDependencies": { - "postcss": "^8.0.3" - } - }, - "node_modules/postcss-selector-not": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-6.0.1.tgz", - "integrity": "sha512-1i9affjAe9xu/y9uqWH+tD4r6/hDaXJruk8xn2x1vzxC2U3J3LKO3zJW4CyxlNhA56pADJ/djpEwpH1RClI2rQ==", - "dependencies": { - "postcss-selector-parser": "^6.0.10" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-selector-parser": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", - "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-svgo": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz", - "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==", - "dependencies": { - "postcss-value-parser": "^4.2.0", - "svgo": "^2.7.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-svgo/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/postcss-svgo/node_modules/css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", - "dependencies": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/postcss-svgo/node_modules/mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" - }, - "node_modules/postcss-svgo/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-svgo/node_modules/svgo": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", - "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", - "dependencies": { - "@trysound/sax": "0.2.0", - "commander": "^7.2.0", - "css-select": "^4.1.3", - "css-tree": "^1.1.3", - "csso": "^4.2.0", - "picocolors": "^1.0.0", - "stable": "^0.1.8" - }, - "bin": { - "svgo": "bin/svgo" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/postcss-unique-selectors": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz", - "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==", - "dependencies": { - "postcss-selector-parser": "^6.0.5" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/pretty-bytes": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", - "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pretty-error": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", - "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", - "dependencies": { - "lodash": "^4.17.20", - "renderkid": "^3.0.0" - } - }, - "node_modules/pretty-format": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", - "dependencies": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "node_modules/promise": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", - "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", - "dependencies": { - "asap": "~2.0.6" - } - }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/prop-types": { - "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dependencies": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" - } - }, - "node_modules/prop-types/node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, - "node_modules/property-expr": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.6.tgz", - "integrity": "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==" - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/proxy-addr/node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" - }, - "node_modules/psl": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", - "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", - "dependencies": { - "punycode": "^2.3.1" - }, - "funding": { - "url": "https://github.com/sponsors/lupomontero" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", - "deprecated": "You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other.\n\n(For a CapTP with native promises, see @endo/eventual-send and @endo/captp)", - "engines": { - "node": ">=0.6.0", - "teleport": ">=0.2.0" - } - }, - "node_modules/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", - "dependencies": { - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/quill": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/quill/-/quill-1.3.7.tgz", - "integrity": "sha512-hG/DVzh/TiknWtE6QmWAF/pxoZKYxfe3J/d/+ShUWkDvvkZQVTPeVmUJVu1uE6DDooC4fWTiCLh84ul89oNz5g==", - "dependencies": { - "clone": "^2.1.1", - "deep-equal": "^1.0.1", - "eventemitter3": "^2.0.3", - "extend": "^3.0.2", - "parchment": "^1.1.4", - "quill-delta": "^3.6.2" - } - }, - "node_modules/quill-delta": { - "version": "3.6.3", - "resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-3.6.3.tgz", - "integrity": "sha512-wdIGBlcX13tCHOXGMVnnTVFtGRLoP0imqxM696fIPwIf5ODIYUHIvHbZcyvGlZFiFhK5XzDC2lpjbxRhnM05Tg==", - "dependencies": { - "deep-equal": "^1.0.1", - "extend": "^3.0.2", - "fast-diff": "1.1.2" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/raf": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", - "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", - "dependencies": { - "performance-now": "^2.1.0" - } - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz", - "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", - "dependencies": { - "bytes": "~3.1.2", - "http-errors": "~2.0.1", - "iconv-lite": "~0.4.24", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/raw-body/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", - "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", - "dependencies": { - "loose-envify": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-app-polyfill": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/react-app-polyfill/-/react-app-polyfill-3.0.0.tgz", - "integrity": "sha512-sZ41cxiU5llIB003yxxQBYrARBqe0repqPTTYBTmMqTz9szeBbE37BehCE891NZsmdZqqP+xWKdT3eo3vOzN8w==", - "dependencies": { - "core-js": "^3.19.2", - "object-assign": "^4.1.1", - "promise": "^8.1.0", - "raf": "^3.4.1", - "regenerator-runtime": "^0.13.9", - "whatwg-fetch": "^3.6.2" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/react-date-object": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/react-date-object/-/react-date-object-2.1.9.tgz", - "integrity": "sha512-BHxD/quWOTo9fLKV/cfL/M31ePoj4a1JaJ/CnOf8Ndg3mrkh4x9wEMMkCfTrzduxDOgU8ZgR8uarhqI5G71sTg==" - }, - "node_modules/react-dev-utils": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", - "integrity": "sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==", - "dependencies": { - "@babel/code-frame": "^7.16.0", - "address": "^1.1.2", - "browserslist": "^4.18.1", - "chalk": "^4.1.2", - "cross-spawn": "^7.0.3", - "detect-port-alt": "^1.1.6", - "escape-string-regexp": "^4.0.0", - "filesize": "^8.0.6", - "find-up": "^5.0.0", - "fork-ts-checker-webpack-plugin": "^6.5.0", - "global-modules": "^2.0.0", - "globby": "^11.0.4", - "gzip-size": "^6.0.0", - "immer": "^9.0.7", - "is-root": "^2.1.0", - "loader-utils": "^3.2.0", - "open": "^8.4.0", - "pkg-up": "^3.1.0", - "prompts": "^2.4.2", - "react-error-overlay": "^6.0.11", - "recursive-readdir": "^2.2.2", - "shell-quote": "^1.7.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/react-dev-utils/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/react-dev-utils/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/react-dev-utils/node_modules/loader-utils": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz", - "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==", - "engines": { - "node": ">= 12.13.0" - } - }, - "node_modules/react-dev-utils/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/react-dev-utils/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/react-dev-utils/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/react-dom": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", - "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", - "dependencies": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.2" - }, - "peerDependencies": { - "react": "^18.3.1" - } - }, - "node_modules/react-element-popper": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/react-element-popper/-/react-element-popper-2.1.7.tgz", - "integrity": "sha512-tuM2OxKlW32h+6uFSK6EENHPeZ2OGgOipHfOAl+VLWEv9/j3QkSGbD+ADX3A9uJlmq24i37n28RjJmAbGTfpEg==", - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" - } - }, - "node_modules/react-error-overlay": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.1.0.tgz", - "integrity": "sha512-SN/U6Ytxf1QGkw/9ve5Y+NxBbZM6Ht95tuXNMKs8EJyFa/Vy/+Co3stop3KBHARfn/giv+Lj1uUnTfOJ3moFEQ==" - }, - "node_modules/react-hot-toast": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/react-hot-toast/-/react-hot-toast-2.6.0.tgz", - "integrity": "sha512-bH+2EBMZ4sdyou/DPrfgIouFpcRLCJ+HoCA32UoAYHn6T3Ur5yfcDCeSr5mwldl6pFOsiocmrXMuoCJ1vV8bWg==", - "dependencies": { - "csstype": "^3.1.3", - "goober": "^2.1.16" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "react": ">=16", - "react-dom": ">=16" - } - }, - "node_modules/react-icons": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz", - "integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==", - "peerDependencies": { - "react": "*" - } - }, - "node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" - }, - "node_modules/react-lifecycles-compat": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", - "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" - }, - "node_modules/react-modal": { - "version": "3.16.3", - "resolved": "https://registry.npmjs.org/react-modal/-/react-modal-3.16.3.tgz", - "integrity": "sha512-yCYRJB5YkeQDQlTt17WGAgFJ7jr2QYcWa1SHqZ3PluDmnKJ/7+tVU+E6uKyZ0nODaeEj+xCpK4LcSnKXLMC0Nw==", - "dependencies": { - "exenv": "^1.2.0", - "prop-types": "^15.7.2", - "react-lifecycles-compat": "^3.0.0", - "warning": "^4.0.3" - }, - "peerDependencies": { - "react": "^0.14.0 || ^15.0.0 || ^16 || ^17 || ^18 || ^19", - "react-dom": "^0.14.0 || ^15.0.0 || ^16 || ^17 || ^18 || ^19" - } - }, - "node_modules/react-multi-date-picker": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/react-multi-date-picker/-/react-multi-date-picker-4.5.2.tgz", - "integrity": "sha512-FgWjZB3Z6IA6XpcWiLPk85PwcRUhOiYhKK42o5k672gD/n2I6rzPfQ8bUrldOIiF/Z7FfOCdH7a6FeubzqteLg==", - "dependencies": { - "react-date-object": "^2.1.8", - "react-element-popper": "^2.1.6" - }, - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" - } - }, - "node_modules/react-quill": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/react-quill/-/react-quill-2.0.0.tgz", - "integrity": "sha512-4qQtv1FtCfLgoD3PXAur5RyxuUbPXQGOHgTlFie3jtxp43mXDtzCKaOgQ3mLyZfi1PUlyjycfivKelFhy13QUg==", - "dependencies": { - "@types/quill": "^1.3.10", - "lodash": "^4.17.4", - "quill": "^1.3.7" - }, - "peerDependencies": { - "react": "^16 || ^17 || ^18", - "react-dom": "^16 || ^17 || ^18" - } - }, - "node_modules/react-refresh": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", - "integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-router": { - "version": "6.30.2", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.2.tgz", - "integrity": "sha512-H2Bm38Zu1bm8KUE5NVWRMzuIyAV8p/JrOaBJAwVmp37AXG72+CZJlEBw6pdn9i5TBgLMhNDgijS4ZlblpHyWTA==", - "dependencies": { - "@remix-run/router": "1.23.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "react": ">=16.8" - } - }, - "node_modules/react-router-dom": { - "version": "6.30.2", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.2.tgz", - "integrity": "sha512-l2OwHn3UUnEVUqc6/1VMmR1cvZryZ3j3NzapC2eUXO1dB0sYp5mvwdjiXhpUbRb21eFow3qSxpP8Yv6oAU824Q==", - "dependencies": { - "@remix-run/router": "1.23.1", - "react-router": "6.30.2" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "react": ">=16.8", - "react-dom": ">=16.8" - } - }, - "node_modules/react-scripts": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz", - "integrity": "sha512-8VAmEm/ZAwQzJ+GOMLbBsTdDKOpuZh7RPs0UymvBR2vRk4iZWCskjbFnxqjrzoIvlNNRZ3QJFx6/qDSi6zSnaQ==", - "dependencies": { - "@babel/core": "^7.16.0", - "@pmmmwh/react-refresh-webpack-plugin": "^0.5.3", - "@svgr/webpack": "^5.5.0", - "babel-jest": "^27.4.2", - "babel-loader": "^8.2.3", - "babel-plugin-named-asset-import": "^0.3.8", - "babel-preset-react-app": "^10.0.1", - "bfj": "^7.0.2", - "browserslist": "^4.18.1", - "camelcase": "^6.2.1", - "case-sensitive-paths-webpack-plugin": "^2.4.0", - "css-loader": "^6.5.1", - "css-minimizer-webpack-plugin": "^3.2.0", - "dotenv": "^10.0.0", - "dotenv-expand": "^5.1.0", - "eslint": "^8.3.0", - "eslint-config-react-app": "^7.0.1", - "eslint-webpack-plugin": "^3.1.1", - "file-loader": "^6.2.0", - "fs-extra": "^10.0.0", - "html-webpack-plugin": "^5.5.0", - "identity-obj-proxy": "^3.0.0", - "jest": "^27.4.3", - "jest-resolve": "^27.4.2", - "jest-watch-typeahead": "^1.0.0", - "mini-css-extract-plugin": "^2.4.5", - "postcss": "^8.4.4", - "postcss-flexbugs-fixes": "^5.0.2", - "postcss-loader": "^6.2.1", - "postcss-normalize": "^10.0.1", - "postcss-preset-env": "^7.0.1", - "prompts": "^2.4.2", - "react-app-polyfill": "^3.0.0", - "react-dev-utils": "^12.0.1", - "react-refresh": "^0.11.0", - "resolve": "^1.20.0", - "resolve-url-loader": "^4.0.0", - "sass-loader": "^12.3.0", - "semver": "^7.3.5", - "source-map-loader": "^3.0.0", - "style-loader": "^3.3.1", - "tailwindcss": "^3.0.2", - "terser-webpack-plugin": "^5.2.5", - "webpack": "^5.64.4", - "webpack-dev-server": "^4.6.0", - "webpack-manifest-plugin": "^4.0.2", - "workbox-webpack-plugin": "^6.4.1" - }, - "bin": { - "react-scripts": "bin/react-scripts.js" - }, - "engines": { - "node": ">=14.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.2" - }, - "peerDependencies": { - "react": ">= 16", - "typescript": "^3.2.1 || ^4" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/react-scripts/node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/read-cache": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", - "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", - "dependencies": { - "pify": "^2.3.0" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/readdirp/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/recursive-readdir": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", - "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", - "dependencies": { - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/redent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", - "dependencies": { - "indent-string": "^4.0.0", - "strip-indent": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/reflect.getprototypeof": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", - "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", - "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.0.0", - "get-intrinsic": "^1.2.7", - "get-proto": "^1.0.1", - "which-builtin-type": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" - }, - "node_modules/regenerate-unicode-properties": { - "version": "10.2.2", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz", - "integrity": "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==", - "dependencies": { - "regenerate": "^1.4.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" - }, - "node_modules/regex-parser": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.3.1.tgz", - "integrity": "sha512-yXLRqatcCuKtVHsWrNg0JL3l1zGfdXeEvDa0bdu4tCDQw0RpMDZsqbkyRTUnKMR0tXF627V2oEWjBEaEdqTwtQ==" - }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", - "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", - "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" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/regexpu-core": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.4.0.tgz", - "integrity": "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==", - "dependencies": { - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.2.2", - "regjsgen": "^0.8.0", - "regjsparser": "^0.13.0", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.2.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regjsgen": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", - "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==" - }, - "node_modules/regjsparser": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.0.tgz", - "integrity": "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==", - "dependencies": { - "jsesc": "~3.1.0" - }, - "bin": { - "regjsparser": "bin/parser" - } - }, - "node_modules/relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/renderkid": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", - "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", - "dependencies": { - "css-select": "^4.1.3", - "dom-converter": "^0.2.0", - "htmlparser2": "^6.1.0", - "lodash": "^4.17.21", - "strip-ansi": "^6.0.1" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" - }, - "node_modules/resolve": { - "version": "1.22.11", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", - "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", - "dependencies": { - "is-core-module": "^2.16.1", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-url-loader": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-4.0.0.tgz", - "integrity": "sha512-05VEMczVREcbtT7Bz+C+96eUO5HDNvdthIiMB34t7FcF8ehcu4wC0sSgPUubs3XW2Q3CNLJk/BJrCU9wVRymiA==", - "dependencies": { - "adjust-sourcemap-loader": "^4.0.0", - "convert-source-map": "^1.7.0", - "loader-utils": "^2.0.0", - "postcss": "^7.0.35", - "source-map": "0.6.1" - }, - "engines": { - "node": ">=8.9" - }, - "peerDependencies": { - "rework": "1.0.1", - "rework-visit": "1.0.0" - }, - "peerDependenciesMeta": { - "rework": { - "optional": true - }, - "rework-visit": { - "optional": true - } - } - }, - "node_modules/resolve-url-loader/node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" - }, - "node_modules/resolve-url-loader/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/resolve-url-loader/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/resolve-url-loader/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve.exports": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.1.tgz", - "integrity": "sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ==", - "engines": { - "node": ">=10" - } - }, - "node_modules/retry": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/reusify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rollup": { - "version": "2.79.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz", - "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==", - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=10.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/rollup-plugin-terser": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", - "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", - "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser", - "dependencies": { - "@babel/code-frame": "^7.10.4", - "jest-worker": "^26.2.1", - "serialize-javascript": "^4.0.0", - "terser": "^5.0.0" - }, - "peerDependencies": { - "rollup": "^2.0.0" - } - }, - "node_modules/rollup-plugin-terser/node_modules/jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/rollup-plugin-terser/node_modules/serialize-javascript": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", - "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-array-concat": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", - "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.2", - "get-intrinsic": "^1.2.6", - "has-symbols": "^1.1.0", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safe-push-apply": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", - "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", - "dependencies": { - "es-errors": "^1.3.0", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-regex-test": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", - "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "is-regex": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/sanitize.css": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/sanitize.css/-/sanitize.css-13.0.0.tgz", - "integrity": "sha512-ZRwKbh/eQ6w9vmTjkuG0Ioi3HBwPFce0O+v//ve+aOq1oeCy7jMV2qzzAlpsNuqpqCBjjriM1lbtZbF/Q8jVyA==" - }, - "node_modules/sass-loader": { - "version": "12.6.0", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-12.6.0.tgz", - "integrity": "sha512-oLTaH0YCtX4cfnJZxKSLAyglED0naiYfNG1iXfU5w1LNZ+ukoA5DtyDIN5zmKVZwYNJP4KRc5Y3hkWga+7tYfA==", - "dependencies": { - "klona": "^2.0.4", - "neo-async": "^2.6.2" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "fibers": ">= 3.1.0", - "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0", - "sass": "^1.3.0", - "sass-embedded": "*", - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "fibers": { - "optional": true - }, - "node-sass": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - } - } - }, - "node_modules/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" - }, - "node_modules/saxes": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", - "dependencies": { - "xmlchars": "^2.2.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/scheduler": { - "version": "0.23.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", - "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", - "dependencies": { - "loose-envify": "^1.1.0" - } - }, - "node_modules/schema-utils": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", - "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/schema-utils/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/schema-utils/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/schema-utils/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "node_modules/select-hose": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==" - }, - "node_modules/selfsigned": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", - "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", - "dependencies": { - "@types/node-forge": "^1.3.0", - "node-forge": "^1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/send": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.19.1.tgz", - "integrity": "sha512-p4rRk4f23ynFEfcD9LA0xRYngj+IyGiEYyqqOak8kaN0TvNmuxC2dcVeBn62GpCeR2CpWqyHCNScTP91QbAVFg==", - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/send/node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/send/node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", - "dependencies": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/serve-index/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/serve-index/node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-index/node_modules/http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-index/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" - }, - "node_modules/serve-index/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/serve-index/node_modules/setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" - }, - "node_modules/serve-index/node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-static": { - "version": "1.16.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", - "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", - "dependencies": { - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.19.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/serve-static/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/serve-static/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/serve-static/node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/serve-static/node_modules/send": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", - "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/serve-static/node_modules/send/node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/serve-static/node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/set-function-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", - "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/set-proto": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", - "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "engines": { - "node": ">=8" - } - }, - "node_modules/shell-quote": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", - "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", - "side-channel-map": "^1.0.1", - "side-channel-weakmap": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-weakmap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3", - "side-channel-map": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "engines": { - "node": ">=8" - } - }, - "node_modules/sockjs": { - "version": "0.3.24", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", - "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", - "dependencies": { - "faye-websocket": "^0.11.3", - "uuid": "^8.3.2", - "websocket-driver": "^0.7.4" - } - }, - "node_modules/source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" - }, - "node_modules/source-map": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", - "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", - "engines": { - "node": ">= 12" - } - }, - "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-loader": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-3.0.2.tgz", - "integrity": "sha512-BokxPoLjyl3iOrgkWaakaxqnelAJSS+0V+De0kKIq6lyWrXuiPgYTGp6z3iHmqljKAaLXwZa+ctD8GccRJeVvg==", - "dependencies": { - "abab": "^2.0.5", - "iconv-lite": "^0.6.3", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sourcemap-codec": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", - "deprecated": "Please use @jridgewell/sourcemap-codec instead" - }, - "node_modules/spdy": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", - "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", - "dependencies": { - "debug": "^4.1.0", - "handle-thing": "^2.0.0", - "http-deceiver": "^1.2.7", - "select-hose": "^2.0.0", - "spdy-transport": "^3.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/spdy-transport": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", - "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", - "dependencies": { - "debug": "^4.1.0", - "detect-node": "^2.0.4", - "hpack.js": "^2.1.6", - "obuf": "^1.1.2", - "readable-stream": "^3.0.6", - "wbuf": "^1.7.3" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" - }, - "node_modules/stable": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", - "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility" - }, - "node_modules/stack-utils": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", - "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "engines": { - "node": ">=8" - } - }, - "node_modules/stackframe": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", - "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==" - }, - "node_modules/static-eval": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.0.2.tgz", - "integrity": "sha512-N/D219Hcr2bPjLxPiV+TQE++Tsmrady7TqAJugLy7Xk1EumfDWS/f5dtBbkRCGE7wKKXuYockQoj8Rm2/pVKyg==", - "dependencies": { - "escodegen": "^1.8.1" - } - }, - "node_modules/static-eval/node_modules/escodegen": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", - "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", - "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=4.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, - "node_modules/static-eval/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/static-eval/node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/static-eval/node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/static-eval/node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/static-eval/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-eval/node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/statuses": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", - "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/stop-iteration-iterator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", - "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", - "dependencies": { - "es-errors": "^1.3.0", - "internal-slot": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/string-natural-compare": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/string-natural-compare/-/string-natural-compare-3.0.1.tgz", - "integrity": "sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==" - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/string.prototype.includes": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz", - "integrity": "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.3" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/string.prototype.matchall": { - "version": "4.0.12", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", - "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.6", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.6", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "internal-slot": "^1.1.0", - "regexp.prototype.flags": "^1.5.3", - "set-function-name": "^2.0.2", - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.repeat": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", - "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", - "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "node_modules/string.prototype.trim": { - "version": "1.2.10", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", - "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.2", - "define-data-property": "^1.1.4", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.5", - "es-object-atoms": "^1.0.0", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", - "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.2", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", - "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/stringify-object": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", - "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", - "dependencies": { - "get-own-enumerable-property-symbols": "^3.0.0", - "is-obj": "^1.0.1", - "is-regexp": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz", - "integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==", - "engines": { - "node": ">=10" - } - }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", - "dependencies": { - "min-indent": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/style-loader": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.4.tgz", - "integrity": "sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w==", - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - } - }, - "node_modules/stylehacks": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz", - "integrity": "sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==", - "dependencies": { - "browserslist": "^4.21.4", - "postcss-selector-parser": "^6.0.4" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/sucrase": { - "version": "3.35.1", - "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.1.tgz", - "integrity": "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.2", - "commander": "^4.0.0", - "lines-and-columns": "^1.1.6", - "mz": "^2.7.0", - "pirates": "^4.0.1", - "tinyglobby": "^0.2.11", - "ts-interface-checker": "^0.1.9" - }, - "bin": { - "sucrase": "bin/sucrase", - "sucrase-node": "bin/sucrase-node" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/sucrase/node_modules/commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-hyperlinks": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", - "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", - "dependencies": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/svg-parser": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", - "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==" - }, - "node_modules/svgo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", - "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", - "deprecated": "This SVGO version is no longer supported. Upgrade to v2.x.x.", - "dependencies": { - "chalk": "^2.4.1", - "coa": "^2.0.2", - "css-select": "^2.0.0", - "css-select-base-adapter": "^0.1.1", - "css-tree": "1.0.0-alpha.37", - "csso": "^4.0.2", - "js-yaml": "^3.13.1", - "mkdirp": "~0.5.1", - "object.values": "^1.1.0", - "sax": "~1.2.4", - "stable": "^0.1.8", - "unquote": "~1.1.1", - "util.promisify": "~1.0.0" - }, - "bin": { - "svgo": "bin/svgo" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/svgo/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/svgo/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/svgo/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/svgo/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "node_modules/svgo/node_modules/css-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", - "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^3.2.1", - "domutils": "^1.7.0", - "nth-check": "^1.0.2" - } - }, - "node_modules/svgo/node_modules/css-what": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", - "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==", - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/svgo/node_modules/dom-serializer": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", - "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", - "dependencies": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - } - }, - "node_modules/svgo/node_modules/domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "dependencies": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "node_modules/svgo/node_modules/domutils/node_modules/domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" - }, - "node_modules/svgo/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/svgo/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "engines": { - "node": ">=4" - } - }, - "node_modules/svgo/node_modules/nth-check": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", - "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", - "dependencies": { - "boolbase": "~1.0.0" - } - }, - "node_modules/svgo/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" - }, - "node_modules/tailwindcss": { - "version": "3.4.19", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.19.tgz", - "integrity": "sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==", - "dependencies": { - "@alloc/quick-lru": "^5.2.0", - "arg": "^5.0.2", - "chokidar": "^3.6.0", - "didyoumean": "^1.2.2", - "dlv": "^1.1.3", - "fast-glob": "^3.3.2", - "glob-parent": "^6.0.2", - "is-glob": "^4.0.3", - "jiti": "^1.21.7", - "lilconfig": "^3.1.3", - "micromatch": "^4.0.8", - "normalize-path": "^3.0.0", - "object-hash": "^3.0.0", - "picocolors": "^1.1.1", - "postcss": "^8.4.47", - "postcss-import": "^15.1.0", - "postcss-js": "^4.0.1", - "postcss-load-config": "^4.0.2 || ^5.0 || ^6.0", - "postcss-nested": "^6.2.0", - "postcss-selector-parser": "^6.1.2", - "resolve": "^1.22.8", - "sucrase": "^3.35.0" - }, - "bin": { - "tailwind": "lib/cli.js", - "tailwindcss": "lib/cli.js" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/tailwindcss/node_modules/lilconfig": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", - "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antonk52" - } - }, - "node_modules/tailwindcss/node_modules/postcss-load-config": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz", - "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "lilconfig": "^3.1.1" - }, - "engines": { - "node": ">= 18" - }, - "peerDependencies": { - "jiti": ">=1.21.0", - "postcss": ">=8.0.9", - "tsx": "^4.8.1", - "yaml": "^2.4.2" - }, - "peerDependenciesMeta": { - "jiti": { - "optional": true - }, - "postcss": { - "optional": true - }, - "tsx": { - "optional": true - }, - "yaml": { - "optional": true - } - } - }, - "node_modules/tailwindcss/node_modules/yaml": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz", - "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", - "optional": true, - "peer": true, - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14.6" - }, - "funding": { - "url": "https://github.com/sponsors/eemeli" - } - }, - "node_modules/tapable": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", - "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", - "engines": { - "node": ">=6" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/temp-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", - "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/tempy": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.6.0.tgz", - "integrity": "sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==", - "dependencies": { - "is-stream": "^2.0.0", - "temp-dir": "^2.0.0", - "type-fest": "^0.16.0", - "unique-string": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/tempy/node_modules/type-fest": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", - "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", - "dependencies": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/terser": { - "version": "5.44.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.44.1.tgz", - "integrity": "sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw==", - "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.15.0", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/terser-webpack-plugin": { - "version": "5.3.16", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.16.tgz", - "integrity": "sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.25", - "jest-worker": "^27.4.5", - "schema-utils": "^4.3.0", - "serialize-javascript": "^6.0.2", - "terser": "^5.31.1" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "uglify-js": { - "optional": true - } - } - }, - "node_modules/terser/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" - }, - "node_modules/thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "dependencies": { - "any-promise": "^1.0.0" - } - }, - "node_modules/thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", - "dependencies": { - "thenify": ">= 3.1.0 < 4" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/throat": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.2.tgz", - "integrity": "sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ==" - }, - "node_modules/thunky": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", - "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" - }, - "node_modules/tiny-case": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tiny-case/-/tiny-case-1.0.3.tgz", - "integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==" - }, - "node_modules/tinyglobby": { - "version": "0.2.15", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", - "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", - "dependencies": { - "fdir": "^6.5.0", - "picomatch": "^4.0.3" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/SuperchupuDev" - } - }, - "node_modules/tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==" - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/toposort": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz", - "integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==" - }, - "node_modules/tough-cookie": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", - "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", - "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tough-cookie/node_modules/universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", - "dependencies": { - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/tryer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", - "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==" - }, - "node_modules/ts-interface-checker": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", - "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" - }, - "node_modules/tsconfig-paths": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", - "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/tsconfig-paths/node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" - }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - } - }, - "node_modules/tsutils/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typed-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", - "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", - "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "is-typed-array": "^1.1.14" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/typed-array-byte-length": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", - "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", - "dependencies": { - "call-bind": "^1.0.8", - "for-each": "^0.3.3", - "gopd": "^1.2.0", - "has-proto": "^1.2.0", - "is-typed-array": "^1.1.14" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", - "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.8", - "for-each": "^0.3.3", - "gopd": "^1.2.0", - "has-proto": "^1.2.0", - "is-typed-array": "^1.1.15", - "reflect.getprototypeof": "^1.0.9" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-length": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", - "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0", - "reflect.getprototypeof": "^1.0.6" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/unbox-primitive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", - "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", - "dependencies": { - "call-bound": "^1.0.3", - "has-bigints": "^1.0.2", - "has-symbols": "^1.1.0", - "which-boxed-primitive": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/underscore": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", - "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==" - }, - "node_modules/undici-types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", - "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==" - }, - "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", - "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "dependencies": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz", - "integrity": "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==", - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-property-aliases-ecmascript": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz", - "integrity": "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/unique-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", - "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "dependencies": { - "crypto-random-string": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/unquote": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", - "integrity": "sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==" - }, - "node_modules/upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "engines": { - "node": ">=4", - "yarn": "*" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.2.tgz", - "integrity": "sha512-E85pfNzMQ9jpKkA7+TJAi4TJN+tBCuWh5rUcS/sv6cFi+1q9LYDwDI5dpUL0u/73EElyQ8d3TEaeW4sPedBqYA==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "dependencies": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "node_modules/util.promisify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", - "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", - "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.2", - "has-symbols": "^1.0.1", - "object.getownpropertydescriptors": "^2.1.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/utila": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==" - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/v8-to-istanbul": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", - "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" - }, - "engines": { - "node": ">=10.12.0" - } - }, - "node_modules/v8-to-istanbul/node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/w3c-hr-time": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", - "deprecated": "Use your platform's native performance.now() and performance.timeOrigin.", - "dependencies": { - "browser-process-hrtime": "^1.0.0" - } - }, - "node_modules/w3c-xmlserializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", - "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", - "dependencies": { - "xml-name-validator": "^3.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "dependencies": { - "makeerror": "1.0.12" - } - }, - "node_modules/warning": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", - "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", - "dependencies": { - "loose-envify": "^1.0.0" - } - }, - "node_modules/watchpack": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz", - "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==", - "dependencies": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/wbuf": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", - "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", - "dependencies": { - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/web-vitals": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-2.1.4.tgz", - "integrity": "sha512-sVWcwhU5mX6crfI5Vd2dC4qchyTqxV8URinzt25XqVh+bHEPGH4C3NPrNionCP7Obx59wrYEbNlw4Z8sjALzZg==" - }, - "node_modules/webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", - "engines": { - "node": ">=10.4" - } - }, - "node_modules/webpack": { - "version": "5.103.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.103.0.tgz", - "integrity": "sha512-HU1JOuV1OavsZ+mfigY0j8d1TgQgbZ6M+J75zDkpEAwYeXjWSqrGJtgnPblJjd/mAyTNQ7ygw0MiKOn6etz8yw==", - "dependencies": { - "@types/eslint-scope": "^3.7.7", - "@types/estree": "^1.0.8", - "@types/json-schema": "^7.0.15", - "@webassemblyjs/ast": "^1.14.1", - "@webassemblyjs/wasm-edit": "^1.14.1", - "@webassemblyjs/wasm-parser": "^1.14.1", - "acorn": "^8.15.0", - "acorn-import-phases": "^1.0.3", - "browserslist": "^4.26.3", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.3", - "es-module-lexer": "^1.2.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.11", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.3.1", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^4.3.3", - "tapable": "^2.3.0", - "terser-webpack-plugin": "^5.3.11", - "watchpack": "^2.4.4", - "webpack-sources": "^3.3.3" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-dev-middleware": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", - "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", - "dependencies": { - "colorette": "^2.0.10", - "memfs": "^3.4.3", - "mime-types": "^2.1.31", - "range-parser": "^1.2.1", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/webpack-dev-server": { - "version": "4.15.2", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.2.tgz", - "integrity": "sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g==", - "dependencies": { - "@types/bonjour": "^3.5.9", - "@types/connect-history-api-fallback": "^1.3.5", - "@types/express": "^4.17.13", - "@types/serve-index": "^1.9.1", - "@types/serve-static": "^1.13.10", - "@types/sockjs": "^0.3.33", - "@types/ws": "^8.5.5", - "ansi-html-community": "^0.0.8", - "bonjour-service": "^1.0.11", - "chokidar": "^3.5.3", - "colorette": "^2.0.10", - "compression": "^1.7.4", - "connect-history-api-fallback": "^2.0.0", - "default-gateway": "^6.0.3", - "express": "^4.17.3", - "graceful-fs": "^4.2.6", - "html-entities": "^2.3.2", - "http-proxy-middleware": "^2.0.3", - "ipaddr.js": "^2.0.1", - "launch-editor": "^2.6.0", - "open": "^8.0.9", - "p-retry": "^4.5.0", - "rimraf": "^3.0.2", - "schema-utils": "^4.0.0", - "selfsigned": "^2.1.1", - "serve-index": "^1.9.1", - "sockjs": "^0.3.24", - "spdy": "^4.0.2", - "webpack-dev-middleware": "^5.3.4", - "ws": "^8.13.0" - }, - "bin": { - "webpack-dev-server": "bin/webpack-dev-server.js" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.37.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "webpack": { - "optional": true - }, - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-dev-server/node_modules/ws": { - "version": "8.18.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", - "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/webpack-manifest-plugin": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/webpack-manifest-plugin/-/webpack-manifest-plugin-4.1.1.tgz", - "integrity": "sha512-YXUAwxtfKIJIKkhg03MKuiFAD72PlrqCiwdwO4VEXdRO5V0ORCNwaOwAZawPZalCbmH9kBDmXnNeQOw+BIEiow==", - "dependencies": { - "tapable": "^2.0.0", - "webpack-sources": "^2.2.0" - }, - "engines": { - "node": ">=12.22.0" - }, - "peerDependencies": { - "webpack": "^4.44.2 || ^5.47.0" - } - }, - "node_modules/webpack-manifest-plugin/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack-manifest-plugin/node_modules/webpack-sources": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.1.tgz", - "integrity": "sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA==", - "dependencies": { - "source-list-map": "^2.0.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/webpack-sources": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", - "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/webpack/node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/webpack/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "dependencies": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "dependencies": { - "iconv-lite": "0.4.24" - } - }, - "node_modules/whatwg-encoding/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/whatwg-fetch": { - "version": "3.6.20", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", - "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==" - }, - "node_modules/whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" - }, - "node_modules/whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", - "dependencies": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-boxed-primitive": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", - "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", - "dependencies": { - "is-bigint": "^1.1.0", - "is-boolean-object": "^1.2.1", - "is-number-object": "^1.1.1", - "is-string": "^1.1.1", - "is-symbol": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-builtin-type": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", - "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", - "dependencies": { - "call-bound": "^1.0.2", - "function.prototype.name": "^1.1.6", - "has-tostringtag": "^1.0.2", - "is-async-function": "^2.0.0", - "is-date-object": "^1.1.0", - "is-finalizationregistry": "^1.1.0", - "is-generator-function": "^1.0.10", - "is-regex": "^1.2.1", - "is-weakref": "^1.0.2", - "isarray": "^2.0.5", - "which-boxed-primitive": "^1.1.0", - "which-collection": "^1.0.2", - "which-typed-array": "^1.1.16" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-collection": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", - "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", - "dependencies": { - "is-map": "^2.0.3", - "is-set": "^2.0.3", - "is-weakmap": "^2.0.2", - "is-weakset": "^2.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.19", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", - "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", - "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" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/workbox-background-sync": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.6.0.tgz", - "integrity": "sha512-jkf4ZdgOJxC9u2vztxLuPT/UjlH7m/nWRQ/MgGL0v8BJHoZdVGJd18Kck+a0e55wGXdqyHO+4IQTk0685g4MUw==", - "dependencies": { - "idb": "^7.0.1", - "workbox-core": "6.6.0" - } - }, - "node_modules/workbox-broadcast-update": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-6.6.0.tgz", - "integrity": "sha512-nm+v6QmrIFaB/yokJmQ/93qIJ7n72NICxIwQwe5xsZiV2aI93MGGyEyzOzDPVz5THEr5rC3FJSsO3346cId64Q==", - "dependencies": { - "workbox-core": "6.6.0" - } - }, - "node_modules/workbox-build": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-6.6.0.tgz", - "integrity": "sha512-Tjf+gBwOTuGyZwMz2Nk/B13Fuyeo0Q84W++bebbVsfr9iLkDSo6j6PST8tET9HYA58mlRXwlMGpyWO8ETJiXdQ==", - "dependencies": { - "@apideck/better-ajv-errors": "^0.3.1", - "@babel/core": "^7.11.1", - "@babel/preset-env": "^7.11.0", - "@babel/runtime": "^7.11.2", - "@rollup/plugin-babel": "^5.2.0", - "@rollup/plugin-node-resolve": "^11.2.1", - "@rollup/plugin-replace": "^2.4.1", - "@surma/rollup-plugin-off-main-thread": "^2.2.3", - "ajv": "^8.6.0", - "common-tags": "^1.8.0", - "fast-json-stable-stringify": "^2.1.0", - "fs-extra": "^9.0.1", - "glob": "^7.1.6", - "lodash": "^4.17.20", - "pretty-bytes": "^5.3.0", - "rollup": "^2.43.1", - "rollup-plugin-terser": "^7.0.0", - "source-map": "^0.8.0-beta.0", - "stringify-object": "^3.3.0", - "strip-comments": "^2.0.1", - "tempy": "^0.6.0", - "upath": "^1.2.0", - "workbox-background-sync": "6.6.0", - "workbox-broadcast-update": "6.6.0", - "workbox-cacheable-response": "6.6.0", - "workbox-core": "6.6.0", - "workbox-expiration": "6.6.0", - "workbox-google-analytics": "6.6.0", - "workbox-navigation-preload": "6.6.0", - "workbox-precaching": "6.6.0", - "workbox-range-requests": "6.6.0", - "workbox-recipes": "6.6.0", - "workbox-routing": "6.6.0", - "workbox-strategies": "6.6.0", - "workbox-streams": "6.6.0", - "workbox-sw": "6.6.0", - "workbox-window": "6.6.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/workbox-build/node_modules/@apideck/better-ajv-errors": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz", - "integrity": "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==", - "dependencies": { - "json-schema": "^0.4.0", - "jsonpointer": "^5.0.0", - "leven": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "ajv": ">=8" - } - }, - "node_modules/workbox-build/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/workbox-build/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/workbox-build/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "node_modules/workbox-build/node_modules/source-map": { - "version": "0.8.0-beta.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", - "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", - "deprecated": "The work that was done in this beta branch won't be included in future versions", - "dependencies": { - "whatwg-url": "^7.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/workbox-build/node_modules/tr46": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", - "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/workbox-build/node_modules/webidl-conversions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", - "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" - }, - "node_modules/workbox-build/node_modules/whatwg-url": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", - "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", - "dependencies": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" - } - }, - "node_modules/workbox-cacheable-response": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-6.6.0.tgz", - "integrity": "sha512-JfhJUSQDwsF1Xv3EV1vWzSsCOZn4mQ38bWEBR3LdvOxSPgB65gAM6cS2CX8rkkKHRgiLrN7Wxoyu+TuH67kHrw==", - "deprecated": "workbox-background-sync@6.6.0", - "dependencies": { - "workbox-core": "6.6.0" - } - }, - "node_modules/workbox-core": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.6.0.tgz", - "integrity": "sha512-GDtFRF7Yg3DD859PMbPAYPeJyg5gJYXuBQAC+wyrWuuXgpfoOrIQIvFRZnQ7+czTIQjIr1DhLEGFzZanAT/3bQ==" - }, - "node_modules/workbox-expiration": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-6.6.0.tgz", - "integrity": "sha512-baplYXcDHbe8vAo7GYvyAmlS4f6998Jff513L4XvlzAOxcl8F620O91guoJ5EOf5qeXG4cGdNZHkkVAPouFCpw==", - "dependencies": { - "idb": "^7.0.1", - "workbox-core": "6.6.0" - } - }, - "node_modules/workbox-google-analytics": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-6.6.0.tgz", - "integrity": "sha512-p4DJa6OldXWd6M9zRl0H6vB9lkrmqYFkRQ2xEiNdBFp9U0LhsGO7hsBscVEyH9H2/3eZZt8c97NB2FD9U2NJ+Q==", - "deprecated": "It is not compatible with newer versions of GA starting with v4, as long as you are using GAv3 it should be ok, but the package is not longer being maintained", - "dependencies": { - "workbox-background-sync": "6.6.0", - "workbox-core": "6.6.0", - "workbox-routing": "6.6.0", - "workbox-strategies": "6.6.0" - } - }, - "node_modules/workbox-navigation-preload": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-6.6.0.tgz", - "integrity": "sha512-utNEWG+uOfXdaZmvhshrh7KzhDu/1iMHyQOV6Aqup8Mm78D286ugu5k9MFD9SzBT5TcwgwSORVvInaXWbvKz9Q==", - "dependencies": { - "workbox-core": "6.6.0" - } - }, - "node_modules/workbox-precaching": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-6.6.0.tgz", - "integrity": "sha512-eYu/7MqtRZN1IDttl/UQcSZFkHP7dnvr/X3Vn6Iw6OsPMruQHiVjjomDFCNtd8k2RdjLs0xiz9nq+t3YVBcWPw==", - "dependencies": { - "workbox-core": "6.6.0", - "workbox-routing": "6.6.0", - "workbox-strategies": "6.6.0" - } - }, - "node_modules/workbox-range-requests": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-6.6.0.tgz", - "integrity": "sha512-V3aICz5fLGq5DpSYEU8LxeXvsT//mRWzKrfBOIxzIdQnV/Wj7R+LyJVTczi4CQ4NwKhAaBVaSujI1cEjXW+hTw==", - "dependencies": { - "workbox-core": "6.6.0" - } - }, - "node_modules/workbox-recipes": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-6.6.0.tgz", - "integrity": "sha512-TFi3kTgYw73t5tg73yPVqQC8QQjxJSeqjXRO4ouE/CeypmP2O/xqmB/ZFBBQazLTPxILUQ0b8aeh0IuxVn9a6A==", - "dependencies": { - "workbox-cacheable-response": "6.6.0", - "workbox-core": "6.6.0", - "workbox-expiration": "6.6.0", - "workbox-precaching": "6.6.0", - "workbox-routing": "6.6.0", - "workbox-strategies": "6.6.0" - } - }, - "node_modules/workbox-routing": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.6.0.tgz", - "integrity": "sha512-x8gdN7VDBiLC03izAZRfU+WKUXJnbqt6PG9Uh0XuPRzJPpZGLKce/FkOX95dWHRpOHWLEq8RXzjW0O+POSkKvw==", - "dependencies": { - "workbox-core": "6.6.0" - } - }, - "node_modules/workbox-strategies": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.6.0.tgz", - "integrity": "sha512-eC07XGuINAKUWDnZeIPdRdVja4JQtTuc35TZ8SwMb1ztjp7Ddq2CJ4yqLvWzFWGlYI7CG/YGqaETntTxBGdKgQ==", - "dependencies": { - "workbox-core": "6.6.0" - } - }, - "node_modules/workbox-streams": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-6.6.0.tgz", - "integrity": "sha512-rfMJLVvwuED09CnH1RnIep7L9+mj4ufkTyDPVaXPKlhi9+0czCu+SJggWCIFbPpJaAZmp2iyVGLqS3RUmY3fxg==", - "dependencies": { - "workbox-core": "6.6.0", - "workbox-routing": "6.6.0" - } - }, - "node_modules/workbox-sw": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-6.6.0.tgz", - "integrity": "sha512-R2IkwDokbtHUE4Kus8pKO5+VkPHD2oqTgl+XJwh4zbF1HyjAbgNmK/FneZHVU7p03XUt9ICfuGDYISWG9qV/CQ==" - }, - "node_modules/workbox-webpack-plugin": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-webpack-plugin/-/workbox-webpack-plugin-6.6.0.tgz", - "integrity": "sha512-xNZIZHalboZU66Wa7x1YkjIqEy1gTR+zPM+kjrYJzqN7iurYZBctBLISyScjhkJKYuRrZUP0iqViZTh8rS0+3A==", - "dependencies": { - "fast-json-stable-stringify": "^2.1.0", - "pretty-bytes": "^5.4.1", - "upath": "^1.2.0", - "webpack-sources": "^1.4.3", - "workbox-build": "6.6.0" - }, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "webpack": "^4.4.0 || ^5.9.0" - } - }, - "node_modules/workbox-webpack-plugin/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/workbox-webpack-plugin/node_modules/webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dependencies": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "node_modules/workbox-window": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-6.6.0.tgz", - "integrity": "sha512-L4N9+vka17d16geaJXXRjENLFldvkWy7JyGxElRD0JvBxvFEd8LOhr+uXCcar/NzAmIBRv9EZ+M+Qr4mOoBITw==", - "dependencies": { - "@types/trusted-types": "^2.0.2", - "workbox-core": "6.6.0" - } - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" - }, - "node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "node_modules/ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" - }, - "node_modules/xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - }, - "node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "engines": { - "node": ">=10" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yup": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/yup/-/yup-1.7.1.tgz", - "integrity": "sha512-GKHFX2nXul2/4Dtfxhozv701jLQHdf6J34YDh2cEkpqoo8le5Mg6/LrdseVLrFarmFygZTlfIhHx/QKfb/QWXw==", - "dependencies": { - "property-expr": "^2.0.5", - "tiny-case": "^1.0.3", - "toposort": "^2.0.2", - "type-fest": "^2.19.0" - } - }, - "node_modules/yup/node_modules/type-fest": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/public/modstagram_panel/package.json b/public/modstagram_panel/package.json deleted file mode 100644 index 2521215..0000000 --- a/public/modstagram_panel/package.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "name": "modstagram_panel", - "version": "0.1.0", - "private": true, - "dependencies": { - "@testing-library/jest-dom": "^5.17.0", - "@testing-library/react": "^13.4.0", - "@testing-library/user-event": "^13.5.0", - "axios": "^1.6.8", - "js-cookie": "^3.0.5", - "moment-jalaali": "^0.10.4", - "react": "^18.3.1", - "react-dom": "^18.3.1", - "react-hot-toast": "^2.4.1", - "react-icons": "^5.5.0", - "react-modal": "^3.16.1", - "react-multi-date-picker": "^4.5.2", - "react-quill": "^2.0.0", - "react-router-dom": "^6.23.1", - "react-scripts": "5.0.1", - "web-vitals": "^2.1.4", - "yup": "^1.4.0" - }, - "scripts": { - "start": "BROWSER=none react-scripts start", - "build": "GENERATE_SOURCEMAP=false react-scripts build", - "build:no-cache": "GENERATE_SOURCEMAP=false INLINE_RUNTIME_CHUNK=false react-scripts build", - "test": "react-scripts test", - "eject": "react-scripts eject" - }, - "eslintConfig": { - "extends": [ - "react-app", - "react-app/jest" - ] - }, - "browserslist": { - "production": [ - ">0.2%", - "not dead", - "not op_mini all" - ], - "development": [ - "last 1 chrome version", - "last 1 firefox version", - "last 1 safari version" - ] - }, - "devDependencies": { - "@babel/plugin-proposal-private-property-in-object": "^7.21.11", - "tailwindcss": "^3.4.3" - } -} diff --git a/public/modstagram_panel/public/favicon.ico b/public/modstagram_panel/public/favicon.ico deleted file mode 100644 index 596b2ec..0000000 Binary files a/public/modstagram_panel/public/favicon.ico and /dev/null differ diff --git a/public/modstagram_panel/public/fonts/KalamehWeb-Medium.woff b/public/modstagram_panel/public/fonts/KalamehWeb-Medium.woff deleted file mode 100644 index 583f1f3..0000000 Binary files a/public/modstagram_panel/public/fonts/KalamehWeb-Medium.woff and /dev/null differ diff --git a/public/modstagram_panel/public/fonts/KalamehWeb-Regular.woff b/public/modstagram_panel/public/fonts/KalamehWeb-Regular.woff deleted file mode 100644 index b258ec9..0000000 Binary files a/public/modstagram_panel/public/fonts/KalamehWeb-Regular.woff and /dev/null differ diff --git a/public/modstagram_panel/public/fonts/KalamehWeb-SemiBold.woff b/public/modstagram_panel/public/fonts/KalamehWeb-SemiBold.woff deleted file mode 100644 index d1f1e84..0000000 Binary files a/public/modstagram_panel/public/fonts/KalamehWeb-SemiBold.woff and /dev/null differ diff --git a/public/modstagram_panel/public/index.html b/public/modstagram_panel/public/index.html deleted file mode 100644 index d58709e..0000000 --- a/public/modstagram_panel/public/index.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - مدستاگرام | پنل مدیریت - - - -
- - diff --git a/public/modstagram_panel/public/logo192.png b/public/modstagram_panel/public/logo192.png deleted file mode 100644 index fc44b0a..0000000 Binary files a/public/modstagram_panel/public/logo192.png and /dev/null differ diff --git a/public/modstagram_panel/public/logo512.png b/public/modstagram_panel/public/logo512.png deleted file mode 100644 index a4e47a6..0000000 Binary files a/public/modstagram_panel/public/logo512.png and /dev/null differ diff --git a/public/modstagram_panel/public/manifest.json b/public/modstagram_panel/public/manifest.json deleted file mode 100644 index 080d6c7..0000000 --- a/public/modstagram_panel/public/manifest.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "short_name": "React App", - "name": "Create React App Sample", - "icons": [ - { - "src": "favicon.ico", - "sizes": "64x64 32x32 24x24 16x16", - "type": "image/x-icon" - }, - { - "src": "logo192.png", - "type": "image/png", - "sizes": "192x192" - }, - { - "src": "logo512.png", - "type": "image/png", - "sizes": "512x512" - } - ], - "start_url": ".", - "display": "standalone", - "theme_color": "#000000", - "background_color": "#ffffff" -} diff --git a/public/modstagram_panel/public/robots.txt b/public/modstagram_panel/public/robots.txt deleted file mode 100644 index e9e57dc..0000000 --- a/public/modstagram_panel/public/robots.txt +++ /dev/null @@ -1,3 +0,0 @@ -# https://www.robotstxt.org/robotstxt.html -User-agent: * -Disallow: diff --git a/public/modstagram_panel/src/App.jsx b/public/modstagram_panel/src/App.jsx deleted file mode 100644 index 4109f71..0000000 --- a/public/modstagram_panel/src/App.jsx +++ /dev/null @@ -1,17 +0,0 @@ -import { RouterProvider } from "react-router-dom"; -import AuthProvider from "./utils/AuthProvider"; -import { Toaster } from "react-hot-toast"; -import { router } from "./routers/appRoutes"; - -function App() { - return ( -
- - - - -
- ); -} - -export default App; diff --git a/public/modstagram_panel/src/assets/css/index.css b/public/modstagram_panel/src/assets/css/index.css deleted file mode 100644 index 9ae09b3..0000000 --- a/public/modstagram_panel/src/assets/css/index.css +++ /dev/null @@ -1,166 +0,0 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; - -@font-face { - font-family: Kalameh; - src: url("/public/fonts/KalamehWeb-Regular.woff"); -} -@font-face { - font-family: KalamehMed; - src: url("/public/fonts/KalamehWeb-Medium.woff"); -} -@font-face { - font-family: KalamehSemi; - src: url("/public/fonts/KalamehWeb-SemiBold.woff"); -} - -html { - scroll-behavior: smooth; -} - -.hide-scrollbar { - -ms-overflow-style: none; - scrollbar-width: none; -} - -.hide-scrollbar::-webkit-scrollbar { - display: none; -} -.datePickerStyle { - width: 100%; - background-color: black; -} -button, -button:focus, -textarea { - outline: none; -} - -input:focus, -button:focus, -select:focus { - outline: none; -} - -input::-webkit-outer-spin-button, -input::-webkit-inner-spin-button { - -webkit-appearance: none; - margin: 0; -} - -/* Firefox */ -input[type="number"] { - -moz-appearance: textfield; -} -* { - font-family: "kalameh" !important; -} - -body { - margin: 0; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", - "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", - sans-serif; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - direction: rtl; - background-color: #252525; -} -code { - font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", - monospace; -} -.dir-ltr { - direction: ltr; -} -.big-circle { - position: fixed; - top: 60vh; /* 30vh پایین‌تر از پایین صفحه */ - left: 50%; /* در وسط صفحه افقی */ - transform: translateX(-50%); /* تنظیم موقعیت در وسط صفحه افقی */ - width: 170vw; /* عرض بیشتر از عرض صفحه */ - height: 100vw; /* ارتفاع برابر با عرض بیشتر از عرض صفحه */ - border-radius: 50%; /* تبدیل به دایره */ - background-color: #fff; /* رنگ پس‌زمینه */ - z-index: 15; -} -.bg-glass { - box-shadow: 0px 4px 12px 0px #00000040; - background-color: #ffffffa2; -} -.purple-line { - width: 200px; - height: 1px; - background: linear-gradient(to right, #f9f2fb 0%, #482d4f 100%); -} -.bg-glass-absolute { - width: 101%; - height: 110%; - box-shadow: 0px 4px 12px 0px #00000040; - background-color: #e9e9e99c; - position: absolute; - bottom: -20px; - border-radius: 20px; - z-index: 99; - display: flex; - align-items: center; - justify-content: center; - left: 50%; - transform: translateX(-50%); -} -.ql-container, -.ql-editor { - min-height: 400px; - color: #fff !important; - text-align: right !important; -} -.ql-editor.ql-blank::before { - color: #fff !important; -} - -.rmdp-input { - border-color: #dee2e6 !important; - width: 130px !important; - height: 48px !important; - padding-right: 16px !important; - color: #111; -} -@media (min-width: 640px) { - .container { - max-width: 640px; - } -} - -@media (min-width: 768px) { - .container { - max-width: 768px; - } -} - -@media (min-width: 1024px) { - .container { - max-width: 1024px; - } -} - -@media (min-width: 1280px) { - .container { - max-width: 1170px; - } -} -@media (min-width: 1400px) { - .container { - max-width: 1300px; - } -} -@media (min-width: 1500px) { - .container { - max-width: 1400px; - } -} -@media (min-width: 1636px) { - .container { - max-width: 1650px; - } -} diff --git a/public/modstagram_panel/src/assets/icons/AdvertisingIcon.jsx b/public/modstagram_panel/src/assets/icons/AdvertisingIcon.jsx deleted file mode 100644 index 5d583be..0000000 --- a/public/modstagram_panel/src/assets/icons/AdvertisingIcon.jsx +++ /dev/null @@ -1,15 +0,0 @@ -import React from "react"; - -function AdvertisingIcon(props) { - return ( - - - - - - - ); -} - -export default AdvertisingIcon; diff --git a/public/modstagram_panel/src/assets/icons/CommentsIcon.jsx b/public/modstagram_panel/src/assets/icons/CommentsIcon.jsx deleted file mode 100644 index 9f33f1f..0000000 --- a/public/modstagram_panel/src/assets/icons/CommentsIcon.jsx +++ /dev/null @@ -1,18 +0,0 @@ -import React from "react"; - -function CommentsIcon(props) { - return ( - - - - - - - - - - ); -} - -export default CommentsIcon; diff --git a/public/modstagram_panel/src/assets/icons/FinancialsIcon.jsx b/public/modstagram_panel/src/assets/icons/FinancialsIcon.jsx deleted file mode 100644 index fa68ab3..0000000 --- a/public/modstagram_panel/src/assets/icons/FinancialsIcon.jsx +++ /dev/null @@ -1,18 +0,0 @@ -import React from "react"; - -function FinancialsIcon(props) { - return ( - - - - - - - - - - ); -} - -export default FinancialsIcon; diff --git a/public/modstagram_panel/src/assets/icons/PostsIcon.jsx b/public/modstagram_panel/src/assets/icons/PostsIcon.jsx deleted file mode 100644 index 3d45171..0000000 --- a/public/modstagram_panel/src/assets/icons/PostsIcon.jsx +++ /dev/null @@ -1,16 +0,0 @@ -import React from "react"; - -function PostsIcon(props) { - return ( - - - - - - - - ); -} - -export default PostsIcon; diff --git a/public/modstagram_panel/src/assets/icons/ProjectsIcon.jsx b/public/modstagram_panel/src/assets/icons/ProjectsIcon.jsx deleted file mode 100644 index bd6e07e..0000000 --- a/public/modstagram_panel/src/assets/icons/ProjectsIcon.jsx +++ /dev/null @@ -1,17 +0,0 @@ -import React from "react"; - -function ProjectsIcon(props) { - return ( - - - - - - - - ); -} - -export default ProjectsIcon; diff --git a/public/modstagram_panel/src/assets/icons/ShopIcon.jsx b/public/modstagram_panel/src/assets/icons/ShopIcon.jsx deleted file mode 100644 index 4f79cec..0000000 --- a/public/modstagram_panel/src/assets/icons/ShopIcon.jsx +++ /dev/null @@ -1,20 +0,0 @@ - - - -import React from "react"; - -function ShopIcon(props) { - return ( - - - - - - - - - ); -} - -export default ShopIcon; diff --git a/public/modstagram_panel/src/assets/icons/SupportIcon.jsx b/public/modstagram_panel/src/assets/icons/SupportIcon.jsx deleted file mode 100644 index 330c4fc..0000000 --- a/public/modstagram_panel/src/assets/icons/SupportIcon.jsx +++ /dev/null @@ -1,14 +0,0 @@ -import React from "react"; - -function SupportIcon(props) { - return ( - - - - - ); -} - -export default SupportIcon; diff --git a/public/modstagram_panel/src/assets/icons/UsersIcon.jsx b/public/modstagram_panel/src/assets/icons/UsersIcon.jsx deleted file mode 100644 index 069f49b..0000000 --- a/public/modstagram_panel/src/assets/icons/UsersIcon.jsx +++ /dev/null @@ -1,16 +0,0 @@ -import React from "react"; - -function UsersIcon(props) { - return ( - - - - - - - ); -} - -export default UsersIcon; diff --git a/public/modstagram_panel/src/assets/icons/dashboardIcon.jsx b/public/modstagram_panel/src/assets/icons/dashboardIcon.jsx deleted file mode 100644 index eb987b2..0000000 --- a/public/modstagram_panel/src/assets/icons/dashboardIcon.jsx +++ /dev/null @@ -1,21 +0,0 @@ -import React from "react"; - -function DashboardIcon(props) { - return ( - - - - - - - ); -} - -export default DashboardIcon; diff --git a/public/modstagram_panel/src/components/BaseUrl.js b/public/modstagram_panel/src/components/BaseUrl.js deleted file mode 100644 index 463a28d..0000000 --- a/public/modstagram_panel/src/components/BaseUrl.js +++ /dev/null @@ -1,7 +0,0 @@ -export const BaseUrl = "https://app.modstagram.ir/api/v1/panel"; -export const AppBaseUrl = "https://app.modstagram.ir/api/v1"; -export const ImageBaseUrl = "https://app.modstagram.ir/storage"; - -// export const BaseUrl = "http://localhost:8000/api/v1/panel"; -// export const AppBaseUrl = "http://localhost:8000/api/v1"; -// export const ImageBaseUrl = "http://localhost:8000/storage"; \ No newline at end of file diff --git a/public/modstagram_panel/src/components/Filters.jsx b/public/modstagram_panel/src/components/Filters.jsx deleted file mode 100644 index 54bf4e8..0000000 --- a/public/modstagram_panel/src/components/Filters.jsx +++ /dev/null @@ -1,126 +0,0 @@ -import React from "react"; - -const Filters = ({ - statusOptions = [], - provinceOptions = [], - cityOptions = [], - photographyModelOptions = [], - blockStatusOptions = [], - onFilterChange = () => {}, -}) => { - const [filters, setFilters] = React.useState({ - startDate: "", - endDate: "", - status: "", - province: "", - city: "", - photographyModel: "", - blockStatus: "", - }); - - const handleFilterChange = (name, value) => { - const newFilters = { ...filters, [name]: value }; - if (name === "province") { - newFilters.city = ""; // ریست شهر هنگام تغییر استان - } - setFilters(newFilters); - onFilterChange(newFilters); - }; - - return ( -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - handleFilterChange("startDate", e.target.value)} - className="w-full p-3 rounded-lg border border-gray-300 dark:border-gray-600 focus:outline-none focus:ring-2 focus:ring-teal-500 dark:bg-gray-700 dark:text-white" - /> -
-
- - handleFilterChange("endDate", e.target.value)} - className="w-full p-3 rounded-lg border border-gray-300 dark:border-gray-600 focus:outline-none focus:ring-2 focus:ring-teal-500 dark:bg-gray-700 dark:text-white" - /> -
-
- ); -}; - -export default Filters; \ No newline at end of file diff --git a/public/modstagram_panel/src/components/Pagination.jsx b/public/modstagram_panel/src/components/Pagination.jsx deleted file mode 100644 index 3a5fd68..0000000 --- a/public/modstagram_panel/src/components/Pagination.jsx +++ /dev/null @@ -1,68 +0,0 @@ -import React from "react"; - -const Pagination = ({ totalPages, currentPage, onPageChange }) => { - if (!totalPages || totalPages <= 1) return null; - - const handlePageClick = (page) => { - if (page >= 1 && page <= totalPages) onPageChange(page); - }; - - const getPageNumbers = () => { - const pages = []; - if (totalPages <= 7) { - for (let i = 1; i <= totalPages; i++) pages.push(i); - } else { - pages.push(1); - let start = Math.max(currentPage - 2, 2); - let end = Math.min(currentPage + 2, totalPages - 1); - - if (start > 2) pages.push("..."); - for (let i = start; i <= end; i++) pages.push(i); - if (end < totalPages - 1) pages.push("..."); - pages.push(totalPages); - } - return pages; - }; - - const pages = getPageNumbers(); - - return ( -
- - - {pages.map((page, idx) => - page === "..." ? ( - ... - ) : ( - - ) - )} - - -
- ); -}; - -export default Pagination; diff --git a/public/modstagram_panel/src/components/academy/Header.js b/public/modstagram_panel/src/components/academy/Header.js deleted file mode 100644 index 3a2b80d..0000000 --- a/public/modstagram_panel/src/components/academy/Header.js +++ /dev/null @@ -1,33 +0,0 @@ -// src/components/Layout/Header.js -import React from "react"; -import { FaBell, FaUserCircle } from "react-icons/fa"; - -const Header = ({ toggleSidebar }) => { - return ( -
-
- -

پنل مدیریت

-
- -
- - -
- - مدیر سیستم -
-
-
- ); -}; - -export default Header; \ No newline at end of file diff --git a/public/modstagram_panel/src/components/academy/Layout.js b/public/modstagram_panel/src/components/academy/Layout.js deleted file mode 100644 index a2fb2be..0000000 --- a/public/modstagram_panel/src/components/academy/Layout.js +++ /dev/null @@ -1,27 +0,0 @@ -// src/components/Layout/Layout.js -import React, { useState } from "react"; -import Sidebar from "./Sidebar"; -import Header from "./Header"; - -const Layout = ({ children }) => { - const [sidebarOpen, setSidebarOpen] = useState(window.innerWidth > 768); - - const toggleSidebar = () => { - setSidebarOpen(!sidebarOpen); - }; - - return ( -
- - -
- {/*
*/} -
- {children} -
-
-
- ); -}; - -export default Layout; \ No newline at end of file diff --git a/public/modstagram_panel/src/components/academy/Sidebar.js b/public/modstagram_panel/src/components/academy/Sidebar.js deleted file mode 100644 index 2d64c5a..0000000 --- a/public/modstagram_panel/src/components/academy/Sidebar.js +++ /dev/null @@ -1,50 +0,0 @@ -// src/components/Layout/Sidebar.js -import React from "react"; -import { NavLink } from "react-router-dom"; -import { - FaTachometerAlt, - FaWallet, - FaBook, - FaShoppingCart, - FaUniversity, - FaCog, - FaBackspace -} from "react-icons/fa"; - -const Sidebar = () => { - const menuItems = [ - { path: "/academy", label: "داشبورد", icon: }, - { path: "/payments", label: "مدیریت پرداخت‌ها", icon: }, - { path: "/courses", label: "مدیریت دوره‌ها", icon: }, - { path: "/purchased", label: "دوره‌های خریداری شده", icon: }, - { path: "/academies", label: "مدیریت آکادمی‌ها", icon: }, - { path: "/settings", label: "تنظیمات", icon: }, - { path: "/", label: "بازگشت", icon: } - ]; - - return ( -
-
-

پنل مدیریت دوره‌ها

-
- -
- ); -}; - -export default Sidebar; \ No newline at end of file diff --git a/public/modstagram_panel/src/components/admin-header.jsx b/public/modstagram_panel/src/components/admin-header.jsx deleted file mode 100644 index f52bffd..0000000 --- a/public/modstagram_panel/src/components/admin-header.jsx +++ /dev/null @@ -1,87 +0,0 @@ -import React, { useContext, useState } from "react"; -import { useNavigate } from "react-router-dom"; -import Loading from "./elements/loading"; -import { Link } from "react-router-dom/dist"; - -function AdminHeader() { - const navigate = useNavigate(); - const handleLogOut = () => { - localStorage.clear(); - document.getElementById("to_login").click(); - }; - function refreshPage() { - setTimeout(() => { - window.location.reload(false); - }, 1000); - } - return ( - <> - -
-
-
-
-
- -
-

- {/* {full_name} */} -

-
-
-
-
logOutMutation.mutate()} - className="flex bg-white cursor-pointer bg-primary hover:bg-[#cbade4] px-5 items-center h-9 group transition-colors duration-500 hover:bg-cyann rounded-[4px] font-KalamehMed font-medium" - > - <> - - - - - - - -
-
-
-
- - ); -} - -export default AdminHeader; diff --git a/public/modstagram_panel/src/components/adminApi.js b/public/modstagram_panel/src/components/adminApi.js deleted file mode 100644 index c89db8d..0000000 --- a/public/modstagram_panel/src/components/adminApi.js +++ /dev/null @@ -1,42 +0,0 @@ -// src/services/adminApi.js -import api from "./api"; - -// ==================== پرداخت‌ها ==================== -export const getPayments = (params) => api.get("/academy/payments", { params }); -export const updatePaymentStatus = (data) => api.put("/academy/payments/status", data); -export const getPaymentStats = () => api.get("/academy/payments/stats"); - -// ==================== دوره‌ها ==================== -export const getCourses = (params) => api.get("/academy/courses", { params }); -export const getCourseById = (id) => api.get(`/academy/courses/${id}`); -export const createCourse = (data) => api.post("/academy/courses", data); -export const updateCourse = (id, data) => api.put(`/academy/courses/${id}`, data); -export const updateCourseStatus = (data) => api.put("/academy/academy/courses/status", data); -export const deleteCourse = (courseId) => api.delete(`/academy/courses/${courseId}`); -export const getCourseStats = () => api.get("/academy/courses/stats"); - -// ==================== دوره‌های خریداری شده ==================== -export const getPurchasedCourses = (params) => api.get("/academy/purchased", { params }); -export const getPurchasedStats = () => api.get("/academy/purchased/stats"); - -// ==================== آکادمی‌ها ==================== -export const getAcademies = (params) => api.get("/academy/academies", { params }); -export const getAcademyById = (id) => api.get(`/academy/academies/${id}`); -export const createAcademy = (data) => api.post("/academy/academies", data); -export const updateAcademy = (id, data) => api.put(`/academy/academies/${id}`, data); -export const updateAcademyStatus = (data) => api.put("/academy/academies/status", data); -export const deleteAcademy = (id) => api.delete(`/academy/academies/${id}`); -export const getAcademyStats = () => api.get("/academy/academies/stats"); - -// ==================== تنظیمات ==================== -// مسیرهای قدیمی (برای سازگاری) -export const getSettings = () => api.get("/academy/settings/all"); -export const updateSettings = (data) => api.put("/academy/settings/all", data); - -// مسیرهای جدید (جداگانه) -export const getCoursePrices = () => api.get("/academy/settings/course-prices"); -export const updateCoursePrice = (data) => api.put("/academy/settings/course-price", data); -export const getTax = () => api.get("/academy/settings/tax"); -export const updateTax = (data) => api.put("/academy/settings/tax", data); -export const getAllSettings = () => api.get("/academy/settings/all"); -export const updateAllSettings = (data) => api.put("/academy/settings/all", data); \ No newline at end of file diff --git a/public/modstagram_panel/src/components/api.js b/public/modstagram_panel/src/components/api.js deleted file mode 100644 index 5767435..0000000 --- a/public/modstagram_panel/src/components/api.js +++ /dev/null @@ -1,45 +0,0 @@ -// src/services/api.js - نسخه ساده و مطمئن -import axios from "axios"; -import Cookies from "js-cookie"; -import { AppBaseUrl } from "./BaseUrl"; - -const API_BASE_URL = AppBaseUrl || "http://localhost:5000/api"; - -const api = axios.create({ - baseURL: API_BASE_URL, - headers: { - "Content-Type": "application/json" - } -}); - -api.interceptors.request.use( - (config) => { - // توکن - const token = Cookies.get("token"); - if (token) { - config.headers.Authorization = `Bearer ${token}`; - } - - // فقط یک تغییر ساده: اضافه کردن timestamp به URL - if (config.method === 'get') { - const separator = config.url.includes('?') ? '&' : '?'; - config.url = `${config.url}${separator}_t=${Date.now()}`; - } - - return config; - }, - (error) => Promise.reject(error) -); - -api.interceptors.response.use( - (response) => response, - (error) => { - if (error.response?.status === 401) { - Cookies.remove("token"); - window.location.href = "/login"; - } - return Promise.reject(error); - } -); - -export default api; \ No newline at end of file diff --git a/public/modstagram_panel/src/components/elements/loading.jsx b/public/modstagram_panel/src/components/elements/loading.jsx deleted file mode 100644 index 10963cc..0000000 --- a/public/modstagram_panel/src/components/elements/loading.jsx +++ /dev/null @@ -1,57 +0,0 @@ -import React from "react"; - -function Loading(props) { - return ( - <> - - - - - - - - - - ); -} - -export default Loading; diff --git a/public/modstagram_panel/src/components/shops/ShopDet.jsx b/public/modstagram_panel/src/components/shops/ShopDet.jsx deleted file mode 100644 index a5c5605..0000000 --- a/public/modstagram_panel/src/components/shops/ShopDet.jsx +++ /dev/null @@ -1,436 +0,0 @@ -import React, { useEffect, useState } from "react"; -import { AppBaseUrl, BaseUrl, ImageBaseUrl } from "../BaseUrl"; -import axios from "axios"; -import toast from "react-hot-toast"; -import Modal from "react-modal"; -const customStyles = { - content: { - top: "50%", - left: "50%", - transform: "translate(-50%, -50%)", - position: "fixed", - }, -}; -const ShopDet = ({ shopData, id, getUserDetails }) => { - const [isEditing, setIsEditing] = useState(false); - const [editedData, setEditedData] = useState({}); - const [categories, setCategories] = useState([]); - const [modalIsOpen, setModalIsOpen] = useState(false); - const [modalImage, setModalImage] = useState(""); - - const openModal = (image) => { - setModalImage(image); - setModalIsOpen(true); - }; - const closeModal = () => { - setModalIsOpen(false); - }; - - const getCategories = (page = 1) => { - const config = { - url: `${AppBaseUrl}/advertising/categories`, - method: "GET", - }; - axios(config) - .then((res) => { - setCategories(res?.data?.categories); - }) - .catch((err) => { }); - }; - useEffect(() => { - getCategories(); - }, []); - const handleChange = (e) => { - const { name, value } = e.target; - setEditedData((prevData) => ({ - ...prevData, - [name]: value, - })); - }; - - console.log(editedData); - - const handleSave = async () => { - try { - const response = await axios.put( - `${BaseUrl}/shops/update?shopId=${shopData._id}`, - editedData, - { - headers: { - Authorization: `Bearer ${localStorage.getItem( - "token" - )}`, // اگر نیاز به توکن احراز هویت دارید - }, - } - ); - getUserDetails(); - setIsEditing(false); - } catch (error) { - if ( - error.response && - error.response.data && - error.response.data.errors - ) { - error.response.data.errors.forEach((err) => { - if (typeof err.message === "string") { - // نمایش پیام خطا در صورتیکه به صورت string باشد - toast.error(err.message); - } else { - // نمایش پیام خطا برای موارد دیگر - toast.error("خطای ناشناخته"); - } - }); - } else { - // نمایش پیام خطا برای سایر موارد - toast.error("خطای ناشناخته"); - } - } - }; - const contactInfoArray = shopData?.contactInfo - ? Object.keys(shopData.contactInfo).map((key) => { - let title; - switch (key) { - case "phone": - title = "شماره ثابت"; - break; - case "mobile": - title = "شماره همراه"; - break; - case "telegramLink": - title = "لینک تلگرام"; - break; - case "whatsappNumber": - title = "شماره واتساپ"; - break; - case "instagramLink": - title = "لینک اینستاگرام"; - break; - case "saveInfoForNextAds": - title = "ذخیره اطلاعات برای آگهی‌های بعدی"; - break; - default: - title = key; - } - return { title, value: shopData.contactInfo[key] }; - }) - : []; - return ( -
-
- - {/* استفاده از ImageMagnify */} - Post - -
-
- {/* - - - */} - تصویر پروفایل: -
-
- -
-
- {/* User Name */} -
-
- نام کاربری: -
-
- {shopData?.user_name} -
-
- - {/* First Name */} -
-
- نام: -
-
- {shopData?.first_name} -
-
- - {/* Last Name */} -
-
- نام خانوادگی: -
-
- {shopData?.last_name} -
-
- - {/* Mobile */} -
-
- دسته بندی: -
-
- {isEditing ? ( - - ) : ( - shopData?.category - )} -
-
- {/* National Code */} -
-
- عنوان فروشگاه: -
-
- {isEditing ? ( - - ) : ( - shopData?.vitrine_name - )} -
-
- -
-
- استان: -
-
- {shopData?.province?.name} -
-
-
-
- شهر: -
-
- {shopData?.city?.name} -
-
-
-
- محله: -
-
- {shopData?.neighbourhood} -
-
- {/* Address */} -
-
- آدرس: -
-
- {isEditing ? ( - - ) : ( - shopData?.address - )} -
-
-
-
- لیست خدمات و کالا -
-
-
- {shopData?.allServices && - shopData?.allServices?.map((item) => { - return ( -
- { - openModal( - ImageBaseUrl + - item?.image - ); - }} - src={ImageBaseUrl + item?.image} - className="w-[100px] h-[100px] rounded-sm" - alt="" - /> -

- نام : {item?.title} -

-

- درصد تخفیف :{" "} - {item?.discountPercentage} -

-

- قیمت اصلی :{" "} - {item?.originalPrice} -

-

- قیمت تخفیف خورده :{" "} - {item?.discountPrice} -

-
- ); - })} -
-
-
-
-
- لیست امکانات -
-
-
- {shopData?.allFeatures && - shopData?.allFeatures?.map((item) => { - return ( -
-

- {" "} - {item?.title} :{" "} -

-

- {item?.value == true - ? "دارد" - : "ندارد"} -

-
- ); - })} -
-
-
-
-
- لیست تماس -
-
-
- {contactInfoArray.map((item, index) => ( -
-

{item.title} :

-

{item.value}

-
- ))} -
-
-
-
-
- تصاویر -
-
- {shopData?.allImages && - shopData?.allImages?.map((item) => { - return ( -
- { - openModal(ImageBaseUrl + item); - }} - src={ImageBaseUrl + item} - className="w-[100px] h-[100px] rounded-sm m-4" - alt="" - /> -
- ); - })} -
-
-
-
- درباره ما: -
-
- {isEditing ? ( - - ) : ( - shopData?.about_us - )} -
-
-
-
- تاریخ ثبت فروشگاه: -
-
- {shopData?.createdAt} -
-
- - {/* Save Button */} -
- {isEditing ? ( - - ) : ( - - )} -
-
-
- ); -}; - -export default ShopDet; diff --git a/public/modstagram_panel/src/components/sidebar.jsx b/public/modstagram_panel/src/components/sidebar.jsx deleted file mode 100644 index 013119e..0000000 --- a/public/modstagram_panel/src/components/sidebar.jsx +++ /dev/null @@ -1,591 +0,0 @@ -import React, { useEffect, useState } from "react"; -import { Link, useLocation, useNavigate, useParams } from "react-router-dom"; -import DashboardIcon from "../assets/icons/dashboardIcon"; -import UsersIcon from "../assets/icons/UsersIcon"; -import PostsIcon from "../assets/icons/PostsIcon"; -import ProjectsIcon from "../assets/icons/ProjectsIcon"; -import SupportIcon from "../assets/icons/SupportIcon"; -import FinancialsIcon from "../assets/icons/FinancialsIcon"; -import CommentsIcon from "../assets/icons/CommentsIcon"; -import AdvertisingIcon from "../assets/icons/AdvertisingIcon"; -import ShopIcon from "../assets/icons/ShopIcon"; -import { GrLicense } from "react-icons/gr"; - -function Tooltip({ svgIcon, title }) { - const [showTooltip, setShowTooltip] = useState(false); - - return ( -
- setShowTooltip(true)} - onMouseLeave={() => setShowTooltip(false)} - > - {svgIcon} - -
-
-
- {title} -
- - - -
-
-
- ); -} - -const Sidebar = () => { - const { pathname } = useLocation(); - const navigate = useNavigate(); - const param = useParams(); - const [items, setItems] = useState([]); - const [isCollapsed, setIsCollapsed] = useState(false); - - useEffect(() => { - setItems([ - { - menu: "داشبورد", - subshow: false, - link: "/", - submenu: [], - icon(pathnamin) { - return ( - - } - title="داشبورد" - /> - ); - }, - }, - { - menu: "کاربران", - link: "/users", - subshow: false, - submenu: [], - icon(pathnamin) { - return ( - - } - title="کاربران" - /> - ); - }, - }, - { - menu: "پست ها", - link: "/posts", - subshow: false, - submenu: [], - icon(pathnamin) { - return ( - - } - title="پست ها" - /> - ); - }, - }, - { - menu: "پروژه ها", - link: "/projects", - subshow: false, - submenu: [], - icon(pathnamin) { - return ( - - } - title="پروژه ها" - /> - ); - }, - }, - { - menu: "تیکت ها", - link: "/tickets", - subshow: false, - submenu: [], - icon(pathnamin) { - return ( - - } - title="تیکت ها" - /> - ); - }, - }, - { - menu: "مالی", - link: "/financials", - subshow: false, - submenu: [], - icon(pathnamin) { - return ( - - } - title="مالی" - /> - ); - }, - }, - { - menu: "نظرات", - link: "/comments", - subshow: false, - submenu: [], - icon(pathnamin) { - return ( - - } - title="نظرات" - /> - ); - }, - }, - { - menu: "ویترین", - link: "/vitrine", - subshow: false, - submenu: [], - icon(pathnamin) { - return ( - - } - title="ویترین" - /> - ); - }, - }, - { - menu: "نظرات ویترین", - link: "/vitrine-comments", - subshow: false, - submenu: [], - icon(pathnamin) { - return ( - - } - title="نظرات ویترین" - /> - ); - }, - }, - { - menu: "فروشگاه", - link: "/shops", - subshow: false, - submenu: [], - icon(pathnamin) { - return ( - - } - title="فروشگاه" - /> - ); - }, - }, - { - menu: "اموزشگاه", - link: "/academy", - subshow: false, - submenu: [], - icon(pathnamin) { - return ( - - } - title="اموزشگاه" - /> - ); - }, - }, - { - menu: "مجوز", - link: "/license", - subshow: false, - submenu: [], - icon(pathnamin) { - return ( - - } - title="مجوز" - /> - ); - }, - }, - { - menu: "ورژن برنامه", - link: "/version", - subshow: false, - submenu: [], - icon(pathnamin) { - return ( - - - - } - title="ورژن برنامه" - /> - ); - }, - }, - { - menu: "تخصص", - link: "/expertise", - subshow: false, - submenu: [], - icon(pathnamin) { - return ( - - - - } - title="تخصص" - /> - ); - }, - }, - { - menu: "قوانین مقررات", - link: "/terms", - subshow: false, - submenu: [], - icon(pathnamin) { - return ( - - } - title="قوانین مقررات" - /> - ); - }, - }, - { - menu: "خروج", - subshow: false, - link: "#", - submenu: [], - icon(pathnamin) { - return ( - - - - - - - - } - title="خروج" - /> - ); - }, - }, - ]); - }, []); - - useEffect(() => { - let indexOfItem = 0; - for (let item of items) { - indexOfItem++; - for (let submenu of item.submenu) { - if (pathname.replace("/", "").includes(submenu?.link.replace("/", ""))) { - setItems((prev) => - prev.map((sidebarItem, i) => - i === indexOfItem - 1 - ? { ...sidebarItem, subshow: true } - : sidebarItem - ) - ); - return; - } - } - } - }, [pathname, items]); - - const navigateToMenu = (item) => { - navigate(item?.link); - setItems((prev) => - prev.map((sidebarItem) => ({ ...sidebarItem, subshow: false })) - ); - }; - - const showSubMenu = (index) => { - setItems((prev) => - prev.map((sidebarItem, i) => - i === index - ? { ...sidebarItem, subshow: !sidebarItem.subshow } - : { ...sidebarItem, subshow: false } - ) - ); - }; - - const handleLogOut = () => { - localStorage.clear(); - document.getElementById("to_login").click(); - }; - - function refreshPage() { - setTimeout(() => { - window.location.reload(false); - }, 1000); - } - - const toggleSidebar = () => { - setIsCollapsed(!isCollapsed); - }; - - return ( -
- - -
- {items.map((item, index) => ( -
- {item.submenu.length === 0 ? ( - - ) : ( - - )} - {!isCollapsed && ( -
- {item.submenu.map((submenuItem, subIndex) => { - const isActive = pathname - .replace("/", "") - .includes(submenuItem.link.replace("/", "")); - return ( - - {submenuItem.menu} - - ); - })} -
- )} -
- ))} -
-
- ); -}; - -export default Sidebar; \ No newline at end of file diff --git a/public/modstagram_panel/src/components/users/UserChangePassword.jsx b/public/modstagram_panel/src/components/users/UserChangePassword.jsx deleted file mode 100644 index 406a4f3..0000000 --- a/public/modstagram_panel/src/components/users/UserChangePassword.jsx +++ /dev/null @@ -1,208 +0,0 @@ -import React, { useState } from 'react'; -import axios from 'axios'; -import { BaseUrl } from '../BaseUrl'; -import toast, { Toaster } from 'react-hot-toast'; -import { FiEye, FiEyeOff, FiLock, FiCheckCircle } from 'react-icons/fi'; -import { useParams } from 'react-router-dom'; - -const UserChangePassword = () => { - const { id } = useParams(); // آیدی کاربر - - const [formData, setFormData] = useState({ - newPassword: '', - confirmPassword: '', - }); - const [showPassword, setShowPassword] = useState({ - new: false, - confirm: false, - }); - const [loading, setLoading] = useState(false); - const [errors, setErrors] = useState({}); - - const handleChange = (e) => { - const { name, value } = e.target; - setFormData((prev) => ({ ...prev, [name]: value })); - if (errors[name]) setErrors((prev) => ({ ...prev, [name]: '' })); - }; - - const togglePasswordVisibility = (field) => { - setShowPassword((prev) => ({ ...prev, [field]: !prev[field] })); - }; - - const validatePassword = (password) => { - const errors = []; - if (password.length < 8) errors.push('حداقل 8 کاراکتر'); - if (!/[A-Z]/.test(password)) errors.push('حداقل یک حرف بزرگ'); - if (!/[a-z]/.test(password)) errors.push('حداقل یک حرف کوچک'); - if (!/[0-9]/.test(password)) errors.push('حداقل یک عدد'); - return errors; - }; - - const handleSubmit = async (e) => { - e.preventDefault(); - const newErrors = {}; - - // اعتبارسنجی پسورد جدید - const passwordErrors = validatePassword(formData.newPassword); - if (passwordErrors.length > 0) { - newErrors.newPassword = passwordErrors.join('، '); - } - - // تطابق پسوردها - if (formData.newPassword !== formData.confirmPassword) { - newErrors.confirmPassword = 'پسوردها مطابقت ندارند'; - } - - if (Object.keys(newErrors).length > 0) { - setErrors(newErrors); - return; - } - - setLoading(true); - - try { - await axios.post( - `https://app.modstagram.ir/api/v1/panel/users/change-password`, - { - userId: id, - password: formData.newPassword, // فقط پسورد جدید - } - - ); - - // toast.success('رمز عبور کاربر با موفقیت تغییر کرد', { - // icon: , - // style: { background: '#10b981', color: 'white' }, - // }); - - // ریست فرم - setFormData({ newPassword: '', confirmPassword: '' }); - } catch (err) { - const message = err.response?.data?.message || 'خطا در تغییر رمز عبور'; - toast.error(message, { style: { background: '#ef4444', color: 'white' } }); - } finally { - setLoading(false); - } - }; - - return ( - <> - -
-
-
-
-
- -
-

تغییر رمز عبور کاربر

-

- آیدی کاربر: {id} -

-
- -
- - {/* پسورد جدید */} -
- -
- - -
- {errors.newPassword && ( -

{errors.newPassword}

- )} -
-

= 8 ? 'text-green-400' : ''}> - حداقل 8 کاراکتر -

-

- یک حرف بزرگ -

-

- یک حرف کوچک -

-

- یک عدد -

-
-
- - {/* تأیید پسورد */} -
- -
- - -
- {errors.confirmPassword && ( -

{errors.confirmPassword}

- )} -
- - {/* دکمه ارسال */} - -
-
-
-
- - ); -}; - -export default UserChangePassword; \ No newline at end of file diff --git a/public/modstagram_panel/src/components/users/UserComments.jsx b/public/modstagram_panel/src/components/users/UserComments.jsx deleted file mode 100644 index e2e3088..0000000 --- a/public/modstagram_panel/src/components/users/UserComments.jsx +++ /dev/null @@ -1,234 +0,0 @@ -import React, { useEffect, useState } from "react"; -import AdminHeader from "../../components/admin-header"; -import Sidebar from "../../components/sidebar"; -import { useNavigate, useParams } from "react-router-dom"; -import { BaseUrl } from "../../components/BaseUrl"; -import axios from "axios"; -import Loading from "../../components/elements/loading"; -import Pagination from "../../components/Pagination"; -import Filters from "../Filters"; - -const Comments = ({}) => { - // دریافت id از props - const navigate = useNavigate(); - const [loading, setLoading] = useState(false); - const [allComments, setAllComments] = useState([]); // تمام کامنت‌ها - const [commentList, setCommentList] = useState([]); // کامنت‌های فیلتر شده - const [totalPages, setTotalPages] = useState(0); - const [currentPage, setCurrentPage] = useState(1); - const [filters, setFilters] = useState({ - startDate: "", - endDate: "", - status: "", - }); - - - const token = document.cookie - .split("; ") - .find((row) => row.startsWith("token=")) - ?.split("=")[1]; - - const param = useParams(); - const id = param?.id; - - const getCommentList = (page = 1) => { - setLoading(true); - - const { startDate, endDate, status } = filters; - const config = { - url: `${BaseUrl}/comments?limit=20&page=${page}${ - startDate ? "&startDate=" + startDate : "" - }${endDate ? "&endDate=" + endDate : ""}&status=${status}`, - - method: "GET", - headers: { - Authorization: `Bearer ${token}`, // اضافه کردن توکن به هدر - }, - }; - axios(config) - .then((res) => { - // setAllComments(res?.data?.comments); - setTotalPages(res?.data?.totalPages); - - // بررسی اینکه کامنت‌ها وجود دارند - const comments = res?.data?.comments || []; - - console.log(comments); - - // فیلتر فقط زمانی انجام میشه که creator وجود داشته باشه - const userComments = comments.filter( - (c) => c?.creator?._id === id - ); - - setCommentList(userComments); - setLoading(false); - - }) - .catch((err) => { - setLoading(false); - }); - }; - useEffect(() => { - getCommentList(currentPage); - }, [currentPage, filters]); - - return ( - <> -
-
-
- {/* Filters */} - - -
-
-
-

- عنوان پروژه -

-
-
-

- نام کاربری سازنده -

-
-
-

- نام و نام خانوادگی سازنده -

-
-
-

- نام کاربری یوزر -

-
-
-

- نام و نام خانوادگی یوزر -

-
-
-

- تاریخ ثبت کامنت -

-
-
-

وضعیت

-
-
-

-
-
-
- {loading ? ( -
- -
- ) : ( -
- {Array.isArray(commentList) && commentList.length > 0 ? ( - commentList.map((comment, index) => { - return ( -
-
-

- {comment?.project || "-"} -

-
-
-

- {comment?.creator?.user_name || "-"} -

-
-
-

- {comment?.creator?.first_name || ""}{" "} - {comment?.creator?.last_name || ""} -

-
-
-

- {comment?.user?.user_name || "-"} -

-
-
-

- {comment?.user?.first_name || ""}{" "} - {comment?.user?.last_name || ""} -

-
-
-

- {comment?.createdAt || "-"} -

-
-
-
-

- {comment?.status === "pending" - ? "در انتظار تایید" - : comment?.status === "accepted" - ? "تایید شده" - : comment?.status === "rejected" - ? "رد شده" - : "-"} -

-
-
-
- -
-
- ); - }) - ) : ( -

- هیچ کامنتی یافت نشد. -

- )} -
- )} - setCurrentPage(page)} - /> -
-
-
- - ); -}; - -export default Comments; diff --git a/public/modstagram_panel/src/components/users/UserDet.jsx b/public/modstagram_panel/src/components/users/UserDet.jsx deleted file mode 100644 index 4f92fac..0000000 --- a/public/modstagram_panel/src/components/users/UserDet.jsx +++ /dev/null @@ -1,607 +0,0 @@ -import React, { useState } from "react"; -import { BaseUrl, ImageBaseUrl } from "../BaseUrl"; -import axios from "axios"; -import Modal from "react-modal"; -import toast from "react-hot-toast"; -import Sidebar from "../sidebar"; - -const customStyles = { - content: { - top: "50%", - left: "50%", - transform: "translate(-50%, -50%)", - position: "fixed", - }, -}; - -const UserDet = ({ userData, id, getUserDet }) => { - const [isEditing, setIsEditing] = useState(false); - const [editedData, setEditedData] = useState({}); - const [modalIsOpen, setModalIsOpen] = useState(false); - const [modalImage, setModalImage] = useState(""); - - const openModal = (image) => { - setModalImage(image); - setModalIsOpen(true); - }; - - const closeModal = () => { - setModalIsOpen(false); - }; - - const handleChange = (e) => { - const { name, value } = e.target; - setEditedData((prevData) => ({ - ...prevData, - [name]: value, - })); - }; - - const handleSave = async () => { - try { - const response = await axios.put( - `${BaseUrl}/users/update?userId=${userData._id}`, - editedData, - { - headers: { - Authorization: `Bearer ${localStorage.getItem("token")}`, - }, - } - ); - setIsEditing(false); - toast.success("اطلاعات با موفقیت ذخیره شد"); - getUserDet(); - } catch (error) { - if (error.response && error.response.data && error.response.data.errors) { - error.response.data.errors.forEach((err) => { - toast.error( - typeof err.message === "string" ? err.message : "خطای ناشناخته" - ); - }); - } else { - toast.error("خطای ناشناخته"); - } - } - }; - - const acceptVerify = () => { - axios - .post(`${BaseUrl}/users/verify?userId=${id}`, { - headers: { - Accept: "application/json", - "Content-Type": "application/json", - }, - }) - .then(async (response) => { - toast.success(response?.data?.message); - getUserDet(); - }) - .catch((error) => { - toast.error(error?.response?.data?.message || "خطای ناشناخته"); - }); - }; - - const rejectVerify = () => { - axios - .post(`${BaseUrl}/users/reject?userId=${id}`, { - headers: { - Accept: "application/json", - "Content-Type": "application/json", - }, - }) - .then(async (response) => { - toast.success(response?.data?.message); - getUserDet(); - }) - .catch((error) => { - toast.error(error?.response?.data?.message || "خطای ناشناخته"); - }); - }; - - const acceptService = async (serviceId) => { - try { - // به‌روزرسانی آرایه services با تغییر status سرویس موردنظر به "true" - const updatedServices = userData.services.map((service) => - service._id === serviceId ? { ...service, status: "true" } : service - ); - - const response = await axios.put( - `${BaseUrl}/users/update?userId=${userData._id}`, - { services: updatedServices }, - { - headers: { - Authorization: `Bearer ${localStorage.getItem("token")}`, - Accept: "application/json", - "Content-Type": "application/json", - }, - } - ); - toast.success(response?.data?.message || "سرویس با موفقیت تأیید شد"); - getUserDet(); - } catch (error) { - toast.error(error?.response?.data?.message || "خطای ناشناخته"); - } - }; - - const rejectService = async (serviceId) => { - // فقط پیام رد نمایش داده می‌شود و status تغییر نمی‌کند - toast.success("سرویس رد شد"); - }; - - return ( -
-
- - Post - - - {/* Profile Image */} -
-
- تصویر پروفایل: -
-
- openModal(ImageBaseUrl + userData?.profile_image)} - src={ImageBaseUrl + userData?.profile_image} - className="w-[200px] h-[200px] rounded-md" - alt="" - /> -
-
- - {/* User Name */} -
-
- نام کاربری: -
-
- {isEditing ? ( - - ) : ( - userData?.user_name - )} -
-
- - {/* First Name */} -
-
- نام: -
-
- {isEditing ? ( - - ) : ( - userData?.first_name - )} -
-
- - {/* Last Name */} -
-
- نام خانوادگی: -
-
- {isEditing ? ( - - ) : ( - userData?.last_name - )} -
-
- - {/* Mobile */} -
-
- موبایل: -
-
- {isEditing ? ( - - ) : ( - userData?.mobile - )} -
-
- - {/* National Code */} -
-
- کد ملی: -
-
- {isEditing ? ( - - ) : ( - userData?.national_code - )} -
-
- - {/* Province */} -
-
- استان: -
-
- {userData?.province?.name} -
-
- - {/* City */} -
-
- شهر: -
-
- {userData?.city?.name} -
-
- - {/* Address */} -
-
- آدرس: -
-
- {isEditing ? ( - - ) : ( - userData?.address - )} -
-
- - {/* Height */} -
-
- قد: -
-
- {isEditing ? ( - - ) : ( - userData?.height - )} -
-
- - {/* Weight */} -
-
- وزن: -
-
- {isEditing ? ( - - ) : ( - userData?.weight - )} -
-
- - {/* Size */} -
-
- سایز: -
-
- {isEditing ? ( - - ) : ( - userData?.size - )} -
-
- - {/* Bio */} -
-
- بیو: -
-
- {isEditing ? ( - - ) : ( - userData?.bio - )} -
-
- - {/* Birthday */} -
-
- تاریخ تولد: -
-
- {userData?.birthday} -
-
- - {/* Cooperation Abroad */} -
-
- خارج از محدوده سکونت به من پیشنهاد بده: -
-
- {userData?.cooperation_abroad == true ? "بله" : "خیر"} -
-
- - {/* Conversation Projects */} -
-
- پروژه با روابط عمومی بالا: -
-
- {userData?.conversation_projects == true ? "بله" : "خیر"} -
-
- - {/* Expertise */} -
- {/* عنوان */} -
- تخصص: -
- - {/* تخصص + زیرتخصص‌ها */} -
- {userData?.expertise} : - - {userData?.sub_expertise?.map((item, index) => ( - - {item} - {index !== userData?.sub_expertise?.length - 1 ? " _ " : ""} - - ))} -
-
- - {/* Shaba */} -
-
- شماره شبا: -
-
- {isEditing ? ( - - ) : ( - userData?.shaba - )} -
-
- - {/* National Card Image */} -
-
- تصویر کارت ملی: -
-
- - openModal(ImageBaseUrl + userData?.national_card_image) - } - src={ImageBaseUrl + userData?.national_card_image} - className="w-[200px] h-[200px] rounded-md" - alt="" - /> -
-
- - {/* Last Online */} -
-
- آخرین زمان ورود: -
-
- {userData?.last_online} -
-
- - {/* Created At */} -
-
- تاریخ ثبت نام: -
-
- {userData?.createdAt} -
-
- - {/* Verification Status */} -
-
- وضعیت مدارک: -
-
-

- {userData?.is_verified === "verified" - ? "تایید شده" - : userData?.is_verified === "pending" - ? "در انتظار تایید" - : ""} -

- - -
-
- - {/* Services Section */} -
-
- خدمات: -
-
- {userData?.services?.length > 0 ? ( - userData.services.map((service) => ( -
- {service.title} openModal(ImageBaseUrl + service.image)} - /> -
-

عنوان: {service.title}

-

قیمت اصلی: {service.originalPrice} تومان

-

قیمت با تخفیف: {service.discountPrice} تومان

-

درصد تخفیف: {service.discountPercentage}%

-

- وضعیت:{" "} - {service.status === "true" - ? "تأیید شده" - : service.status === "UnderReview" - ? "در انتظار بررسی" - : "رد شده"} -

-
-
- -
-
- )) - ) : ( -

هیچ سرویسی یافت نشد

- )} -
-
- - {/* User Rate */} -
-
- امتیاز کاربر: -
-
- {userData?.rate} -
-
- - {/* User Level */} -
-
- سطح کاربر: -
-
- {userData?.user_level} -
-
- - {/* Save Button */} -
- {isEditing ? ( - - ) : ( - - )} -
-
-
- ); -}; - -export default UserDet; diff --git a/public/modstagram_panel/src/components/users/UserFinancial.jsx b/public/modstagram_panel/src/components/users/UserFinancial.jsx deleted file mode 100644 index 59471a3..0000000 --- a/public/modstagram_panel/src/components/users/UserFinancial.jsx +++ /dev/null @@ -1,9 +0,0 @@ -import React from 'react' - -const UserFinancial = () => { - return ( -
UserFinancial
- ) -} - -export default UserFinancial \ No newline at end of file diff --git a/public/modstagram_panel/src/components/users/UserMessages.jsx b/public/modstagram_panel/src/components/users/UserMessages.jsx deleted file mode 100644 index e03c8e5..0000000 --- a/public/modstagram_panel/src/components/users/UserMessages.jsx +++ /dev/null @@ -1,9 +0,0 @@ -import React from 'react' - -const UserMessages = () => { - return ( -
UserMessages
- ) -} - -export default UserMessages \ No newline at end of file diff --git a/public/modstagram_panel/src/components/users/UserPosts.jsx b/public/modstagram_panel/src/components/users/UserPosts.jsx deleted file mode 100644 index 0a8fe3e..0000000 --- a/public/modstagram_panel/src/components/users/UserPosts.jsx +++ /dev/null @@ -1,217 +0,0 @@ -import React, { useEffect, useState } from "react"; -import { useNavigate } from "react-router-dom"; -import { BaseUrl, ImageBaseUrl } from "../../components/BaseUrl"; -import axios from "axios"; -import Loading from "../../components/elements/loading"; -import Pagination from "../../components/Pagination"; - -const UserPosts = ({ id }) => { - const navigate = useNavigate(); - const [loading, setLoading] = useState(false); - const [allPosts, setAllPosts] = useState([]); // تمام پست‌ها - const [postsList, setPostsList] = useState([]); // پست‌های صفحه جاری - const [totalPages, setTotalPages] = useState(0); - const [currentPage, setCurrentPage] = useState(1); - const [filters, setFilters] = useState({ - startDate: "", - endDate: "", - status: "", - }); - - const itemsPerPage = 10; // تعداد آیتم در هر صفحه - - // دریافت همه پست‌ها از API (بدون user_id) - const fetchAllPosts = () => { - setLoading(true); - const { startDate, endDate, status } = filters; - - let url = `${BaseUrl}/posts?limit=1000`; // گرفتن تعداد زیاد برای فیلتر فرانت - if (startDate) url += `&startDate=${startDate}`; - if (endDate) url += `&endDate=${endDate}`; - if (status) url += `&status=${status}`; - - axios - .get(url) - .then((res) => { - const posts = res?.data?.posts || []; - setAllPosts(posts); - setLoading(false); - }) - .catch(() => setLoading(false)); - }; - - // فیلتر و صفحه‌بندی روی فرانت - const paginatePosts = () => { - const filteredPosts = allPosts.filter((post) => post.user_id === id); - const startIndex = (currentPage - 1) * itemsPerPage; - const paginatedPosts = filteredPosts.slice( - startIndex, - startIndex + itemsPerPage - ); - setPostsList(paginatedPosts); - setTotalPages(Math.ceil(filteredPosts.length / itemsPerPage)); - }; - - useEffect(() => { - fetchAllPosts(); - }, [filters]); - - useEffect(() => { - paginatePosts(); - }, [allPosts, currentPage, id]); - - return ( - <> -
-
-
- {/* Table Header */} -
-
-
-

تصویر

-
-
-

نام کاربری

-
-
-

نوع کاربری

-
-
-

نام و نام خانوادگی

-
-
-

موبایل

-
-
-

کد ملی

-
-
-

تاریخ ثبت پست

-
-
-

وضعیت

-
-
-

جزئیات

-
-
-
- - {loading ? ( -
- -
- ) : ( -
- {postsList?.map((post, index) => ( -
-
-
- {post?.files?.length > 0 ? ( - post.files[0].type === "image" ? ( - Post - ) : ( -
-
-

{post?.user_name}

-
-
- {" "} -

- {post?.user_type === "employer" - ? "کارفرما" - : post?.user_type === "user" - ? post?.expertise || "-" - : "-"} -

-
-
-

- {post?.first_name} {post?.last_name} -

-
-
-

{post?.mobile}

-
-
-

{post?.national_code}

-
-
-

{post?.createdAt}

-
-
-

- {post?.status === "accept" - ? "منتشر شده" - : post?.status === "pending" - ? "در انتظار تایید" - : "رد شده"} -

-
-
- -
-
-
- ))} -
- )} - - post.user_id === id).length} - totalPages={totalPages} - currentPage={currentPage} - onPageChange={(page) => setCurrentPage(page)} - /> -
-
-
- - ); -}; - -export default UserPosts; diff --git a/public/modstagram_panel/src/components/users/UserWorkroom.jsx b/public/modstagram_panel/src/components/users/UserWorkroom.jsx deleted file mode 100644 index 1d6e7bb..0000000 --- a/public/modstagram_panel/src/components/users/UserWorkroom.jsx +++ /dev/null @@ -1,200 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import axios from 'axios'; -import { AppBaseUrl } from '../BaseUrl'; -import { useParams } from 'react-router-dom'; -import moment from 'moment-jalaali'; -import { FiUser, FiCalendar, FiClock, FiCheckCircle, FiXCircle, FiAlertCircle } from 'react-icons/fi'; - -const UserWorkroom = () => { - const [projects, setProjects] = useState([]); - const [loading, setLoading] = useState(true); - const [error, setError] = useState(null); - const param = useParams(); - const id = param?.id; - - useEffect(() => { - const fetchProjects = async () => { - try { - const response = await axios.get(`${AppBaseUrl}/offers`, { - params: { status_filter: "دریافت", id }, - }); - - const offersFromSender = response.data.offerbyidsender?.docs || []; - const offersFromReceiver = response.data.offerbyid?.docs || []; - - const mergedOffers = [...offersFromSender, ...offersFromReceiver]; - const sortedOffers = mergedOffers.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt)); - - setProjects(sortedOffers); - } catch (err) { - setError('خطا در بارگذاری درخواست‌ها'); - } finally { - setLoading(false); - } - }; - - fetchProjects(); - }, [id]); - - const formatJalaliDate = (date) => { - if (!date) return 'نامشخص'; - return moment(date).format('jYYYY/jMM/jDD - HH:mm'); - }; - - const StatusTag = ({ status }) => { - const config = { - accepted: { text: 'تایید شده', color: 'bg-green-900/30 text-green-300 border border-green-800', icon: }, - rejected: { text: 'رد شده', color: 'bg-red-900/30 text-red-300 border border-red-800', icon: }, - pending: { text: 'در انتظار', color: 'bg-yellow-900/30 text-yellow-300 border border-yellow-800', icon: }, - }; - - const { text, color, icon } = config[status] || { text: status, color: 'bg-gray-800 text-gray-400 border border-gray-700', icon: null }; - - return ( - - {icon} - {text} - - ); - }; - - if (loading) { - return ( -
-
-
- ); - } - - if (error) { - return ( -
-

{error}

-
- ); - } - - if (projects.length === 0) { - return ( -
- -

هیچ درخواستی یافت نشد.

-
- ); - } - - return ( -
-
-
-

- - لیست درخواست‌ها -

-

مجموع: {projects.length} درخواست

-
- - {/* موبایل: کارت‌ها */} -
- {projects.map((project) => ( -
-
-
-
-

درخواست‌کننده

-

- {project.sender - ? `${project.sender.first_name} ${project.sender.last_name}` - : 'نامشخص'} -

-

@{project.sender?.user_name}

-
- -
- -
-

درخواست‌شونده

-

- {project.receiver - ? `${project.receiver.first_name} ${project.receiver.last_name}` - : 'نامشخص'} -

-

@{project.receiver?.user_name}

-
- -
- - {formatJalaliDate(project.createdAt)} -
- {project.updatedAt && ( -
- - آخرین تغییر: {formatJalaliDate(project.updatedAt)} -
- )} -
-
- ))} -
- - {/* دسکتاپ: جدول */} -
- - - - - - - - - - - - {projects.map((project) => ( - - - - - - - - ))} - -
درخواست‌کنندهدرخواست‌شوندهوضعیتتاریخ ثبتآخرین تغییر
-
-

- {project.sender - ? `${project.sender.first_name} ${project.sender.last_name}` - : 'نامشخص'} -

-

@{project.sender?.user_name}

-
-
-
-

- {project.receiver - ? `${project.receiver.first_name} ${project.receiver.last_name}` - : 'نامشخص'} -

-

@{project.receiver?.user_name}

-
-
- - - {formatJalaliDate(project.createdAt)} - - {project.updatedAt ? formatJalaliDate(project.updatedAt) : '—'} -
-
-
-
- ); -}; - -export default UserWorkroom; \ No newline at end of file diff --git a/public/modstagram_panel/src/index.js b/public/modstagram_panel/src/index.js deleted file mode 100644 index b6adba9..0000000 --- a/public/modstagram_panel/src/index.js +++ /dev/null @@ -1,73 +0,0 @@ -import React from 'react'; -import ReactDOM from 'react-dom/client'; -import './assets/css/index.css'; -import App from './App'; -import toast from 'react-hot-toast'; -import axios from 'axios'; -import { BaseUrl } from './components/BaseUrl'; - -const root = ReactDOM.createRoot(document.getElementById('root')); - -const handleUnauthorized = () => { - localStorage.removeItem("userData"); - localStorage.removeItem("token"); - localStorage.removeItem("login"); - window.location = "/login"; -}; - -const getToken = () => { - const token = localStorage.getItem("token"); - return token == null ? "" : token; -}; -axios.interceptors.request.use( - (config) => { - if (!config.url.endsWith('/panel/login')) { - config.headers["Authorization"] = `Bearer ${getToken()}`; - } - return config; - }, - (error) => { - return Promise.reject(error); - } -); - -axios.interceptors.response.use( - (response) => { - if (response.data.message && response.data.message != "") - toast.success(response.data.message); - return response; - }, - (error) => { - if (error.response.status == 422) { - if (error.response.data.errors) { - Object.keys(error.response.data.errors).map((err) => - error.response.data.errors[err].map((item) => toast.error(item)) - ); - } - - } else if (error.response.status == 401) { - handleUnauthorized(); - } else if ( - error.response.status == 429 || - error.response.status == 500 || - error.response.status == 503 - ) { - toast.error("خطایی رخ داده"); - } else if (error.response.status == 403) { - // window.location.reload(); - toast.error( - "متاسفانه دسترسی شما به بخش هایی از این صفحه محدود شده است" - ); - } else { - toast.error(error.response.data.message); - } - - return Promise.reject(error); - } -); -root.render( - - - -); - diff --git a/public/modstagram_panel/src/pages/Dashboard.jsx b/public/modstagram_panel/src/pages/Dashboard.jsx deleted file mode 100644 index 8418a96..0000000 --- a/public/modstagram_panel/src/pages/Dashboard.jsx +++ /dev/null @@ -1,50 +0,0 @@ -import React, { useState } from "react"; -import { Link } from "react-router-dom"; -import AdminHeader from "../components/admin-header"; -import Sidebar from "../components/sidebar"; - -const items = [ - { id: 1, label: "کاربران جدید", href: "/users?status=pending" }, - { id: 2, label: "پست‌های جدید", href: "/posts?status=pending" }, - { id: 3, label: "بیلبورد جدید", href: "/vitrine?status=pending" }, - { id: 4, label: "نظرات جدید", href: "/comments?status=pending" }, - { id: 5, label: "تیکت جدید", href: "/tickets?status=pending" }, - { id: 6, label: "نظرات بیلبورد جدید", href: "/vitrine-comments?status=pending" }, -]; - -const Dashboard = () => { - const [active, setActive] = useState(null); - - return ( - <> - -
-
-
- -
-
- {items.map((item) => ( - setActive(item.id)} - className={`cursor-pointer rounded-xl border p-6 shadow-md transition block - ${ - active === item.id - ? "bg-cyan-600 text-white font-bold shadow-lg scale-105" - : "bg-[#232a31] hover:bg-[#2a3036] text-gray-200" - }`} - > - {item.label} - - ))} -
-
-
-
- - ); -}; - -export default Dashboard; diff --git a/public/modstagram_panel/src/pages/Login.jsx b/public/modstagram_panel/src/pages/Login.jsx deleted file mode 100644 index 78bf9d2..0000000 --- a/public/modstagram_panel/src/pages/Login.jsx +++ /dev/null @@ -1,116 +0,0 @@ -import React, { useEffect, useState } from "react"; -import { Link, useNavigate } from "react-router-dom"; -import * as Yup from "yup"; -import Loading from "../components/elements/loading"; -import { useAuth } from "../utils/AuthProvider"; -import axios from "axios"; -import { BaseUrl } from "../components/BaseUrl"; -import toast, { useToaster } from "react-hot-toast"; - -const Login = () => { - const navigate = useNavigate(); - const [loading, setloading] = useState(false); - const token = useAuth(); - const [userName, setUserName] = useState("") - const [password, setPassword] = useState("") - useEffect(() => { - if (token !== null) { - navigate("/", { replace: true }); - } - }, []); - const loginHandler = () => { - const data = { - user_name: userName, - password, - }; - axios - .post(`${BaseUrl}/login`, data, { - headers: { - Accept: "application/json", - "Content-Type": "application/json", - }, - }) - .then(async (response) => { - try { - localStorage.setItem("token", response?.data?.token); - document.getElementById("to_dashboard").click(); - } catch (error) { - toast.error("اطلاعات وارد شده صحیح نمیباشد"); - } - }) - .catch(function (error) { - toast.error(error?.response?.data?.message); - }); - } - function refreshPage() { - setTimeout(() => { - window.location.reload(false); - }, 1000); - } - return ( -
- -
-
-
-
- ورود -
-
-
- - setUserName(e.target.value)} - /> -
-
- - setPassword(e.target.value)} - /> -
-
- -
-
-
-
-
-
- ); -}; - -export default Login; diff --git a/public/modstagram_panel/src/pages/academies/academies.jsx b/public/modstagram_panel/src/pages/academies/academies.jsx deleted file mode 100644 index 5a818c5..0000000 --- a/public/modstagram_panel/src/pages/academies/academies.jsx +++ /dev/null @@ -1,412 +0,0 @@ -// src/pages/Academies.js -import React, { useState, useEffect, useCallback } from "react"; -import toast from "react-hot-toast"; -import { - getAcademies, - updateAcademyStatus, - deleteAcademy, - getAcademyStats -} from "../../components/adminApi"; // اصلاح مسیر -import Layout from "../../components/academy/Layout"; -import { FaSearch, FaEdit, FaTrash, FaEye, FaStar, FaUniversity, FaTimes } from "react-icons/fa"; -import { ImageBaseUrl } from "../../components/BaseUrl"; - -// در صورت نیاز به BASE_URL -const IMAGE_BASE_URL = ImageBaseUrl|| ""; - -const Academies = () => { - const [academies, setAcademies] = useState([]); - const [stats, setStats] = useState(null); - const [loading, setLoading] = useState(true); - const [page, setPage] = useState(1); - const [totalPages, setTotalPages] = useState(1); - const [search, setSearch] = useState(""); - const [searchInput, setSearchInput] = useState(""); - const [showModal, setShowModal] = useState(false); - const [selectedAcademy, setSelectedAcademy] = useState(null); - - const fetchAcademies = useCallback(async () => { - setLoading(true); - try { - const response = await getAcademies({ page, limit: 12, search }); - console.log("Academies response:", response.data); - - if (response.data.success) { - const responseData = response.data.data; - setAcademies(responseData?.academies || []); - setStats(responseData?.stats || null); - setTotalPages(responseData?.pagination?.totalPages || 1); - } else { - toast.error(response.data.message || "خطا در دریافت آکادمی‌ها"); - } - } catch (error) { - console.error("Error fetching academies:", error); - toast.error("خطا در دریافت آکادمی‌ها"); - } finally { - setLoading(false); - } - }, [page, search]); - - const fetchStats = async () => { - try { - const response = await getAcademyStats(); - console.log("Stats response:", response.data); - - if (response.data.success) { - setStats(response.data.data); - } - } catch (error) { - console.error("Error fetching stats:", error); - } - }; - - useEffect(() => { - fetchAcademies(); - fetchStats(); - }, [fetchAcademies]); - - const handleStatusChange = async (academyId, status) => { - try { - const response = await updateAcademyStatus({ academyId, status }); - if (response.data.success) { - toast.success("وضعیت آکادمی تغییر کرد"); - fetchAcademies(); - fetchStats(); - } else { - toast.error(response.data.message || "خطا در تغییر وضعیت"); - } - } catch (error) { - console.error("Error updating status:", error); - toast.error("خطا در تغییر وضعیت"); - } - }; - - const handleDelete = async (academyId) => { - if (window.confirm("آیا از حذف این آکادمی مطمئن هستید؟\nتوجه: با حذف آکادمی، تمام دوره‌های آن نیز حذف خواهند شد.")) { - try { - const response = await deleteAcademy(academyId); - if (response.data.success) { - toast.success("آکادمی حذف شد"); - fetchAcademies(); - fetchStats(); - } else { - toast.error(response.data.message || "خطا در حذف آکادمی"); - } - } catch (error) { - console.error("Error deleting academy:", error); - toast.error("خطا در حذف آکادمی"); - } - } - }; - - const handleSearch = (e) => { - e.preventDefault(); - setSearch(searchInput); - setPage(1); - }; - - const handleClearSearch = () => { - setSearchInput(""); - setSearch(""); - setPage(1); - }; - - const getImageUrl = (imagePath) => { - if (!imagePath) return null; - if (imagePath.startsWith("http")) return imagePath; - return `${IMAGE_BASE_URL}${imagePath}`; - }; - - const getStatusText = (status) => { - const statusMap = { - active: { text: "فعال", className: "bg-green-100 text-green-700" }, - inactive: { text: "غیرفعال", className: "bg-gray-100 text-gray-700" }, - blocked: { text: "مسدود", className: "bg-red-100 text-red-700" } - }; - return statusMap[status] || { text: status || "فعال", className: "bg-gray-100 text-gray-700" }; - }; - - - - - if (loading && page === 1) { - return ( - -
-
-
-
- ); - } - - return ( - -
-
-

مدیریت آکادمی‌ها

-

لیست تمام آکادمی‌های ثبت شده در سامانه

-
- - {/* Stats */} - {stats && ( -
-
-
-
-

تعداد آکادمی‌ها

-

{stats.totalAcademies?.toLocaleString() || 0}

-
- -
-
-
-

میانگین امتیاز

-

{stats.avgRate?.toFixed(1) || 0}

-
-
-

مجموع امتیاز

-

{stats.totalRate?.toLocaleString() || 0}

-
-
- )} - - {/* Search */} -
-
- setSearchInput(e.target.value)} - className="w-full px-4 py-3 pl-12 pr-4 border rounded-xl focus:outline-none focus:ring-2 focus:ring-pink-500" - /> - - {searchInput && ( - - )} -
-
- - {/* Search result info */} - {search && ( -
- نتایج جستجو برای: {search} - -
- )} - - {/* Academies Grid */} - {academies.length === 0 && !loading ? ( -
- -

آکادمی‌ای یافت نشد

- {search && ( - - )} -
- ) : ( -
- {academies.map((academy) => { - const statusInfo = getStatusText(academy.status); - return ( -
-
-
- - {statusInfo.text} - -
-
-
-
- {academy.academy_image ? ( - {academy.academy_name} - ) : ( -
- -
- )} -
-
-
-
- -
-
-
-

{academy.academy_name}

-

مدیر: {academy.userId?.user_name || "نامشخص"}

-
-
- - {academy.rate || 0} -
-
- -

- {academy.bio || "توضیحاتی ثبت نشده"} -

- -
-
- - -
- {/* */} -
-
-
- ); - })} -
- )} - - {/* Pagination */} - {totalPages > 1 && ( -
- - - صفحه {page} از {totalPages} - - -
- )} - - {/* Modal */} - {showModal && selectedAcademy && ( -
-
-
-

جزئیات آکادمی

- -
-
-
-
- {selectedAcademy.academy_image ? ( - {selectedAcademy.academy_name} - ) : ( -
- -
- )} -
-
- -
- نام آکادمی: - {selectedAcademy.academy_name} -
-
- مدیر: - {selectedAcademy.userId?.user_name || "-"} -
-
- ایمیل: - {selectedAcademy.userId?.email || "-"} -
-
- امتیاز: - {selectedAcademy.rate || 0} -
-
- تعداد نظرات: - {selectedAcademy.number_of_rate || 0} -
-
- شماره شبا: - {selectedAcademy.sheba || "ثبت نشده"} -
-
- تاریخ ثبت: - {new Date(selectedAcademy.createdAt).toLocaleDateString("fa-IR")} -
-
-

درباره:

-

{selectedAcademy.bio || "توضیحاتی ثبت نشده"}

-
-
-
- -
-
-
- )} -
-
- ); -}; - -export default Academies; \ No newline at end of file diff --git a/public/modstagram_panel/src/pages/academy/academy.jsx b/public/modstagram_panel/src/pages/academy/academy.jsx deleted file mode 100644 index dcdee9f..0000000 --- a/public/modstagram_panel/src/pages/academy/academy.jsx +++ /dev/null @@ -1,293 +0,0 @@ -// src/pages/Dashboard.js -import React, { useState, useEffect } from "react"; -import Layout from "../../components/academy/Layout"; -import { - getPaymentStats, - getCourseStats, - getPurchasedStats, - getAcademyStats, - getPayments, - getCourses -} from "../../components/adminApi"; -import { Link } from "react-router-dom"; -import { FaWallet, FaBook, FaShoppingCart, FaUniversity, FaStar } from "react-icons/fa"; - -const Dashboard = () => { - const [stats, setStats] = useState({ - payments: { totalAmount: 0, totalCount: 0, pendingCount: 0, successCount: 0, settledCount: 0 }, - courses: { totalCourses: 0, acceptCount: 0, pendingCount: 0, normalCount: 0, proCount: 0, legendCount: 0 }, - purchased: { totalPurchases: 0, uniqueUsers: 0 }, - academies: { totalAcademies: 0, avgRate: 0 } - }); - const [loading, setLoading] = useState(true); - const [recentPayments, setRecentPayments] = useState([]); - const [recentCourses, setRecentCourses] = useState([]); - - useEffect(() => { - const fetchStats = async () => { - setLoading(true); - try { - const [paymentsRes, coursesRes, purchasedRes, academiesRes] = await Promise.all([ - getPaymentStats(), - getCourseStats(), - getPurchasedStats(), - getAcademyStats() - ]); - - console.log("Payment Stats:", paymentsRes.data); - console.log("Course Stats:", coursesRes.data); - console.log("Purchased Stats:", purchasedRes.data); - console.log("Academy Stats:", academiesRes.data); - - setStats({ - payments: paymentsRes.data?.data || {}, - courses: coursesRes.data?.data || {}, - purchased: purchasedRes.data?.data || {}, - academies: academiesRes.data?.data || {} - }); - } catch (error) { - console.error("Error fetching stats:", error); - } finally { - setLoading(false); - } - }; - - const fetchRecentData = async () => { - try { - // دریافت 5 پرداخت آخر - const paymentsRes = await getPayments({ page: 1, limit: 5 }); - if (paymentsRes.data?.success) { - setRecentPayments(paymentsRes.data.data?.payments || []); - } - - // دریافت 5 دوره آخر - const coursesRes = await getCourses({ page: 1, limit: 5 }); - if (coursesRes.data?.success) { - setRecentCourses(coursesRes.data.data?.courses || []); - } - } catch (error) { - console.error("Error fetching recent data:", error); - } - }; - - fetchStats(); - fetchRecentData(); - }, []); - - const statCards = [ - // { - // title: "مجموع فروش", - // value: stats.payments.totalAmount?.toLocaleString() || 0, - // unit: "تومان", - // icon: , - // bgColor: "bg-blue-100", - // textColor: "text-blue-600", - // iconBg: "bg-blue-500" - // }, - { - title: "تعداد پرداخت‌ها", - value: stats.payments.totalCount || 0, - unit: "", - icon: , - bgColor: "bg-green-100", - textColor: "text-green-600", - iconBg: "bg-green-500" - }, - { - title: "دوره‌های تایید شده", - value: stats.courses.acceptCount || 0, - unit: "", - subValue: `در انتظار: ${stats.courses.pendingCount || 0}`, - icon: , - bgColor: "bg-purple-100", - textColor: "text-purple-600", - iconBg: "bg-purple-500" - }, - { - title: "کل دوره‌ها", - value: stats.courses.totalCourses || 0, - unit: "", - icon: , - bgColor: "bg-indigo-100", - textColor: "text-indigo-600", - iconBg: "bg-indigo-500" - }, - { - title: "خریدهای انجام شده", - value: stats.purchased.totalPurchases || 0, - unit: "", - icon: , - bgColor: "bg-orange-100", - textColor: "text-orange-600", - iconBg: "bg-orange-500" - }, - { - title: "کاربران خریدار", - value: stats.purchased.uniqueUsers || 0, - unit: "نفر", - icon: , - bgColor: "bg-rose-100", - textColor: "text-rose-600", - iconBg: "bg-rose-500" - }, - { - title: "آکادمی‌ها", - value: stats.academies.totalAcademies || 0, - unit: "", - icon: , - bgColor: "bg-teal-100", - textColor: "text-teal-600", - iconBg: "bg-teal-500" - }, - // { - // title: "میانگین امتیاز", - // value: stats.academies.avgRate?.toFixed(1) || 0, - // unit: "از 5", - // icon: , - // bgColor: "bg-yellow-100", - // textColor: "text-yellow-600", - // iconBg: "bg-yellow-500" - // } - ]; - - const getStatusBadge = (status) => { - const badges = { - pending: "bg-yellow-100 text-yellow-700", - accept: "bg-green-100 text-green-700", - success: "bg-blue-100 text-blue-700", - settled: "bg-purple-100 text-purple-700", - }; - const texts = { - pending: "در انتظار", - accept: "تایید شده", - success: "موفق", - settled: "تسویه شده", - }; - return ( - - {texts[status] || status} - - ); - }; - - console.log(stats); - - - if (loading) { - return ( - -
-
-
-
- ); - } - - return ( - -
-
-

داشبورد مدیریتی

-

خلاصه وضعیت سیستم

-
- - {/* Stat Cards */} -
- {statCards.map((card, index) => ( -
-
-
-

{card.title}

-

- {card.value} - {card.unit && {card.unit}} -

- {card.subValue && ( -

{card.subValue}

- )} -
-
-
{card.icon}
-
-
-
- ))} -
- - {/* Recent Payments & Courses */} -
- {/* آخرین پرداخت‌ها */} -
-
-

آخرین پرداخت‌ها

- - مشاهده همه - -
-
- {recentPayments.length === 0 ? ( -
- - هیچ پرداختی یافت نشد -
- ) : ( -
- {recentPayments.map((payment) => ( -
-
-

{payment.course_id?.cuorse_name || "-"}

-

{payment.user_id?.user_name}

-
-
-

{payment.price?.toLocaleString()} تومان

- {getStatusBadge(payment.status)} -
-
- ))} -
- )} -
-
- - {/* آخرین دوره‌ها */} -
-
-

آخرین دوره‌ها

- - مشاهده همه - -
-
- {recentCourses.length === 0 ? ( -
- - هیچ دوره‌ای یافت نشد -
- ) : ( -
- {recentCourses.map((course) => ( -
-
-

{course.cuorse_name}

-

{course.teacher_name}

-
-
-

{parseInt(course.price).toLocaleString()} تومان

- {getStatusBadge(course.status)} -
-
- ))} -
- )} -
-
-
-
-
- ); -}; - -export default Dashboard; \ No newline at end of file diff --git a/public/modstagram_panel/src/pages/comments/CommentDetail.jsx b/public/modstagram_panel/src/pages/comments/CommentDetail.jsx deleted file mode 100644 index 00407a9..0000000 --- a/public/modstagram_panel/src/pages/comments/CommentDetail.jsx +++ /dev/null @@ -1,286 +0,0 @@ -import React, { useEffect, useState } from 'react' -import { useNavigate, useParams } from 'react-router-dom'; -import { BaseUrl } from '../../components/BaseUrl'; -import axios from 'axios'; -import AdminHeader from '../../components/admin-header'; -import Sidebar from '../../components/sidebar'; -import Loading from '../../components/elements/loading'; -import toast from 'react-hot-toast'; - -const CommentDetail = () => { - const navigate = useNavigate(); - const param = useParams(); - const id = param?.id; - const [loading, setLoading] = useState(false); - const [commentDetails, setCommentDetails] = useState([]); - const [commentStatus, setCommentStatus] = useState(''); - const [editingComment, setEditingComment] = useState(false); - const [newComment, setNewComment] = useState(''); - const getCommentDetails = (page = 1) => { - setLoading(true); - const config = { - url: `${BaseUrl}/comments/detail?comment_id=${id}`, - method: "GET", - }; - axios(config) - .then((res) => { - setCommentDetails(res?.data?.comment); - setLoading(false); - setNewComment(res?.data?.comment?.comment) - }) - .catch((err) => { - setLoading(false); - }); - }; - useEffect(() => { - getCommentDetails(); - }, [id]); - - const acceptComment = () => { - const data = { - id: commentDetails?._id, - status: "accepted", - text: newComment - }; - axios - .post(`${BaseUrl}/comments/accept`, data, { - headers: { - Accept: "application/json", - "Content-Type": "application/json", - }, - }) - .then(async (response) => { - try { - toast.success(response?.data?.message) - getCommentDetails() - } catch (error) { - if ( - error?.response?.data?.error - ) { - toast.error(error.response.data.error); - } else { - // نمایش پیام خطا برای سایر موارد - toast.error("خطای ناشناخته"); - } - } - }) - .catch((error) => { - console.error(error); - toast.show(error?.response?.data?.message, { - type: "danger", - placement: "top", - duration: 4000, - offset: 30, - animationType: "slide-in", - }); - }); - }; - - const rejectComment = () => { - const data = { - id: commentDetails?._id, - status: "rejected" - }; - axios - .post(`${BaseUrl}/comments/accept`, data, { - headers: { - Accept: "application/json", - "Content-Type": "application/json", - }, - }) - .then(async (response) => { - try { - toast.success(response?.data?.message) - getCommentDetails() - } catch (error) { - if ( - error?.response?.data?.error - ) { - toast.error(error.response.data.error); - } else { - // نمایش پیام خطا برای سایر موارد - toast.error("خطای ناشناخته"); - } - } - }) - .catch((error) => { - console.error(error); - toast.show(error?.response?.data?.message, { - type: "danger", - placement: "top", - duration: 4000, - offset: 30, - animationType: "slide-in", - }); - }); - }; - - const handleEditComment = () => { - // ارسال درخواست برای ویرایش کامنت به سرور - // سپس بروزرسانی متغیر مربوط به متن کامنت - setEditingComment(true); - }; - return (<> - {loading && } - {!loading && commentDetails && ( - <> - -
-
-
-
-
-

- اطلاعات کامنت: -

- -
-
-
-
- عنوان پروژه: -
-
- {commentDetails?.project} -
-
-
-
- نام کاربری سازنده: -
-
- {commentDetails?.creator?.user_name} -
-
-
-
- نام و نام خانوادگی سازنده: -
-
- {commentDetails?.creator?.first_name} {commentDetails?.creator?.last_name} -
-
-
-
- نام کاربری کاربر: -
-
- {commentDetails?.user?.user_name} -
-
-
-
- نام و نام خانوادگی کاربر: -
-
- {commentDetails?.user?.first_name} {commentDetails?.user?.last_name} -
-
-
-
- تاریخ ثبت کامنت: -
-
- {commentDetails?.createdAt} -
-
-
-
- تعداد ستاره: -
-
- {commentDetails?.rating} -
-
-
-
- متن کامنت: -
-
- {commentDetails?.comment} -
-
-
-
- وضعیت: -
-
- {commentDetails?.status - === "pending" ? - "در انتظار تایید" : - commentDetails?.status == "accepted" ? - "تایید شده" : - "رد شده" - } -
-
-
-
- {!editingComment ? ( - <> - - - - - ) : ( - <> -
- - -
- - -
-
-
-
-
- دلیل رد پروژه: -
-
- {projectDetails?.reject_reason} -
-
-
-
- کاربران پیشنهاد دهنده : -
-
-
-
-
-

- نام و نام خانوادگی -

-
-
-

- نام کاربری -

-
-
-

- قیمت پینهادی -

-
-
-

- زمان پیشنهادی -

-
-
-
- {projectDetails?.requested_users?.map( - (user, index) => ( -
-
-
-
- -

- { - user?.first_name - }{" "} - { - user?.last_name - } -

-
-
-
-

- { - user?.user_name - } -

-
-
-

- {Number( - user?.price - ).toLocaleString()} -

-
-
-

- { - user?.time - } -

-
- -
-

- -

-
-
-
- ) - )} -
-
-
-
- - )} - - - - - ); -}; - -export default ProjectDetail; diff --git a/public/modstagram_panel/src/pages/projects/Projects.jsx b/public/modstagram_panel/src/pages/projects/Projects.jsx deleted file mode 100644 index 4fe6029..0000000 --- a/public/modstagram_panel/src/pages/projects/Projects.jsx +++ /dev/null @@ -1,161 +0,0 @@ -import React, { useEffect, useState, useMemo } from "react"; -import AdminHeader from "../../components/admin-header"; -import Sidebar from "../../components/sidebar"; -import { useNavigate } from "react-router-dom"; -import { BaseUrl } from "../../components/BaseUrl"; -import axios from "axios"; -import Loading from "../../components/elements/loading"; -import toast from "react-hot-toast"; -import Pagination from "../../components/Pagination"; -import Filters from "../../components/Filters"; - -const statusMap = { - all: { label: "همه", class: "text-yellow-300" }, - pre_payment: { label: "پرداخت نشده", class: "text-yellow-300" }, - paid: { label: "در دست بررسی", class: "text-yellow-300" }, - accepted: { label: "منتشر شده", class: "text-green-300" }, - ongoing: { label: "در دست اقدام", class: "text-green-300" }, - done: { label: "انجام شده", class: "text-green-300" }, - rejected: { label: "رد شده", class: "text-red-300" }, - cancled: { label: "کنسل شده", class: "text-red-300" }, -}; - -const Projects = () => { - const navigate = useNavigate(); - const [loading, setLoading] = useState(false); - const [projectsList, setProjectsList] = useState([]); - const [totalPages, setTotalPages] = useState(0); - const [currentPage, setCurrentPage] = useState(1); - const [filters, setFilters] = useState({ startDate: "", endDate: "", status: "" }); - - const getProjectList = async (page = 1) => { - try { - setLoading(true); - const { startDate, endDate, status } = filters; - const res = await axios.get( - `${BaseUrl}/projects?limit=20&page=${page}${startDate ? "&startDate=" + startDate : "" - }${endDate ? "&endDate=" + endDate : ""}${status ? "&status=" + status : ""}` - ); - setProjectsList(res?.data?.projects || []); - setTotalPages(res?.data?.totalPages || 0); - } catch (err) { - toast.error("خطا در دریافت لیست پروژه‌ها"); - } finally { - setLoading(false); - } - }; - - useEffect(() => { - getProjectList(currentPage); - }, [currentPage, filters]); - - const toggleProjectStatus = async (project) => { - try { - const newStatus = project.status === "accepted" ? "rejected" : "accepted"; - await axios.post(`${BaseUrl}/projects/accept`, { - id: project._id, - user_id: project?.selected_user?._id, - status: newStatus, - }); - toast.success(`پروژه ${newStatus === "accepted" ? "تأیید" : "رد"} شد`); - getProjectList(currentPage); - } catch (error) { - toast.error(error?.response?.data?.message || "خطا در تغییر وضعیت"); - } - }; - - return ( - <> - -
-
-
- {/* فیلترها */} - ({ - key, - label: val.label, - }))} - provinceOptions={[{ value: "", label: "همه استان‌ها" }]} - cityOptions={[{ value: "", label: "همه شهرها" }]} - photographyModelOptions={[{ value: "", label: "همه مدل‌ها" }]} - blockStatusOptions={[{ value: "", label: "همه کاربران" }]} - onFilterChange={setFilters} - /> - - {/* هدر جدول */} -
- {[ - "عنوان پروژه", - "کارفرما", - "کاربر", - "تخصص", - "زمان پیشنهادی", - "زمان نهایی", - "قیمت پیشنهادی", - "قیمت نهایی", - "تاریخ ثبت", - "وضعیت", - "عملیات", - ].map((title, idx) => ( -
{title}
- ))} -
- - {/* لیست پروژه‌ها */} - {loading ? ( -
- -
- ) : ( -
- {projectsList.map((project, index) => { - const statusInfo = statusMap[project?.status] || { label: "-", class: "text-gray-300" }; - return ( -
-
{project?.title}
-
{project?.creator?.first_name} {project?.creator?.last_name}
-
{project?.selected_user?.first_name} {project?.selected_user?.last_name}
-
{project?.expertise}
-
{project?.offer_time}
-
{project?.final_time}
-
{Number(project?.offer_price).toLocaleString()}
-
{Number(project?.final_price).toLocaleString()}
-
{new Date(project?.createdAt).toLocaleDateString("fa-IR")}
-
{statusInfo.label}
-
- - -
-
- ); - })} -
- )} - - {/* صفحه‌بندی */} - setCurrentPage(page)} - /> -
-
- - ); -}; - -export default Projects; diff --git a/public/modstagram_panel/src/pages/purchased/purchased.jsx b/public/modstagram_panel/src/pages/purchased/purchased.jsx deleted file mode 100644 index b0d2108..0000000 --- a/public/modstagram_panel/src/pages/purchased/purchased.jsx +++ /dev/null @@ -1,307 +0,0 @@ -// src/pages/Purchased.js -import React, { useState, useEffect, useCallback } from "react"; -import toast from "react-hot-toast"; -import { getPurchasedCourses, getPurchasedStats } from "../../components/adminApi"; // اصلاح مسیر -import Layout from "../../components/academy/Layout"; -import { FaSearch, FaUser, FaBook, FaCalendar, FaEye, FaTimes } from "react-icons/fa"; - -const Purchased = () => { - const [purchases, setPurchases] = useState([]); - const [stats, setStats] = useState(null); - const [loading, setLoading] = useState(true); - const [page, setPage] = useState(1); - const [totalPages, setTotalPages] = useState(1); - const [search, setSearch] = useState(""); - const [searchInput, setSearchInput] = useState(""); - const [selectedPurchase, setSelectedPurchase] = useState(null); - const [showModal, setShowModal] = useState(false); - - const fetchPurchases = useCallback(async () => { - setLoading(true); - try { - const response = await getPurchasedCourses({ page, limit: 15, search }); - console.log("Purchased response:", response.data); - - if (response.data.success) { - const responseData = response.data.data; - setPurchases(responseData?.purchases || []); - setStats(responseData?.stats || null); - setTotalPages(responseData?.pagination?.totalPages || 1); - } else { - toast.error(response.data.message || "خطا در دریافت اطلاعات"); - } - } catch (error) { - console.error("Error fetching purchases:", error); - toast.error("خطا در دریافت اطلاعات"); - } finally { - setLoading(false); - } - }, [page, search]); - - const fetchStats = async () => { - try { - const response = await getPurchasedStats(); - console.log("Stats response:", response.data); - - if (response.data.success) { - setStats(response.data.data); - } - } catch (error) { - console.error("Error fetching stats:", error); - } - }; - - useEffect(() => { - fetchPurchases(); - fetchStats(); - }, [fetchPurchases]); - - const handleSearch = (e) => { - e.preventDefault(); - setSearch(searchInput); - setPage(1); - }; - - const handleClearSearch = () => { - setSearchInput(""); - setSearch(""); - setPage(1); - }; - - const getImageUrl = (imagePath) => { - if (!imagePath) return null; - if (imagePath.startsWith("http")) return imagePath; - // اگر نیاز به BASE_URL داری، اینجا اضافه کن - return imagePath; - }; - - if (loading && page === 1) { - return ( - -
-
-
-
- ); - } - - return ( - -
-
-

دوره‌های خریداری شده

-

لیست تمام دوره‌هایی که کاربران خریداری کرده‌اند

-
- - {/* Stats */} - {stats && ( -
-
-
-
-

تعداد کل خریدها

-

{stats.totalPurchases?.toLocaleString() || 0}

-
- -
-
-
-
-
-

کاربران خریدار

-

{stats.uniqueUsers?.toLocaleString() || 0}

-
- -
-
-
- )} - - {/* Search */} -
-
- setSearchInput(e.target.value)} - className="w-full px-4 py-3 pl-12 pr-4 border rounded-xl focus:outline-none focus:ring-2 focus:ring-pink-500" - /> - - {searchInput && ( - - )} -
-
- - {/* Search result info */} - {search && ( -
- نتایج جستجو برای: {search} - -
- )} - - {/* Purchases List */} -
- {purchases.length === 0 && !loading ? ( -
- -

هیچ خریدی یافت نشد

- {search && ( - - )} -
- ) : ( - purchases.map((purchase) => ( -
-
-
-
-
- {purchase.course_id?.course_image ? ( - {purchase.course_id?.cuorse_name} - ) : ( - - )} -
-
-

{purchase.course_id?.cuorse_name || "نامشخص"}

-

مدرس: {purchase.course_id?.teacher_name || "نامشخص"}

-
- - - {purchase.user_id?.user_name || "کاربر ناشناس"} - - - - {new Date(purchase.createdAt).toLocaleDateString("fa-IR")} - -
-
-
-
-
-
- {parseInt(purchase.course_id?.price || 0).toLocaleString()} تومان -
- -
-
-
- )) - )} -
- - {/* Pagination */} - {totalPages > 1 && ( -
- - - صفحه {page} از {totalPages} - - -
- )} - - {/* Modal */} - {showModal && selectedPurchase && ( -
-
-
-

جزئیات خرید

- -
-
-
- کاربر: - {selectedPurchase.user_id?.user_name || "-"} -
- {/*
- ایمیل: - {selectedPurchase.user_id?.email || "-"} -
*/} -
- دوره: - {selectedPurchase.course_id?.cuorse_name || "-"} -
-
- مدرس: - {selectedPurchase.course_id?.teacher_name || "-"} -
-
- تاریخ خرید: - {new Date(selectedPurchase.createdAt).toLocaleDateString("fa-IR")} -
- {selectedPurchase.payment_ref_id && ( -
- کد پیگیری: - {selectedPurchase.payment_ref_id} -
- )} -
-
- -
-
-
- )} -
-
- ); -}; - -export default Purchased; \ No newline at end of file diff --git a/public/modstagram_panel/src/pages/settings/settings.jsx b/public/modstagram_panel/src/pages/settings/settings.jsx deleted file mode 100644 index 4640fcd..0000000 --- a/public/modstagram_panel/src/pages/settings/settings.jsx +++ /dev/null @@ -1,281 +0,0 @@ -// src/pages/Settings.js -import React, { useState, useEffect } from "react"; -import toast from "react-hot-toast"; -import { getAllSettings, updateAllSettings } from "../../components/adminApi"; -import Layout from "../../components/academy/Layout"; -import { FaSave, FaPercent, FaGem, FaSpinner, FaExclamationTriangle } from "react-icons/fa"; - -const Settings = () => { - const [settings, setSettings] = useState({ - tax: 8, - proPrice: "60000", - legendPrice: "199000", - }); - const [loading, setLoading] = useState(true); - const [saving, setSaving] = useState(false); - const [errors, setErrors] = useState({}); - - const fetchSettings = async () => { - setLoading(true); - try { - const response = await getAllSettings(); - console.log("Settings response:", response.data); - - if (response.data.success) { - setSettings({ - tax: response.data.data.tax || 8, - proPrice: response.data.data.prices?.pro || "60000", - legendPrice: response.data.data.prices?.legend || "199000", - }); - } else { - toast.error(response.data.message || "خطا در دریافت تنظیمات"); - } - } catch (error) { - console.error("Error fetching settings:", error); - toast.error("خطا در دریافت تنظیمات"); - } finally { - setLoading(false); - } - }; - - useEffect(() => { - fetchSettings(); - }, []); - - const validateSettings = () => { - const newErrors = {}; - - // اعتبارسنجی مالیات - const taxNum = parseFloat(settings.tax); - if (isNaN(taxNum)) { - newErrors.tax = "مقدار مالیات باید عدد باشد"; - } else if (taxNum < 0) { - newErrors.tax = "مالیات نمی‌تواند منفی باشد"; - } else if (taxNum > 100) { - newErrors.tax = "مالیات نمی‌تواند بیشتر از 100 درصد باشد"; - } - - // اعتبارسنجی قیمت پرو - const proPriceNum = parseInt(settings.proPrice); - if (isNaN(proPriceNum)) { - newErrors.proPrice = "قیمت پرو باید عدد باشد"; - } else if (proPriceNum < 0) { - newErrors.proPrice = "قیمت نمی‌تواند منفی باشد"; - } - - // اعتبارسنجی قیمت لجند - const legendPriceNum = parseInt(settings.legendPrice); - if (isNaN(legendPriceNum)) { - newErrors.legendPrice = "قیمت لجند باید عدد باشد"; - } else if (legendPriceNum < 0) { - newErrors.legendPrice = "قیمت نمی‌تواند منفی باشد"; - } - - setErrors(newErrors); - return Object.keys(newErrors).length === 0; - }; - - const handleChange = (e) => { - const { name, value } = e.target; - setSettings({ - ...settings, - [name]: value, - }); - // پاک کردن خطای مربوط به این فیلد - if (errors[name]) { - setErrors({ ...errors, [name]: "" }); - } - }; - - const handleSubmit = async (e) => { - e.preventDefault(); - - // اعتبارسنجی - if (!validateSettings()) { - toast.error("لطفاً مقادیر را به درستی وارد کنید"); - return; - } - - setSaving(true); - try { - const response = await updateAllSettings({ - tax: parseFloat(settings.tax), - proPrice: parseInt(settings.proPrice) || 0, - legendPrice: parseInt(settings.legendPrice) || 0, - }); - - console.log("Save response:", response.data); - - if (response.data.success) { - toast.success("تنظیمات با موفقیت ذخیره شد"); - fetchSettings(); // رفرش کردن مقادیر از سرور - } else { - toast.error(response.data.message || "خطا در ذخیره تنظیمات"); - } - } catch (error) { - console.error("Error saving settings:", error); - toast.error(error.response?.data?.message || "خطا در ذخیره تنظیمات"); - } finally { - setSaving(false); - } - }; - - if (loading) { - return ( - -
-
-
-
- ); - } - - return ( - -
-
-

تنظیمات سیستم

-

مدیریت مالیات و قیمت دوره‌های ویژه

-
- -
- {/* درصد مالیات */} -
-
-
- -
-

درصد مالیات (تکس)

-
-
-
- - {errors.tax && ( -

- - {errors.tax} -

- )} -
- درصد -
-

- این درصد به مبلغ هر فروش اضافه خواهد شد (محدوده: 0 تا 100) -

-
- - {/* قیمت دوره‌های ویژه */} -
-
-
- -
-

قیمت دوره‌های ویژه

-
-
-
- دوره پرو: -
- - {errors.proPrice && ( -

- - {errors.proPrice} -

- )} -
- تومان -
-
- دوره لجند: -
- - {errors.legendPrice && ( -

- - {errors.legendPrice} -

- )} -
- تومان -
-
-

- قیمت دوره معمولی از قیمت تعیین شده توسط آکادمی محاسبه می‌شود -

-
- - {/* دکمه ذخیره */} -
- - -
-
- - {/* توضیحات پایین صفحه */} -
-

ℹ️ نکات مهم:

-
    -
  • تغییر مالیات بر روی تمام فروش‌های جدید تأثیر می‌گذارد
  • -
  • قیمت دوره‌های پرو و لجند برای ساخت دوره‌های جدید اعمال می‌شود
  • -
  • دوره‌های موجود با قیمت قبلی خود باقی می‌مانند
  • -
-
-
-
- ); -}; - -export default Settings; \ No newline at end of file diff --git a/public/modstagram_panel/src/pages/shops/ShopDetail.jsx b/public/modstagram_panel/src/pages/shops/ShopDetail.jsx deleted file mode 100644 index bacb31a..0000000 --- a/public/modstagram_panel/src/pages/shops/ShopDetail.jsx +++ /dev/null @@ -1,106 +0,0 @@ -import React, { useEffect, useState } from "react"; -import AdminHeader from "../../components/admin-header"; -import Sidebar from "../../components/sidebar"; -import Loading from "../../components/elements/loading"; -import { BaseUrl, ImageBaseUrl } from "../../components/BaseUrl"; -import axios from "axios"; -import { useNavigate, useParams } from "react-router-dom"; -import ShopDet from "../../components/shops/ShopDet"; - -const ShopDetail = () => { - const navigate = useNavigate(); - const param = useParams(); - const id = param?.id; - const [loading, setLoading] = useState(false); - const [section, setSection] = useState(0); - const sectionTitles = [ - "جزئیات", - // "تبلیغ ها", - ]; - const [shopDetails, setShopDetails] = useState([]); - const getUserDetails = (page = 1) => { - setLoading(true); - const config = { - url: `${BaseUrl}/shops/detail?profile_id=${id}`, - method: "GET", - }; - axios(config) - .then((res) => { - setShopDetails(res?.data?.shop); - setLoading(false); - }) - .catch((err) => { - setLoading(false); - }); - }; - useEffect(() => { - getUserDetails(); - }, [id]); - const sectionItems = [ - , - - ]; - return ( - <> - -
-
-
-
-
-

- اطلاعات کاربر: -

- -
-
- {sectionTitles?.map((title, index) => ( - - ))} -
- {loading ? ( -
- -
- ) : ( - sectionItems?.filter( - (item, index) => index == section - ) - )} -
-
-
- - ); -}; - -export default ShopDetail; diff --git a/public/modstagram_panel/src/pages/shops/Shops.jsx b/public/modstagram_panel/src/pages/shops/Shops.jsx deleted file mode 100644 index e236ee6..0000000 --- a/public/modstagram_panel/src/pages/shops/Shops.jsx +++ /dev/null @@ -1,203 +0,0 @@ -import React, { useEffect, useState } from "react"; -import AdminHeader from "../../components/admin-header"; -import Sidebar from "../../components/sidebar"; -import Loading from "../../components/elements/loading"; -import { BaseUrl, ImageBaseUrl } from "../../components/BaseUrl"; -import axios from "axios"; -import { useNavigate } from "react-router-dom"; -import Pagination from "../../components/Pagination"; - -const Shops = () => { - const navigate = useNavigate(); - const [loading, setLoading] = useState(false); - const [shopsList, setShopList] = useState([]); - const [totalPages, setTotalPages] = useState(0); - const [currentPage, setCurrentPage] = useState(1); - const getUserList = (page = 1) => { - setLoading(true); - const config = { - url: `${BaseUrl}/shops?limit=20&page=${page}`, - method: "GET", - }; - axios(config) - .then((res) => { - setShopList(res?.data?.shops); - setTotalPages(res?.data?.totalPages); // دریافت تعداد صفحات از API - setLoading(false); - }) - .catch((err) => { - setLoading(false); - }); - }; - useEffect(() => { - getUserList(currentPage); - }, [currentPage]); - return ( - <> - -
-
-
-
-
-
-
-

- نام و نام خانوادگی کاربر -

-
-
-

- عنوان فروشگاه -

-
-
-

- دسته بندی -

-
-
-

- استان -

-
-
-

- شهر -

-
-
-

- محله -

-
-
-

- تاریخ ایجاد فروشگاه -

-
- {/*
-

- وضعیت -

-
*/} -
-

-
-
-
- {loading ? ( -
- -
- ) : ( -
- {shopsList?.map((shop, index) => ( -
-
-
-
- -

- {shop?.first_name}{" "} - {shop?.last_name} -

-
-
-
-

- {shop?.vitrine_name} -

-
-
-

- {shop?.category} -

-
-
-

- {shop?.province?.name} -

-
-
-

- {shop?.city?.name} -

-
-
-

- {shop?.neighbourhood} -

-
-
-

- {shop?.createdAt} -

-
- {/*
-
-

- {shop?.blocked - ? "غیر فعال" - : "فعال"} -

- {shop?.blocked ? ( - - ) : ( - - )} -
-
*/} -
-

- -

-
-
-
- ))} -
- )} - - setCurrentPage(page)} // تغییر صفحه - /> -
-
-
- - ); -}; - -export default Shops; diff --git a/public/modstagram_panel/src/pages/terms/TermsAndConditionsEditor.js b/public/modstagram_panel/src/pages/terms/TermsAndConditionsEditor.js deleted file mode 100644 index 87ee1af..0000000 --- a/public/modstagram_panel/src/pages/terms/TermsAndConditionsEditor.js +++ /dev/null @@ -1,107 +0,0 @@ -import React, { useEffect, useState } from "react"; -import ReactQuill from "react-quill"; -import "react-quill/dist/quill.snow.css"; -import AdminHeader from "../../components/admin-header"; -import Sidebar from "../../components/sidebar"; -import axios from "axios"; -import { BaseUrl } from "../../components/BaseUrl"; -import toast from "react-hot-toast"; - -const TermsAndConditionsEditor = () => { - const [editorContent, setEditorContent] = useState(""); - - useEffect(() => { - // دریافت قوانین و مقررات موجود از سرور در بارگذاری اولیه - axios - .get(`${BaseUrl}/settings/terms-and-conditions`) - .then((response) => { - setEditorContent(response.data.value); - }) - .catch((error) => { - console.error("Error fetching terms and conditions:", error); - }); - }, []); - - const handleSave = () => { - axios - .put(`${BaseUrl}/settings/terms-and-conditions`, { value: editorContent }, { - headers: { - Accept: "application/json", - "Content-Type": "application/json", - }, - }) - .then((response) => { - toast.success(response?.data?.message) - // نمایش پیغام موفقیت (در صورت نیاز از toast یا هر کتابخانه مشابه دیگر استفاده کنید) - }) - .catch((error) => { - console.error("Error updating terms and conditions:", error); - // نمایش پیغام خطا (در صورت نیاز از toast یا هر کتابخانه مشابه دیگر استفاده کنید) - }); - }; - return ( - <> - -
-
-
-
-

ویرایشگر قوانین و مقررات

- - -
-
-
- - ); -}; - -TermsAndConditionsEditor.modules = { - toolbar: [ - [ - { header: "1" }, - { header: "2" }, - { header: "3" }, - { header: "4" }, - { header: "5" }, - { header: "6" }, - { font: [] }, - ], - [{ list: "ordered" }, { list: "bullet" }], - ["bold", "italic", "underline", "strike", "blockquote"], - [{ align: [] }], - [{ color: [] }, { background: [] }], - ["link"], - ["clean"], - ], -}; - -TermsAndConditionsEditor.formats = [ - "header", - "font", - "list", - "bullet", - "bold", - "italic", - "underline", - "strike", - "blockquote", - "align", - "color", - "background", - "link", -]; - -export default TermsAndConditionsEditor; diff --git a/public/modstagram_panel/src/pages/tickets/TicketDetail.jsx b/public/modstagram_panel/src/pages/tickets/TicketDetail.jsx deleted file mode 100644 index 93b6a5d..0000000 --- a/public/modstagram_panel/src/pages/tickets/TicketDetail.jsx +++ /dev/null @@ -1,176 +0,0 @@ -import React, { useEffect, useState } from "react"; -import AdminHeader from "../../components/admin-header"; -import Sidebar from "../../components/sidebar"; -import { useNavigate, useParams } from "react-router-dom"; -import { BaseUrl, ImageBaseUrl } from "../../components/BaseUrl"; -import axios from "axios"; -import Loading from "../../components/elements/loading"; -import Modal from 'react-modal'; -const customStyles = { - content: { - top: '50%', - left: '50%', - transform: 'translate(-50%, -50%)', - position: "fixed", - }, -}; -const TicketDetail = () => { - const param = useParams(); - console.log(param); - const ticketId = param?.id; - const status = param?.status - const navigate = useNavigate(); - const [loading, setLoading] = useState(false); - const [messageList, setMessageList] = useState([]); - const [newMessage, setNewMessage] = useState(""); - const [modalIsOpen, setModalIsOpen] = useState(false); - const [modalImage, setModalImage] = useState(''); - - const openModal = (image) => { - setModalImage(image); - setModalIsOpen(true); - } - - const closeModal = () => { - setModalIsOpen(false); - } - const getMessageList = (page = 1) => { - setLoading(true); - const config = { - url: `${BaseUrl}/tickets/messages?ticketId=${ticketId}&page=${page}&limit=20`, - method: "GET", - }; - axios(config) - .then((res) => { - setMessageList(res?.data?.messages); - setLoading(false); - }) - .catch((err) => { - setLoading(false); - }); - }; - useEffect(() => { - getMessageList(); - }, []); - const handleSendMessage = () => { - if (!newMessage.trim()) return; - - const config = { - url: `${BaseUrl}/tickets/message`, - method: "POST", - data: { - ticketId, - text: newMessage, - }, - }; - axios(config) - .then((res) => { - setNewMessage(""); - getMessageList(); - }) - .catch((err) => { - console.error(err); - }); - }; - - const handleCloseTicket = () => { - const config = { - url: `${BaseUrl}/tickets/close`, - method: "POST", - data: { ticketId }, - }; - axios(config) - .then((res) => { - navigate(-1); - }) - .catch((err) => { - console.error(err); - }); - } - - return ( - <> - -
- -
-

آیا مطمئنید میخواهید تیکت را ببندید ؟

-
- - -
-
-
-
- -
- {loading ? ( - - ) : ( -
- {messageList.map((message) => ( -
-
- {message.senderType === "Admin" ? "Admin" : `${message.senderId?.first_name} ${message.senderId?.last_name}`} -
-
{message.createdAt}
-
{message.text}
- {message.file && ( - - )} -
- ))} -
- )} -
- - { - status && status == "Closed" && "تیکت بسته شده است" - } - - { - status !== "Closed" && - <> - - -
- - - -
- - } -
-
-
-
- - ); -}; - -export default TicketDetail; diff --git a/public/modstagram_panel/src/pages/tickets/Tickets.jsx b/public/modstagram_panel/src/pages/tickets/Tickets.jsx deleted file mode 100644 index 098fee6..0000000 --- a/public/modstagram_panel/src/pages/tickets/Tickets.jsx +++ /dev/null @@ -1,208 +0,0 @@ -import React, { useCallback, useEffect, useState } from "react"; -import AdminHeader from "../../components/admin-header"; -import Sidebar from "../../components/sidebar"; -import { useLocation, useNavigate } from "react-router-dom"; -import { BaseUrl } from "../../components/BaseUrl"; -import axios from "axios"; -import Loading from "../../components/elements/loading"; -import Pagination from "../../components/Pagination"; -import Filters from "../../components/Filters"; - -const Tickets = () => { - const navigate = useNavigate(); - const location = useLocation(); // اضافه شد - const [loading, setLoading] = useState(false); - const [ticketList, setTicketList] = useState([]); - const [totalPages, setTotalPages] = useState(0); - const [currentPage, setCurrentPage] = useState(1); - - const [filters, setFilters] = useState({ startDate: "", endDate: "", status: "" }); - - const getTicketList = useCallback((page = 1) => { - setLoading(true); - - // بررسی پارامتر URL - const urlParams = new URLSearchParams(location.search); - let statusParam = filters.status; - - if (urlParams.get("status") === "pending") { - statusParam = "Customer Response"; // فقط تیکت‌های در انتظار پاسخ - } - - const { startDate, endDate } = filters; - - const config = { - url: `${BaseUrl}/tickets?limit=20&page=${page}${ - startDate ? "&startDate=" + startDate : "" - }${endDate ? "&endDate=" + endDate : ""}${statusParam ? "&status=" + statusParam : ""}`, - method: "GET", - }; - - axios(config) - .then((res) => { - setTicketList(res?.data?.tickets || []); - setTotalPages(res?.data?.totalPages || 0); - }) - .catch(() => { - setTicketList([]); - }) - .finally(() => setLoading(false)); - }, [filters, location.search]); - - useEffect(() => { - getTicketList(currentPage); - }, [currentPage, filters, getTicketList]); - - return ( - <> - -
-
-
-
- -
-
-
-

- نام کاربری -

-
-
-

- نوع کاربری -

-
-
-

- نام و نام خانوادگی -

-
-
-

- موبایل -

-
-
-

- تاریخ ثبت تیکت -

-
-
-

- وضعیت -

-
-
-

-
-
-
- {loading ? ( -
- -
- ) : ( -
- {ticketList?.map((ticket, index) => ( -
-
-
-

- {ticket?.user?.user_name} -

-
-
-

- {ticket?.user?.expertise} - -

-
-
-

- {ticket?.user?.first_name}{" "}{ticket?.user?.last_name} -

-
-
-

- {ticket?.user?.mobile} -

-
-
-
-

- {ticket?.createdAt} -

-
-
-
-
-

- {ticket?.status === "Pending" ? - "در انتظار پاسخ" : - ticket?.status === "Answered" ? - "پاسخ داده شده" : - ticket?.status === "Customer Response" ? - "پاسخ مشتری" : "بسته شده"} -

-
-
-
-

- -

-
-
-
- ))} -
- )} - setCurrentPage(page)} // تغییر صفحه - /> -
-
-
- - ); -}; - -export default Tickets; diff --git a/public/modstagram_panel/src/pages/users/UserDetail.jsx b/public/modstagram_panel/src/pages/users/UserDetail.jsx deleted file mode 100644 index 2d45e9f..0000000 --- a/public/modstagram_panel/src/pages/users/UserDetail.jsx +++ /dev/null @@ -1,122 +0,0 @@ -import React, { useEffect, useState } from "react"; -import AdminHeader from "../../components/admin-header"; -import Sidebar from "../../components/sidebar"; -import Loading from "../../components/elements/loading"; -import { BaseUrl, ImageBaseUrl } from "../../components/BaseUrl"; -import axios from "axios"; -import { useNavigate, useParams } from "react-router-dom"; -import UserPosts from "../../components/users/UserPosts"; -import UserDet from "../../components/users/UserDet"; -import UserWorkroom from "../../components/users/UserWorkroom"; -import UserComments from "../../components/users/UserComments"; -import UserMessages from "../../components/users/UserMessages"; -import UserFinancial from "../../components/users/UserFinancial"; -import UserChangePassword from "../../components/users/UserChangePassword"; - -const UserDetail = () => { - const navigate = useNavigate(); - const param = useParams(); - const id = param?.id; - const [loading, setLoading] = useState(false); - const [section, setSection] = useState(0); - const sectionTitles = [ - "جزئیات", - "پستها", - "درخواستها", - "نظرات", - "پیامها", - "مالی", - "تغییر رمز عبور", - ]; - const [userDetails, setUsersDetails] = useState([]); - const getUserDetails = (page = 1) => { - setLoading(true); - const config = { - url: `${BaseUrl}/users/detail?user_id=${id}`, - method: "GET", - }; - axios(config) - .then((res) => { - setUsersDetails(res?.data?.user); - setLoading(false); - }) - .catch((err) => { - setLoading(false); - }); - }; - useEffect(() => { - getUserDetails(); - }, [id]); - const sectionItems = [ - , - , - , - , - , - , - , - ]; - return ( - <> - -
-
-
-
-
-

- اطلاعات کاربر: -

- -
-
- {sectionTitles?.map((title, index) => ( - - ))} -
- {loading ? ( -
- -
- ) : ( - sectionItems?.filter( - (item, index) => index == section - ) - )} -
-
-
- - ); -}; - -export default UserDetail; diff --git a/public/modstagram_panel/src/pages/users/Users.jsx b/public/modstagram_panel/src/pages/users/Users.jsx deleted file mode 100644 index ec6c09f..0000000 --- a/public/modstagram_panel/src/pages/users/Users.jsx +++ /dev/null @@ -1,438 +0,0 @@ -import React, { useEffect, useState } from "react"; -import Sidebar from "../../components/sidebar"; -import Loading from "../../components/elements/loading"; -import { BaseUrl, ImageBaseUrl } from "../../components/BaseUrl"; -import axios from "axios"; -import { useNavigate, useSearchParams } from "react-router-dom"; -import Pagination from "../../components/Pagination"; -import Filters from "../../components/Filters"; -import { FaCheck, FaTimes, FaInfoCircle, FaMoon, FaSun } from "react-icons/fa"; - -// تابع کمکی برای تبدیل تاریخ شمسی به فرمت قابل مقایسه -const parsePersianDate = (dateStr) => { - if (!dateStr) return null; - const [year, month, day] = dateStr.split(" ")[0].split("-").map(Number); - // تبدیل تاریخ شمسی به میلادی برای مقایسه (تقریبی) - const gregorianYear = year - 621; // تقریبی: 1404 شمسی ≈ 2025 میلادی - return new Date(gregorianYear, month - 1, day); -}; - -// تابع فرمت تاریخ شمسی برای نمایش -const formatPersianDate = (dateStr) => { - if (!dateStr) return "-"; - return dateStr.split(" ")[0]; // فقط تاریخ (مثل 1404-07-04) -}; - -// کامپوننت اصلی صفحه کاربران -const Users = () => { - const navigate = useNavigate(); - const [loading, setLoading] = useState(false); - const [allUsers, setAllUsers] = useState([]); // ذخیره همه کاربران - const [filteredUsers, setFilteredUsers] = useState([]); // کاربران فیلترشده - const [totalPages, setTotalPages] = useState(0); - const [currentPage, setCurrentPage] = useState(1); - const [error, setError] = useState(""); // حالت خطا - const [filters, setFilters] = useState({ - startDate: "", - endDate: "", - status: "", - province: "", - city: "", - photographyModel: "", - blockStatus: "", - }); - const [searchQuery, setSearchQuery] = useState(""); - const [darkMode, setDarkMode] = useState(false); - - // لیست‌های دینامیک برای فیلترها - const [provinces, setProvinces] = useState([{ value: "", label: "همه استان‌ها" }]); - const [cities, setCities] = useState({ "": [{ value: "", label: "همه شهرها" }] }); - const [photographyModels, setPhotographyModels] = useState([{ value: "", label: "همه مدل‌ها" }]); - - const itemsPerPage = 20; - - const blockStatusOptions = [ - { value: "", label: "همه وضعیت‌ها" }, - { value: "active", label: "فعال" }, - { value: "inactive", label: "غیرفعال" }, - ]; - - const statusOptions = [ - { key: "", label: "همه وضعیت‌ها" }, - { key: "none", label: "بدون مدارک" }, - { key: "pending", label: "در انتظار تایید" }, - { key: "verified", label: "تایید شده" }, - { key: "rejected", label: "رد شده" }, - ]; - - // تابع استخراج لیست‌های فیلتر از کاربران - const extractFilterOptions = (users) => { - // استخراج استان‌ها - const provinceSet = new Map(); - users.forEach((user) => { - if (user.province?.id && user.province?.name && !provinceSet.has(String(user.province.id))) { - provinceSet.set(String(user.province.id), user.province.name); - } - }); - const provinceList = [ - { value: "", label: "همه استان‌ها" }, - ...Array.from(provinceSet, ([value, label]) => ({ value, label })) - .sort((a, b) => a.label.localeCompare(b.label)), // مرتب‌سازی الفبایی - ]; - setProvinces(provinceList); - console.log("استان‌های استخراج‌شده:", provinceList); - - // استخراج شهرها بر اساس استان - const cityMap = {}; - users.forEach((user) => { - const provId = String(user.province?.id || ""); - if (!cityMap[provId]) cityMap[provId] = new Map(); - if (user.city?.id && user.city?.name && !cityMap[provId].has(String(user.city.id))) { - cityMap[provId].set(String(user.city.id), user.city.name); - } - }); - const cityObj = { "": [{ value: "", label: "همه شهرها" }] }; - Object.keys(cityMap).forEach((provId) => { - cityObj[provId] = [ - { value: "", label: "همه شهرها" }, - ...Array.from(cityMap[provId], ([value, label]) => ({ value, label })) - .sort((a, b) => a.label.localeCompare(b.label)), // مرتب‌سازی الفبایی - ]; - }); - setCities(cityObj); - console.log("شهرهای استخراج‌شده:", cityObj); - - // استخراج مدل‌های عکاسی - const modelSet = new Set(); - users.forEach((user) => { - if (user.sub_expertise) { - user.sub_expertise.forEach((model) => modelSet.add(model)); - } - }); - const modelList = [ - { value: "", label: "همه مدل‌ها" }, - ...Array.from(modelSet, (value) => ({ value, label: value })) - .sort((a, b) => a.label.localeCompare(b.label)), // مرتب‌سازی الفبایی - ]; - setPhotographyModels(modelList); - console.log("مدل‌های عکاسی استخراج‌شده:", modelList); - }; - - // تابع تغییر وضعیت کاربر (فعال/غیرفعال) - const toggleUserStatus = async (userId, currentStatus) => { - try { - await axios.post( - `${BaseUrl}/users/update-status`, - { userId, block_status: !currentStatus }, - { - headers: { Authorization: `Bearer ${localStorage.getItem("token")}` }, - } - ); - // به‌روزرسانی حالت محلی - setAllUsers((prev) => - prev.map((u) => (u._id === userId ? { ...u, block_status: !currentStatus } : u)) - ); - } catch (err) { - console.error("خطا در تغییر وضعیت کاربر:", err); - setError("خطا در تغییر وضعیت کاربر. لطفاً دوباره تلاش کنید."); - } - }; - - // تابع تایید یا رد تصویر پروفایل - const handleApproveProfileImage = async (userId, approve) => { - try { - await axios.put( - `${BaseUrl}/users/update?userId=${userId}`, - { - approveProfileImage: approve, - ...(approve === false && { profile_image: "" }), - }, - { - headers: { Authorization: `Bearer ${localStorage.getItem("token")}` }, - } - ); - // به‌روزرسانی حالت محلی - setAllUsers((prev) => - prev.map((u) => (u._id === userId ? { ...u, profile_image: approve ? u.profile_image : "" } : u)) - ); - } catch (err) { - console.error("خطا در تایید/رد تصویر پروفایل:", err); - setError("خطا در تایید/رد تصویر پروفایل. لطفاً دوباره تلاش کنید."); - } - }; - - // تابع دریافت کاربران از API - const fetchUsers = () => { - setLoading(true); - setError(""); - const url = `${BaseUrl}/users?limit=1000`; // دریافت تعداد زیادی کاربر - console.log("درخواست API:", url); - - axios - .get(url, { - headers: { Authorization: `Bearer ${localStorage.getItem("token")}` }, - }) - .then((res) => { - if (res?.data?.users) { - console.log("داده‌های کاربران:", res.data.users); - setAllUsers(res.data.users); - extractFilterOptions(res.data.users); // استخراج گزینه‌های فیلتر - } else { - setAllUsers([]); - setError("داده‌ای از سرور دریافت نشد."); - } - setLoading(false); - }) - .catch((err) => { - console.error("خطا در دریافت کاربران:", err); - setError("خطا در دریافت لیست کاربران. لطفاً دوباره تلاش کنید."); - setLoading(false); - }); - }; - - // تابع اعمال فیلترهای محلی - const applyFilters = () => { - let result = [...allUsers]; - - // فیلتر جستجو - if (searchQuery) { - const query = searchQuery.toLowerCase(); - result = result.filter( - (user) => - user.first_name?.toLowerCase().includes(query) || - user.last_name?.toLowerCase().includes(query) || - user.user_name?.toLowerCase().includes(query) || - user.mobile?.toLowerCase().includes(query) - ); - } - - // فیلتر وضعیت مدارک - if (filters.status) { - result = result.filter((user) => user.is_verified === filters.status); - } - - - if (statusParam === "pending") { - result = result.filter((user) => user.is_verified === "pending"); - } - - // فیلتر استان - if (filters.province) { - result = result.filter((user) => String(user.province?.id) === filters.province); - } - if (filters.city) { - result = result.filter((user) => String(user.city?.id) === filters.city); - } - if (filters.photographyModel) { - result = result.filter((user) => user.sub_expertise?.includes(filters.photographyModel)); - } - if (filters.blockStatus) { - const isActive = filters.blockStatus === "active"; - result = result.filter((user) => user.block_status === !isActive); - } - - // فیلتر تاریخ - if (filters.startDate) { - const start = parsePersianDate(filters.startDate); - result = result.filter((user) => { - const userDate = parsePersianDate(user.createdAt); - return userDate && start && userDate >= start; - }); - } - if (filters.endDate) { - const end = parsePersianDate(filters.endDate); - result = result.filter((user) => { - const userDate = parsePersianDate(user.createdAt); - return userDate && end && userDate <= end; - }); - } - - // لاگ برای دیباگ - console.log("کاربران فیلترشده:", result); - - // به‌روزرسانی صفحه‌بندی و کاربران نمایش‌داده‌شده - setTotalPages(Math.ceil(result.length / itemsPerPage)); - const startIndex = (currentPage - 1) * itemsPerPage; - setFilteredUsers(result.slice(startIndex, startIndex + itemsPerPage)); - }; - - // بارگذاری کاربران هنگام بارگذاری صفحه - useEffect(() => { - fetchUsers(); - }, []); - - // اعمال فیلترها هنگام تغییر - useEffect(() => { - applyFilters(); - }, [allUsers, filters, searchQuery, currentPage]); - - // مدیریت تغییر صفحه - const handlePageChange = (page) => setCurrentPage(page); - - // تغییر حالت تاریک/روشن - const toggleDarkMode = () => { - setDarkMode(!darkMode); - }; - - const [searchParams] = useSearchParams(); -const statusParam = searchParams.get("status"); // مثلا "pending" - - return ( -
-
- {/* سایدبار پاسخ‌گو */} -
- -
-
- - - {/* نمایش پیام خطا */} - {error && ( -
- {error} -
- )} - - {/* جستجو و فیلترها */} -
- { - setSearchQuery(e.target.value); - setCurrentPage(1); - }} - /> - { - setFilters((prev) => ({ - ...prev, - ...newFilters, - city: newFilters.province !== prev.province ? "" : newFilters.city, // ریست شهر هنگام تغییر استان - })); - setCurrentPage(1); - }} - /> -
- - {/* جدول کاربران */} -
-
-

نام و نام خانوادگی

-

نام کاربری

-

موبایل

-

تاریخ ثبت نام

-

وضعیت

-

عملیات

-
- -
- {loading ? ( -
- -
- ) : filteredUsers.length === 0 ? ( -
- هیچ کاربری یافت نشد -
- ) : ( - filteredUsers.map((user, index) => ( -
-
- {`${user.first_name} (e.target.src = "/default-avatar.png")} - /> -

{user?.first_name} {user?.last_name}

-

- {user?.first_name} {user?.last_name} -

-
-

{user?.user_name || "-"}

-

{user?.mobile || "-"}

-

{formatPersianDate(user?.createdAt)}

-
- - {user?.block_status ? "غیرفعال" : "فعال"} - - -
-
- - - -
-
- )) - )} -
-
- - -
-
-
- ); -}; - -export default Users; \ No newline at end of file diff --git a/public/modstagram_panel/src/pages/version/Version.jsx b/public/modstagram_panel/src/pages/version/Version.jsx deleted file mode 100644 index 7455125..0000000 --- a/public/modstagram_panel/src/pages/version/Version.jsx +++ /dev/null @@ -1,181 +0,0 @@ -import React, { useEffect, useState } from 'react'; -import AdminHeader from '../../components/admin-header'; -import Sidebar from '../../components/sidebar'; -import axios from 'axios'; -import { BaseUrl } from '../../components/BaseUrl'; - -function Version() { - const [version, setVersion] = useState(null); // اطلاعات نسخه فعلی - const [loading, setLoading] = useState(false); // حالت بارگذاری - const [error, setError] = useState(null); // خطای احتمالی - const [formData, setFormData] = useState({ - version: '', - mandatory: false, - releaseNotes: '', - updateUrls: '', - }); // اطلاعات فرم - - // دریافت نسخه فعلی از سرور - useEffect(() => { - setLoading(true); - axios - .get(`${BaseUrl}/version`) - .then((response) => { - setVersion(response.data); - setFormData({ - version: response.data.version || '', - mandatory: response.data.mandatory || false, - releaseNotes: response.data.releaseNotes || '', - updateUrls: response.data.updateUrls ? response.data.updateUrls.join(', ') : '', - }); - setLoading(false); - }) - .catch((error) => { - setError('خطا در دریافت اطلاعات نسخه'); - setLoading(false); - }); - }, []); - - // مدیریت تغییرات فرم - const handleChange = (e) => { - const { name, value, type, checked } = e.target; - setFormData({ - ...formData, - [name]: type === 'checkbox' ? checked : value, - }); - }; - - // ارسال اطلاعات به سرور - const handleSubmit = (e) => { - e.preventDefault(); - setLoading(true); - setError(null); - - // تبدیل `updateUrls` به آرایه - const formattedData = { - ...formData, - updateUrls: formData.updateUrls.split(',').map((url) => url.trim()), - }; - - axios - .post(`${BaseUrl}/version`, formattedData) - .then((response) => { - setVersion(response.data.version); - setLoading(false); - alert('نسخه با موفقیت ذخیره شد.'); - }) - .catch((error) => { - setError('خطا در ذخیره اطلاعات نسخه'); - setLoading(false); - }); - }; - - return ( - <> - -
-
-
-
-

مدیریت ورژن برنامه

- - {/* نمایش خطا */} - {error &&

{error}

} - - {/* حالت بارگذاری */} - {loading ? ( -
-

در حال بارگذاری...

-
- ) : ( - <> - {/* نمایش اطلاعات نسخه */} - {version && ( -
-

نسخه فعلی:

-

ورژن: {version.version}

-

اجباری: {version.mandatory ? 'بله' : 'خیر'}

-

توضیحات: {version.releaseNotes}

-

لینک‌ها: {version.updateUrls.join(', ')}

-
- )} - -
- -

فرم ایجاد/ویرایش نسخه

-
-
- - -
- -
- -
- -
- - -
- -
- - -
- - -
- - )} -
-
-
- - ); -} - -export default Version; diff --git a/public/modstagram_panel/src/pages/vitrine/VitrineDetail.jsx b/public/modstagram_panel/src/pages/vitrine/VitrineDetail.jsx deleted file mode 100644 index a035e20..0000000 --- a/public/modstagram_panel/src/pages/vitrine/VitrineDetail.jsx +++ /dev/null @@ -1,427 +0,0 @@ -import React, { useEffect, useState } from 'react' -import { useNavigate, useParams } from 'react-router-dom'; -import { BaseUrl, ImageBaseUrl } from '../../components/BaseUrl'; -import axios from 'axios'; -import AdminHeader from '../../components/admin-header'; -import Sidebar from '../../components/sidebar'; -import Loading from '../../components/elements/loading'; -import toast from 'react-hot-toast'; -import Modal from 'react-modal'; -const customStyles = { - content: { - top: '50%', - left: '50%', - transform: 'translate(-50%, -50%)', - position: "fixed", - }, -}; -const VitrineDetail = () => { - const navigate = useNavigate(); - const param = useParams(); - const id = param?.id; - const [loading, setLoading] = useState(false); - const [vitrineDetails, setVitrineDetails] = useState([]); - const [editingVitrine, setEditingVitrine] = useState(false); - const [newVitrine, setNewVitrine] = useState(''); - const [rejectReason, setRejectReason] = useState("") - const [modalIsOpen, setModalIsOpen] = useState(false); - const [modalImage, setModalImage] = useState(''); - - const openModal = (image) => { - setModalImage(image); - setModalIsOpen(true); - } - const closeModal = () => { - setModalIsOpen(false); - } - const getVitrineDetails = (page = 1) => { - setLoading(true); - const config = { - url: `${BaseUrl}/advertising/detail?advertisingId=${id}`, - method: "GET", - }; - axios(config) - .then((res) => { - setVitrineDetails(res?.data?.advertising); - setLoading(false); - }) - .catch((err) => { - setLoading(false); - }); - }; - useEffect(() => { - getVitrineDetails(); - }, [id]); - - const acceptVitrine = () => { - const data = { - advertisingId: vitrineDetails?._id, - }; - axios - .post(`${BaseUrl}/advertising/accept`, data, { - headers: { - Accept: "application/json", - "Content-Type": "application/json", - }, - }) - .then(async (response) => { - try { - toast.success(response?.data?.message) - getVitrineDetails() - } catch (error) { - if ( - error?.response?.data?.error - ) { - toast.error(error.response.data.error); - } else { - // نمایش پیام خطا برای سایر موارد - toast.error("خطای ناشناخته"); - } - } - }) - .catch((error) => { - console.error(error); - toast.show(error?.response?.data?.message, { - type: "danger", - placement: "top", - duration: 4000, - offset: 30, - animationType: "slide-in", - }); - }); - }; - - const rejectVitrine = () => { - const data = { - advertisingId: vitrineDetails?._id, - rejectReason: rejectReason, - }; - axios - .post(`${BaseUrl}/advertising/reject`, data, { - headers: { - Accept: "application/json", - "Content-Type": "application/json", - }, - }) - .then(async (response) => { - try { - toast.success(response?.data?.message) - getVitrineDetails() - } catch (error) { - if ( - error?.response?.data?.error - ) { - toast.error(error.response.data.error); - } else { - // نمایش پیام خطا برای سایر موارد - toast.error("خطای ناشناخته"); - } - } - }) - .catch((error) => { - console.error(error); - toast.show(error?.response?.data?.message, { - type: "danger", - placement: "top", - duration: 4000, - offset: 30, - animationType: "slide-in", - }); - }); - }; - - const handleEditVitrine = () => { - // ارسال درخواست برای ویرایش ویترین به سرور - // سپس بروزرسانی متغیر مربوط به متن ویترین - setEditingVitrine(true); - }; - - - - const contactInfoArray = vitrineDetails?.contactInfo ? Object.keys(vitrineDetails.contactInfo).map(key => { - let title; - switch (key) { - case "phone": - title = "شماره ثابت"; - break; - case "mobile": - title = "شماره همراه"; - break; - case "telegramLink": - title = "لینک تلگرام"; - break; - case "whatsappNumber": - title = "شماره واتساپ"; - break; - case "instagramLink": - title = "لینک اینستاگرام"; - break; - case "saveInfoForNextAds": - title = "ذخیره اطلاعات برای آگهی‌های بعدی"; - break; - default: - title = key; - } - return { title, value: vitrineDetails.contactInfo[key] }; - }) : []; - - return (<> - {loading && } - {!loading && vitrineDetails && ( - <> - -
- - {/* استفاده از ImageMagnify */} - Post - -
-
-
-
-

- اطلاعات ویترین: -

- -
-
-
-
- عنوان ویترین: -
-
- {vitrineDetails?.title} -
-
-
-
- نام و نام خانوادگی سازنده: -
-
- {vitrineDetails?.creator_id?.first_name} {vitrineDetails?.creator_id?.last_name} -
-
-
-
- نام کاربری کاربر: -
-
- {vitrineDetails?.creator_id?.user_name} -
-
-
-
- دسته بندی -
-
- {vitrineDetails?.category} -
-
-
-
- استان -
-
- {vitrineDetails?.province?.name} -
-
-
-
- شهر -
-
- {vitrineDetails?.city?.name} -
-
-
-
- محله -
-
- {vitrineDetails?.neighbourhood} -
-
-
-
- لیست خدمات و کالا -
-
-
- {vitrineDetails?.services && vitrineDetails?.services?.map(item => { - return (
- { openModal(ImageBaseUrl + item?.image) }} - src={ImageBaseUrl + item?.image} className='w-[100px] h-[100px] rounded-sm' alt="" /> -

نام : {item?.title}

-

درصد تخفیف : {item?.discountPercentage}

-

قیمت اصلی : {item?.originalPrice}

-

قیمت تخفیف خورده : {item?.discountPrice}

-
) - })} -
-
-
-
-
- لیست امکانات -
-
-
- {vitrineDetails?.features && vitrineDetails?.features?.map(item => { - return (
-

{item?.title} :

-

{item?.value == true ? "دارد" : "ندارد"}

-
) - })} -
-
-
-
-
- لیست تماس -
-
-
- {contactInfoArray.map((item, index) => ( -
-

{item.title} :

-

{item.value}

-
- ))} -
-
-
-
-
- تصاویر -
-
- {vitrineDetails?.images && vitrineDetails?.images?.map(item => { - return (
- { openModal(ImageBaseUrl + item) }} - src={ImageBaseUrl + item} className='w-[100px] h-[100px] rounded-sm mx-4' alt="" /> -
) - })} -
-
-
-
- توضیحات -
-
- {vitrineDetails?.description} -
-
-
-
- وضعیت: -
-
-

- {vitrineDetails?.status - === "pre_payment" ? - "در انتظار پرداخت" : - vitrineDetails?.status == "paid" ? - "پرداخت شده" : vitrineDetails?.status == "accepted" ? - "تایید شده" : vitrineDetails?.status == "rejected" ? - "رد شده" : - "منقضی شده" - } -

-
-
- {vitrineDetails?.reject_reason && - -
-
- علت رد -
-
- {vitrineDetails?.reject_reason} -
-
} -
-
- {!editingVitrine ? ( - <> - {/* */} - -
- - -
- - ) : ( - <> -