├── frontend
├── .env
├── postcss.config.js
├── vercel.json
├── src
│ ├── components
│ │ ├── Loader.jsx
│ │ ├── inputForm
│ │ │ └── InputField.jsx
│ │ ├── nav
│ │ │ ├── UserMenu.jsx
│ │ │ └── Header.jsx
│ │ ├── ProductCard.jsx
│ │ └── CartCard.jsx
│ ├── pages
│ │ ├── index.js
│ │ ├── Hero.jsx
│ │ ├── Login.jsx
│ │ ├── Cart.jsx
│ │ ├── Register.jsx
│ │ └── DetailPage.jsx
│ ├── main.jsx
│ ├── App.jsx
│ ├── layout
│ │ └── Layout.jsx
│ ├── hook
│ │ └── useOuterClick.js
│ ├── schema
│ │ └── index.js
│ ├── App.css
│ ├── index.css
│ ├── routes
│ │ └── Router.jsx
│ └── assets
│ │ └── react.svg
├── vite.config.js
├── utils
│ └── axios.js
├── tailwind.config.js
├── .gitignore
├── index.html
├── README.md
├── .eslintrc.cjs
├── package.json
├── public
│ └── vite.svg
└── store
│ └── appStore.js
├── .gitignore
├── backend
├── .env
├── middleware
│ ├── asyncHandler.js
│ ├── checkAuth.js
│ └── errorHandler.js
├── vercel.json
├── config
│ └── db.js
├── utils
│ └── jwt.js
├── package.json
├── server.js
├── routes
│ └── userRoutes.js
├── model
│ ├── cartModel.js
│ └── userModel.js
├── controller
│ └── userController.js
├── data
│ └── products.json
└── package-lock.json
└── README.md
/frontend/.env:
--------------------------------------------------------------------------------
1 | VITE_BASE_URL = http://localhost:2060
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | frontend/node_modules/
2 | backend/node_modules/
3 |
4 |
5 |
--------------------------------------------------------------------------------
/frontend/postcss.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/backend/.env:
--------------------------------------------------------------------------------
1 | PORT = 2060
2 | DB_URI = mongodb://127.0.0.1:27017/shopping-cart
3 | BASE_URL = http://localhost:5173
4 | SECRET_KEY= shopping-cart-1112
--------------------------------------------------------------------------------
/frontend/vercel.json:
--------------------------------------------------------------------------------
1 | {
2 | "routes": [{ "src": "/[^.]+", "dest": "/", "status": 200 }],
3 | "github": {
4 | "silent": true
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/components/Loader.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | const Loader = () => {
4 | return ;
5 | };
6 |
7 | export default Loader;
8 |
--------------------------------------------------------------------------------
/backend/middleware/asyncHandler.js:
--------------------------------------------------------------------------------
1 | const asyncHandler = (fn) => (req, res, next) => {
2 | Promise.resolve(fn(req, res, next)).catch(next);
3 | };
4 |
5 | module.exports = asyncHandler;
6 |
--------------------------------------------------------------------------------
/frontend/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import react from '@vitejs/plugin-react'
3 |
4 | // https://vitejs.dev/config/
5 | export default defineConfig({
6 | plugins: [react()],
7 | })
8 |
--------------------------------------------------------------------------------
/frontend/utils/axios.js:
--------------------------------------------------------------------------------
1 | import axios from "axios";
2 |
3 | const BASE_URL = import.meta.env.VITE_BASE_URL;
4 |
5 | const API = axios.create({ baseURL: BASE_URL, withCredentials: true });
6 |
7 | export default API;
8 |
--------------------------------------------------------------------------------
/frontend/src/pages/index.js:
--------------------------------------------------------------------------------
1 | export { default as Login } from "./Login";
2 | export { default as Register } from "./Register";
3 | export { default as Cart } from "./Cart";
4 | export { default as DetailPage } from "./DetailPage";
5 |
--------------------------------------------------------------------------------
/frontend/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | export default {
3 | content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
4 | theme: {
5 | extend: {},
6 | },
7 | plugins: [],
8 | };
9 |
--------------------------------------------------------------------------------
/frontend/src/main.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom/client";
3 | import App from "./App.jsx";
4 | import "./index.css";
5 |
6 | ReactDOM.createRoot(document.getElementById("root")).render();
7 |
--------------------------------------------------------------------------------
/frontend/src/App.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { RouterProvider } from "react-router-dom";
3 | import routes from "./routes/Router";
4 |
5 | const App = () => {
6 | return ;
7 | };
8 |
9 | export default App;
10 |
--------------------------------------------------------------------------------
/frontend/src/layout/Layout.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | const Layout = ({ children }) => {
4 | return (
5 |
8 | );
9 | };
10 |
11 | export default Layout;
12 |
--------------------------------------------------------------------------------
/backend/vercel.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 2,
3 | "name": "backend",
4 | "builds": [
5 | {
6 | "src": "server.js",
7 | "use": "@vercel/node"
8 | }
9 | ],
10 | "routes": [
11 | {
12 | "src": "/(.*)",
13 | "dest": "/server.js"
14 | }
15 | ],
16 | "github": {
17 | "silent": true
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/backend/config/db.js:
--------------------------------------------------------------------------------
1 | const mongoose = require("mongoose");
2 |
3 | const connectDB = async () => {
4 | try {
5 | const { connection } = await mongoose.connect(process.env.DB_URI);
6 | console.log(`connected with `, connection.host, connection.port);
7 | } catch (error) {
8 | console.log(error);
9 | }
10 | };
11 |
12 | module.exports = connectDB;
13 |
--------------------------------------------------------------------------------
/frontend/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/backend/utils/jwt.js:
--------------------------------------------------------------------------------
1 | const sendToken = (user, res) => {
2 | const token = user.getJwtToken();
3 | const options = {
4 | httpOnly: true,
5 | secure: true,
6 | sameSite: "none",
7 | maxAge: 72 * 60 * 60 * 1000,
8 | };
9 | res
10 | .cookie("token", token, options)
11 | .status(200)
12 | .json({ success: true, token, user });
13 | };
14 |
15 | module.exports = sendToken;
16 |
--------------------------------------------------------------------------------
/frontend/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite + React
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/frontend/README.md:
--------------------------------------------------------------------------------
1 | # React + Vite
2 |
3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
4 |
5 | Currently, two official plugins are available:
6 |
7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
9 |
--------------------------------------------------------------------------------
/frontend/src/hook/useOuterClick.js:
--------------------------------------------------------------------------------
1 | import { useEffect } from "react";
2 |
3 | const useOuterClick = (ref, callback) => {
4 | useEffect(() => {
5 | const close = (event) => {
6 | if (ref?.current && !ref?.current?.contains(event.target)) {
7 | callback(false);
8 | }
9 | };
10 | document.addEventListener("mousedown", close);
11 | return () => {
12 | document.removeEventListener("mousedown", close);
13 | };
14 | }, []);
15 | };
16 |
17 | export default useOuterClick;
18 |
--------------------------------------------------------------------------------
/frontend/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | env: { browser: true, es2020: true },
4 | extends: [
5 | 'eslint:recommended',
6 | 'plugin:react/recommended',
7 | 'plugin:react/jsx-runtime',
8 | 'plugin:react-hooks/recommended',
9 | ],
10 | ignorePatterns: ['dist', '.eslintrc.cjs'],
11 | parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
12 | settings: { react: { version: '18.2' } },
13 | plugins: ['react-refresh'],
14 | rules: {
15 | 'react-refresh/only-export-components': [
16 | 'warn',
17 | { allowConstantExport: true },
18 | ],
19 | },
20 | }
21 |
--------------------------------------------------------------------------------
/backend/middleware/checkAuth.js:
--------------------------------------------------------------------------------
1 | const jwt = require("jsonwebtoken");
2 | const asyncHandler = require("./asyncHandler");
3 |
4 | const checkAuth = asyncHandler(async (req, res, next) => {
5 | const { token } = req.cookies;
6 |
7 | if (token) {
8 | jwt.verify(token, process.env.SECRET_KEY, (err, user) => {
9 | if (err) {
10 | res.status(400);
11 | throw new Error("Invalid token");
12 | }
13 | req.userId = user.id;
14 | next();
15 | });
16 | } else {
17 | return res.status(401).json({ success: false, message: "Unauthorized" });
18 | }
19 | });
20 |
21 | module.exports = checkAuth;
22 |
--------------------------------------------------------------------------------
/frontend/src/schema/index.js:
--------------------------------------------------------------------------------
1 | import * as YUP from "yup";
2 |
3 | export const loginSchema = YUP.object({
4 | email: YUP.string().email("invalid mail").required("enter email"),
5 | password: YUP.string().required("enter password"),
6 | });
7 |
8 | export const registerSchema = YUP.object({
9 | name: YUP.string().min(3, "minimum 3 character").required("enter name"),
10 | email: YUP.string().email("invalid mail").required("enter email"),
11 | password: YUP.string().required("enter password"),
12 | confirmPassword: YUP.string()
13 | .oneOf([YUP.ref("password"), null], "password must be match")
14 | .required("enter password"),
15 | });
16 |
--------------------------------------------------------------------------------
/backend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "backend",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "server.js",
6 | "scripts": {
7 | "dev": "nodemon server.js",
8 | "start": "node server.js",
9 | "test": "echo \"Error: no test specified\" && exit 1"
10 | },
11 | "keywords": [],
12 | "author": "",
13 | "license": "ISC",
14 | "devDependencies": {
15 | "nodemon": "^3.0.1"
16 | },
17 | "dependencies": {
18 | "bcrypt": "^5.1.1",
19 | "cookie-parser": "^1.4.6",
20 | "cors": "^2.8.5",
21 | "dotenv": "^16.3.1",
22 | "express": "^4.18.2",
23 | "jsonwebtoken": "^9.0.2",
24 | "mongoose": "^7.6.2"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/frontend/src/App.css:
--------------------------------------------------------------------------------
1 | #root {
2 | max-width: 1280px;
3 | margin: 0 auto;
4 | padding: 2rem;
5 | text-align: center;
6 | }
7 |
8 | .logo {
9 | height: 6em;
10 | padding: 1.5em;
11 | will-change: filter;
12 | transition: filter 300ms;
13 | }
14 | .logo:hover {
15 | filter: drop-shadow(0 0 2em #646cffaa);
16 | }
17 | .logo.react:hover {
18 | filter: drop-shadow(0 0 2em #61dafbaa);
19 | }
20 |
21 | @keyframes logo-spin {
22 | from {
23 | transform: rotate(0deg);
24 | }
25 | to {
26 | transform: rotate(360deg);
27 | }
28 | }
29 |
30 | @media (prefers-reduced-motion: no-preference) {
31 | a:nth-of-type(2) .logo {
32 | animation: logo-spin infinite 20s linear;
33 | }
34 | }
35 |
36 | .card {
37 | padding: 2em;
38 | }
39 |
40 | .read-the-docs {
41 | color: #888;
42 | }
43 |
--------------------------------------------------------------------------------
/backend/server.js:
--------------------------------------------------------------------------------
1 | const express = require("express");
2 | const cors = require("cors");
3 | require("dotenv").config();
4 | const connectDB = require("./config/db");
5 | const userRoutes = require("./routes/userRoutes");
6 | const cookieParser = require("cookie-parser");
7 | const { notFound, errorHandler } = require("./middleware/errorHandler");
8 | connectDB();
9 |
10 | const app = express();
11 |
12 | app.use(
13 | cors({
14 | origin: process.env.BASE_URL,
15 | credentials: true,
16 | methods: "PUT,POST,GET,DELETE,PATCH,HEAD",
17 | })
18 | );
19 |
20 | app.use(express.json());
21 | app.use(express.urlencoded({ extended: true }));
22 | app.use(cookieParser());
23 | app.use("/api/user/", userRoutes);
24 |
25 | app.use(notFound);
26 | app.use(errorHandler);
27 |
28 | app.listen(process.env.PORT, () => {
29 | console.log(`Server running on port ${process.env.PORT}`);
30 | });
31 |
--------------------------------------------------------------------------------
/frontend/src/components/inputForm/InputField.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | const InputField = ({
4 | title,
5 | name,
6 | value,
7 | type,
8 | handleChange,
9 | errors,
10 | touched,
11 | handleBlur,
12 | }) => {
13 | return (
14 |
15 |
19 | {errors[name] && touched[name] ? (
20 | {errors[name]}
21 | ) : null}
22 |
32 |
33 | );
34 | };
35 |
36 | export default InputField;
37 |
--------------------------------------------------------------------------------
/backend/routes/userRoutes.js:
--------------------------------------------------------------------------------
1 | const express = require("express");
2 | const {
3 | login,
4 | register,
5 | logout,
6 | addCart,
7 | removeCart,
8 | decreaseCartQty,
9 | addCartQty,
10 | getUserCart,
11 | getCartNumber,
12 | } = require("../controller/userController");
13 | const checkAuth = require("../middleware/checkAuth");
14 |
15 | const userRoutes = express.Router();
16 |
17 | userRoutes.post("/login", login);
18 | userRoutes.post("/register", register);
19 | userRoutes.post("/logout", checkAuth, logout);
20 | userRoutes.get("/get-user-cart-number", checkAuth, getCartNumber);
21 | userRoutes.get("/get-user-cart", checkAuth, getUserCart);
22 | userRoutes.post("/add-cart", checkAuth, addCart);
23 | userRoutes.delete("/remove-cart", checkAuth, removeCart);
24 | userRoutes.post("/add-qty", checkAuth, addCartQty);
25 | userRoutes.post("/decrease-qty", checkAuth, decreaseCartQty);
26 |
27 | module.exports = userRoutes;
28 |
--------------------------------------------------------------------------------
/frontend/src/components/nav/UserMenu.jsx:
--------------------------------------------------------------------------------
1 | import React, { useRef } from "react";
2 | import { useAppStore } from "../../../store/appStore";
3 | import { useNavigate } from "react-router-dom";
4 | import useOuterClick from "../../hook/useOuterClick";
5 |
6 | const UserMenu = ({ setShowMenu }) => {
7 | const userRef = useRef(null);
8 | useOuterClick(userRef, setShowMenu);
9 | const navigate = useNavigate();
10 | const { logout, user } = useAppStore();
11 | return (
12 |
16 |
{user?.name}
17 | logout(navigate, setShowMenu)}
20 | >
21 | Logout
22 |
23 |
24 | );
25 | };
26 |
27 | export default UserMenu;
28 |
--------------------------------------------------------------------------------
/backend/model/cartModel.js:
--------------------------------------------------------------------------------
1 | const mongoose = require("mongoose");
2 |
3 | const cartSchema = mongoose.Schema(
4 | {
5 | cartItems: [
6 | {
7 | product: {
8 | id: { type: Number, required: true },
9 | title: { type: String, required: true },
10 | price: Number,
11 | description: { type: String, required: true },
12 | rating: { rate: { type: Number }, count: { type: Number } },
13 | category: { type: String, required: true },
14 | image: { type: String, required: true },
15 | },
16 | quantity: { type: Number, default: 1 },
17 | },
18 | ],
19 | user: {
20 | type: mongoose.Types.ObjectId,
21 | ref: "user",
22 | required: [true, "user id is required"],
23 | },
24 | totalPrice: Number,
25 | },
26 | { timestamp: true }
27 | );
28 |
29 | const cartModel = mongoose.model("cart", cartSchema);
30 |
31 | module.exports = cartModel;
32 |
--------------------------------------------------------------------------------
/frontend/src/pages/Hero.jsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from "react";
2 | import Layout from "../layout/Layout";
3 | import axios from "axios";
4 | import ProductCard from "../components/ProductCard";
5 |
6 | const Hero = () => {
7 | const [products, setProducts] = useState([]);
8 | const getAllProducts = async () => {
9 | try {
10 | const { data } = await axios(
11 | "https://ecommerce-backend-new.vercel.app/api/products"
12 | );
13 | setProducts(data);
14 | } catch (error) {
15 | console.log(error);
16 | }
17 | };
18 | useEffect(() => {
19 | getAllProducts();
20 | }, []);
21 | return (
22 |
23 |
24 | {products?.map((item, id) => (
25 |
26 | ))}
27 |
28 |
29 | );
30 | };
31 |
32 | export default Hero;
33 |
--------------------------------------------------------------------------------
/backend/model/userModel.js:
--------------------------------------------------------------------------------
1 | const mongoose = require("mongoose");
2 | const bcrypt = require("bcrypt");
3 | const jwt = require("jsonwebtoken");
4 |
5 | const userSchema = mongoose.Schema({
6 | name: { type: "string", required: true },
7 | email: { type: "string", required: true, unique: true },
8 | password: { type: "string", required: true },
9 | role: { type: "string", default: "user", enum: ["user", "admin"] },
10 | });
11 |
12 | userSchema.pre("save", async function (next) {
13 | if (!this.isModified("password")) {
14 | next();
15 | }
16 | this.password = await bcrypt.hash(this.password, 10);
17 | next();
18 | });
19 |
20 | userSchema.methods.getJwtToken = function () {
21 | return jwt.sign({ id: this.id }, process.env.SECRET_KEY, { expiresIn: "2d" });
22 | };
23 |
24 | userSchema.methods.verifyPassword = async function (enteredPassword) {
25 | return bcrypt.compare(enteredPassword, this.password);
26 | };
27 |
28 | const userModel = mongoose.model("user", userSchema);
29 |
30 | module.exports = userModel;
31 |
--------------------------------------------------------------------------------
/frontend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "frontend",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "vite build",
9 | "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
10 | "preview": "vite preview"
11 | },
12 | "dependencies": {
13 | "axios": "^1.5.1",
14 | "formik": "^2.4.5",
15 | "react": "^18.2.0",
16 | "react-dom": "^18.2.0",
17 | "react-icons": "^4.11.0",
18 | "react-router-dom": "^6.16.0",
19 | "react-toastify": "^9.1.3",
20 | "yup": "^1.3.2",
21 | "zustand": "^4.4.3"
22 | },
23 | "devDependencies": {
24 | "@types/react": "^18.2.15",
25 | "@types/react-dom": "^18.2.7",
26 | "@vitejs/plugin-react": "^4.0.3",
27 | "autoprefixer": "^10.4.16",
28 | "eslint": "^8.45.0",
29 | "eslint-plugin-react": "^7.32.2",
30 | "eslint-plugin-react-hooks": "^4.6.0",
31 | "eslint-plugin-react-refresh": "^0.4.3",
32 | "postcss": "^8.4.31",
33 | "tailwindcss": "^3.3.3",
34 | "vite": "^4.4.5"
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/backend/middleware/errorHandler.js:
--------------------------------------------------------------------------------
1 | const notFound = (req, res, next) => {
2 | const error = new Error(`Not Found - ${req.originalUrl}`);
3 | res.status(404);
4 | next(error);
5 | };
6 |
7 | const errorHandler = (err, req, res, next) => {
8 | let statusCode = res.statusCode === 200 ? 500 : res.statusCode;
9 | let message = err.message;
10 |
11 | if (err.name === "CastError" && err.kind === "ObjectId") {
12 | message = `Resource not found`;
13 | statusCode = 404;
14 | }
15 |
16 | if (err.name === "validationError") {
17 | message = Object.values(err.errors).map((value) => value.message);
18 | statusCode = 400;
19 | }
20 |
21 | if (err.code == 11000) {
22 | message = `Duplicate ${Object.keys(err.keyvalue)} entered`;
23 | }
24 |
25 | if (err.name === "JsonWebTokenError") {
26 | message = `Json web token is invalid`;
27 | statusCode = 400;
28 | }
29 | if (err.name === "TokenExpiredError") {
30 | message = `Json web token is expired`;
31 | statusCode = 400;
32 | }
33 |
34 | res.status(statusCode).json({ message });
35 | };
36 |
37 | module.exports = { notFound, errorHandler };
38 |
--------------------------------------------------------------------------------
/frontend/src/index.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | .loader {
6 | width: 48px;
7 | height: 48px;
8 | border-radius: 50%;
9 | z-index: 50;
10 | position: fixed;
11 | top: 50%;
12 | left: 50%;
13 | transform: translate(-50%, -50%);
14 | animation: rotate 1s linear infinite;
15 | }
16 | .loader::before,
17 | .loader::after {
18 | content: "";
19 | box-sizing: border-box;
20 | position: absolute;
21 | inset: 0px;
22 | border-radius: 50%;
23 | border: 5px solid #fff;
24 | animation: prixClipFix 2s linear infinite;
25 | }
26 | .loader::after {
27 | border-color: #ff3d00;
28 | animation: prixClipFix 2s linear infinite, rotate 0.5s linear infinite reverse;
29 | inset: 6px;
30 | }
31 |
32 | @keyframes rotate {
33 | 0% {
34 | transform: rotate(0deg);
35 | }
36 | 100% {
37 | transform: rotate(360deg);
38 | }
39 | }
40 |
41 | @keyframes prixClipFix {
42 | 0% {
43 | clip-path: polygon(50% 50%, 0 0, 0 0, 0 0, 0 0, 0 0);
44 | }
45 | 25% {
46 | clip-path: polygon(50% 50%, 0 0, 100% 0, 100% 0, 100% 0, 100% 0);
47 | }
48 | 50% {
49 | clip-path: polygon(50% 50%, 0 0, 100% 0, 100% 100%, 100% 100%, 100% 100%);
50 | }
51 | 75% {
52 | clip-path: polygon(50% 50%, 0 0, 100% 0, 100% 100%, 0 100%, 0 100%);
53 | }
54 | 100% {
55 | clip-path: polygon(50% 50%, 0 0, 100% 0, 100% 100%, 0 100%, 0 0);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/frontend/public/vite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/frontend/src/routes/Router.jsx:
--------------------------------------------------------------------------------
1 | import { createBrowserRouter, useLocation } from "react-router-dom";
2 | import Hero from "../pages/Hero";
3 | import Header from "../components/nav/Header";
4 | import { Outlet } from "react-router-dom";
5 | import Login from "../pages/Login";
6 | import Register from "./../pages/Register";
7 | import Cart from "./../pages/Cart";
8 | import { ToastContainer } from "react-toastify";
9 | import "react-toastify/dist/ReactToastify.css";
10 | import { useAppStore } from "../../store/appStore";
11 | import { useEffect } from "react";
12 | import { DetailPage } from "../pages";
13 | import Loader from "../components/Loader";
14 |
15 | const Layout = () => {
16 | const { pathname } = useLocation();
17 | const { loading } = useAppStore();
18 | useEffect(() => {
19 | window.scrollTo({ top: 0, left: 0, behavior: "smooth" });
20 | }, [pathname]);
21 | return (
22 | <>
23 | {loading && }
24 |
25 |
26 |
27 | >
28 | );
29 | };
30 |
31 | const routes = createBrowserRouter([
32 | {
33 | path: "/",
34 | element: ,
35 | children: [
36 | {
37 | path: "",
38 | element: ,
39 | },
40 | {
41 | path: "login",
42 | element: ,
43 | },
44 | {
45 | path: "register",
46 | element: ,
47 | },
48 | {
49 | path: "cart",
50 | element: ,
51 | },
52 | {
53 | path: "product/:id",
54 | element: ,
55 | },
56 | ],
57 | },
58 | ]);
59 |
60 | export default routes;
61 |
--------------------------------------------------------------------------------
/frontend/src/components/ProductCard.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { useNavigate } from "react-router-dom";
3 | import { useAppStore } from "../../store/appStore";
4 |
5 | const ProductCard = ({ item }) => {
6 | const { addCart } = useAppStore();
7 | const navigate = useNavigate();
8 | const productName = (name) => {
9 | if (name.length > 20) {
10 | return name.substring(0, 20) + "...";
11 | }
12 | return name;
13 | };
14 | return (
15 |
16 |
17 |

navigate(`/product/${item.id}`)}
20 | className="w-full h-full object-cover cursor-pointer"
21 | alt=""
22 | />
23 |
24 |
25 |
navigate(`/product/${item.id}`)}
28 | >
29 | {productName(item.title)}
30 |
31 |
32 | {"₹ "}
33 | {Math.ceil(item.price * 81)}
34 |
35 |
36 |
37 |
43 |
44 |
45 |
46 | {item.rating.count}
47 |
48 |
49 | );
50 | };
51 |
52 | export default ProductCard;
53 |
--------------------------------------------------------------------------------
/frontend/src/pages/Login.jsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect } from "react";
2 | import Layout from "../layout/Layout";
3 | import { useFormik } from "formik";
4 | import { loginSchema } from "../schema";
5 | import InputField from "../components/inputForm/InputField";
6 | import { Navigate, useNavigate } from "react-router-dom";
7 | import { useAppStore } from "../../store/appStore";
8 |
9 | const initialValues = {
10 | email: "",
11 | password: "",
12 | };
13 |
14 | const Login = () => {
15 | const { loginUser, user } = useAppStore();
16 | const navigate = useNavigate();
17 | const { handleBlur, handleChange, handleSubmit, values, errors, touched } =
18 | useFormik({
19 | initialValues,
20 | validationSchema: loginSchema,
21 | onSubmit: (values, action) => {
22 | loginUser(values, navigate);
23 | },
24 | });
25 |
26 | useEffect(() => {
27 | if (user) {
28 | navigate("/");
29 | }
30 | }, [user]);
31 |
32 | return (
33 |
34 |
79 |
80 | );
81 | };
82 |
83 | export default Login;
84 |
--------------------------------------------------------------------------------
/frontend/src/pages/Cart.jsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect } from "react";
2 | import Layout from "./../layout/Layout";
3 | import CartCard from "../components/CartCard";
4 | import { useAppStore } from "../../store/appStore";
5 | import { useNavigate } from "react-router-dom";
6 | import { PiSmileySadFill } from "react-icons/pi";
7 |
8 | const Cart = () => {
9 | const navigate = useNavigate();
10 | const { cart, getUserCart, user } = useAppStore();
11 | const displaycart = cart?.map((itemes, id) => {
12 | return ;
13 | });
14 |
15 | useEffect(() => {
16 | if (!user) {
17 | navigate("/login");
18 | }
19 |
20 | getUserCart();
21 | }, []);
22 |
23 | let initialValue = 0;
24 | let total = Math.ceil(
25 | cart?.reduce(
26 | (acc, item) => acc + item.product.price * item.quantity,
27 | initialValue
28 | ) * 81
29 | );
30 |
31 | return (
32 |
33 |
34 |
35 |
36 |
Your Cart
37 | Total Itemes : {cart?.length}
38 |
39 |
{displaycart}
40 | {!cart?.length && (
41 |
42 |
cart is empty
{" "}
43 |
44 |
45 |
46 | )}
47 |
48 | {cart?.length ? (
49 |
50 |
51 |
52 |
You Pay
53 | Check Our order Policy
54 |
55 |
56 | You Can Pay .... on This Order
57 |
58 |
59 |
60 | Total Price {"₹"} {total}
61 |
62 |
63 | Distributor Price -20
64 |
65 | Discount 40
66 |
67 |
68 |
69 | ) : null}
70 |
71 |
72 | );
73 | };
74 |
75 | export default Cart;
76 |
--------------------------------------------------------------------------------
/frontend/src/pages/Register.jsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect } from "react";
2 | import Layout from "../layout/Layout";
3 | import { useFormik } from "formik";
4 | import { registerSchema } from "../schema";
5 | import InputField from "../components/inputForm/InputField";
6 | import { useNavigate } from "react-router-dom";
7 | import { useAppStore } from "../../store/appStore";
8 |
9 | const initialValues = {
10 | name: "",
11 | email: "",
12 | password: "",
13 | confirmPassword: "",
14 | };
15 |
16 | const Register = () => {
17 | const { registerUser, user } = useAppStore();
18 | const navigate = useNavigate();
19 | const { handleBlur, handleChange, handleSubmit, values, errors, touched } =
20 | useFormik({
21 | initialValues,
22 | validationSchema: registerSchema,
23 | onSubmit: (values, action) => {
24 | registerUser(values, navigate);
25 | },
26 | });
27 |
28 | const formValues = [
29 | { name: "name", title: "Name ", type: "text", value: values.name },
30 | { name: "email", title: "Email ", type: "email", value: values.email },
31 | {
32 | name: "password",
33 | title: "Password ",
34 | type: "password",
35 | value: values.password,
36 | },
37 | {
38 | name: "confirmPassword",
39 | title: "Confirm password ",
40 | type: "password",
41 | value: values.confirmPassword,
42 | },
43 | ];
44 |
45 | useEffect(() => {
46 | if (user) {
47 | navigate("/");
48 | }
49 | }, [user]);
50 |
51 | return (
52 |
53 |
92 |
93 | );
94 | };
95 |
96 | export default Register;
97 |
--------------------------------------------------------------------------------
/frontend/src/components/CartCard.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { useNavigate } from "react-router-dom";
3 | import { HiPlus, HiMinus } from "react-icons/hi";
4 | import { useAppStore } from "../../store/appStore";
5 |
6 | const CartCard = ({ item }) => {
7 | const { removeCart, addCartQty, removeCartQty } = useAppStore();
8 | const productName = (name) => {
9 | if (name.length > 20) {
10 | return name.substring(0, 20) + "...";
11 | }
12 | return name;
13 | };
14 | const navigate = useNavigate();
15 | return (
16 |
17 |
18 |
![]()
navigate(`/product/${item.product.id}`)}
20 | src={item.product.image}
21 | className="h-full w-full cursor-pointer object-contain"
22 | alt=""
23 | />
24 |
{" "}
25 |
26 |
navigate(`/product/${item.product.id}`)}
28 | className="cursor-pointer text-[16px] text-slate-600"
29 | >
30 | {productName(item.product.title)}
31 |
32 |
33 |
34 |
{
36 | item.quantity === 1
37 | ? removeCart(item.product.id)
38 | : removeCartQty(item.product.id);
39 | }}
40 | className="flex relative bg-white md:h-[30px] md:w-[30px] h-[24px] w-[24px] items-center justify-center rounded-full border-[1px] p-[2px] text-center text-[35px] shadow-xl"
41 | >
42 |
43 |
44 |
45 |
46 |
{item?.quantity}
47 |
48 |
56 |
57 |
58 |
59 |
60 | {"₹ "}
61 |
62 | {Math.ceil(item.product.price * 81)}
63 |
64 |
65 | removeCart(item.product.id)}
67 | className="cursor-pointer text-right text-red-500"
68 | >
69 | Remove
70 |
71 |
72 |
73 | );
74 | };
75 |
76 | export default CartCard;
77 |
--------------------------------------------------------------------------------
/frontend/src/components/nav/Header.jsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from "react";
2 | import { HiShoppingCart, HiUserCircle } from "react-icons/hi";
3 | import { NavLink, useNavigate } from "react-router-dom";
4 | import UserMenu from "./UserMenu";
5 | import { useAppStore } from "../../../store/appStore";
6 | import API from "../../../utils/axios";
7 |
8 | const Header = () => {
9 | const { user, totalCart } = useAppStore();
10 | const [showMenu, setShowMenu] = useState(false);
11 | const navigate = useNavigate();
12 |
13 | const getCartNumber = async () => {
14 | try {
15 | const { data, status } = await API("/api/user/get-user-cart-number");
16 | useAppStore.setState({ totalCart: data });
17 | } catch (error) {
18 | console.log(error?.response?.data?.message);
19 | }
20 | };
21 |
22 | useEffect(() => {
23 | if (user) {
24 | getCartNumber();
25 | }
26 | }, [user]);
27 |
28 | return (
29 |
30 |
31 |
navigate("/")}
33 | className="font-extrabold text-[26px] cursor-pointer tracking-wide sm:tracking-widest"
34 | >
35 | Shopping Cart
36 |
37 |
38 |
39 |
40 | -
41 | (isActive ? "text-blue-400" : "")}
44 | >
45 | Home
46 |
47 |
48 | {!user && (
49 | -
50 | (isActive ? "text-blue-400" : "")}
53 | >
54 | Login
55 |
56 |
57 | )}
58 |
59 |
60 |
61 | (isActive ? "text-blue-400" : "")}
64 | >
65 |
66 | {user && (
67 |
72 | )}
73 |
74 | {user ? (
75 | setShowMenu((pre) => !pre)}
79 | />
80 | ) : (
81 | (isActive ? "text-blue-400" : "")}
84 | >
85 |
86 |
87 | )}
88 |
89 | {showMenu && }
90 |
91 |
92 | );
93 | };
94 |
95 | export default Header;
96 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # MERN eCommerce Shopping Cart
2 |
3 | This is a MERN (MongoDB, Express.js, React, Node.js) eCommerce shopping cart project that allows users to browse products online. It includes features like user authentication, cart management.
4 |
5 | 
6 | 
7 |
8 | ## Table of Contents
9 |
10 | 1. [Demo](#demo)
11 | 2. [Features](#features)
12 | 3. [Technologies Used](#technologies-used)
13 | 4. [Installation](#installation)
14 | 5. [Screenshot](#screenshot)
15 |
16 | ## Demo
17 |
18 | You can check out a live demo of this project [here](https://shopping-cart-new-one.vercel.app).
19 |
20 | ## Features
21 |
22 | - User authentication (signup, login, logout).
23 | - Form validation using
24 | - Add products to the shopping cart.
25 | - Manage the shopping cart (add, remove, update items).
26 | - Product detail page.
27 |
28 | ## Technologies Used
29 |
30 | - Frontend:
31 |
32 | - React: A JavaScript library for building user interfaces.
33 | - Zustand: A state management library for managing application state with simplicity.
34 | - Tailwind: A CSS framework for responsive and modern UI design.
35 | - Axios: A popular JavaScript library for making HTTP requests.
36 | - Formik - For handling forms and form validation.
37 | - Yup - For schema validation with Formik.
38 | - React-Toastify - For displaying toast notifications in the application.
39 | - React-Icons - For including icons in the user interface.
40 |
41 | - Backend:
42 | - Node.js: A server-side JavaScript runtime environment.
43 | - Express: A web application framework for Node.js.
44 | - Cors: A middleware for enabling Cross-Origin Resource Sharing.
45 | - Dotenv: A module for loading environment variables from a .env file.
46 | - nodemon - For automatically restarting the server during development.
47 | - bcrypt - For hashing and securing passwords.
48 | - cookie-parser - For parsing cookies in HTTP requests.
49 | - cors - For handling Cross-Origin Resource Sharing.
50 | - jsonwebtoken - For generating and verifying JSON Web Tokens for user authentication.
51 |
52 | ## Installation
53 |
54 | - Clone the repository from GitHub.
55 | - Install Node.js and MongoDB on your system if you haven't already.
56 | - Run
57 |
58 | ```
59 | npm install
60 | ```
61 |
62 | in the root directory to install the required dependencies.
63 |
64 | - Configure the MongoDB connection string in the server configuration file.
65 | - Run
66 |
67 | ```
68 | npm run dev
69 | ```
70 |
71 | start to start the development server.
72 |
73 | ## Screenshot
74 |
75 | 
76 | 
77 | 
78 | 
79 | 
80 | 
81 | 
82 | 
83 | 
84 | 
85 |
--------------------------------------------------------------------------------
/frontend/src/assets/react.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/frontend/src/pages/DetailPage.jsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from "react";
2 | import Layout from "../layout/Layout";
3 | import { useNavigate, useParams } from "react-router-dom";
4 | import axios from "axios";
5 | import { useAppStore } from "../../store/appStore";
6 |
7 | const DetailPage = () => {
8 | const navigate = useNavigate();
9 | const { addCart } = useAppStore();
10 | const [singleProduct, setSingleProduct] = useState(null);
11 | const { id } = useParams();
12 |
13 | const getSingleProduct = async () => {
14 | try {
15 | const { data, status } = await axios(
16 | `https://ecommerce-backend-new.vercel.app/api/products/${id}`
17 | );
18 | setSingleProduct(data);
19 | } catch (error) {
20 | console.log(error);
21 | }
22 | };
23 |
24 | useEffect(() => {
25 | if (id) {
26 | getSingleProduct();
27 | }
28 | }, [id]);
29 |
30 | return (
31 |
32 |
33 |
34 | <>
35 | {singleProduct ? (
36 | <>
37 |
38 |

43 |
44 |
45 |
46 |
47 | {singleProduct?.category}
48 |
49 |
50 | {singleProduct?.title}
51 |
52 |
53 |
54 |
55 | {"₹ "}
56 |
57 | {Math.ceil(singleProduct?.price * 81)}
58 |
59 |
60 |
61 | Rating {": "}
62 |
63 | {singleProduct?.rating?.rate}
64 |
65 |
66 |
67 |
68 | {singleProduct?.description}
69 |
70 |
71 | Quantity :{" "}
72 |
73 | {singleProduct?.rating?.count} nos
74 |
75 |
76 |
77 |
80 |
86 |
87 |
88 | >
89 | ) : (
90 |
91 | No Itemes Found
92 |
93 | )}
94 | >
95 |
96 |
97 |
98 | );
99 | };
100 |
101 | export default DetailPage;
102 |
--------------------------------------------------------------------------------
/backend/controller/userController.js:
--------------------------------------------------------------------------------
1 | const asyncHandler = require("../middleware/asyncHandler");
2 | const userModel = require("../model/userModel");
3 | const cartModel = require("../model/cartModel");
4 | const bcrypt = require("bcrypt");
5 | const sendToken = require("../utils/jwt");
6 |
7 | // /api/user/login
8 | const login = asyncHandler(async (req, res) => {
9 | const { email, password } = req.body;
10 | if (!email || !password) {
11 | res.status(401).json({ success: false, message: "Invalid Credential" });
12 | } else {
13 | const isExist = await userModel.findOne({ email });
14 | if (!isExist) {
15 | res.status(401).json({ success: false, message: "Invalid Credential" });
16 | }
17 | const checkPassword = isExist.verifyPassword;
18 | if (checkPassword) {
19 | sendToken(isExist, res);
20 | } else {
21 | res.status(400).json({ success: false, message: "Invalid Credential" });
22 | }
23 | }
24 | });
25 |
26 | const register = asyncHandler(async (req, res) => {
27 | const { email, password, name } = req.body;
28 | if (!email || !password || !name) {
29 | res.status(401).json({ success: false, message: "Invalid credential" });
30 | }
31 | const isExist = await userModel.findOne({ email });
32 | if (!isExist) {
33 | const newUser = await userModel.create(req.body);
34 | sendToken(newUser, res);
35 | } else {
36 | res.status(400).json({ success: false, message: "Mail already exists" });
37 | }
38 | });
39 |
40 | const logout = asyncHandler(async (req, res) => {
41 | res.cookie("token", "", { httpOnly: true, expires: new Date(0) });
42 | res.status(200).json({ message: "Logout successfully" });
43 | });
44 |
45 | const addCart = asyncHandler(async (req, res) => {
46 | const { userId } = req;
47 | const { id } = req.body.product;
48 | const cart = await cartModel.findOne({ user: userId });
49 | if (cart) {
50 | const productExist = cart.cartItems.findIndex(
51 | (item) => item.product.id == id
52 | );
53 | if (productExist !== -1) {
54 | await cartModel.findOneAndUpdate(
55 | { user: userId, "cartItems.product.id": id },
56 | { $inc: { "cartItems.$.quantity": 1 } },
57 | { new: true }
58 | );
59 | const updatedProduct = await cartModel.findOne({ user: userId });
60 | res.status(200).json({
61 | message: "Added Cart",
62 | total: updatedProduct?.cartItems?.length,
63 | });
64 | } else {
65 | const addNewProduct = await cartModel.findOneAndUpdate(
66 | { user: userId },
67 | { $push: { cartItems: { product: { ...req.body.product } } } },
68 | { new: true }
69 | );
70 | res.status(200).json({
71 | message: "Added Cart",
72 | total: addNewProduct?.cartItems?.length,
73 | });
74 | }
75 | } else {
76 | const product = await cartModel.create({
77 | user: userId,
78 | cartItems: [{ product: { ...req.body.product } }],
79 | });
80 | res.status(200).json({
81 | message: "Added Cart",
82 | total: product?.cartItems?.length,
83 | });
84 | }
85 | });
86 |
87 | const removeCart = asyncHandler(async (req, res) => {
88 | const { userId } = req;
89 | const { id } = req.body;
90 | const cart = await cartModel.findOne({
91 | user: userId,
92 | "cartItems.product.id": id,
93 | });
94 | if (cart) {
95 | const response = await cartModel.findOneAndUpdate(
96 | {
97 | user: userId,
98 | "cartItems.product.id": id,
99 | },
100 | { $pull: { cartItems: { "product.id": id } } },
101 | { new: true }
102 | );
103 | res.status(200).json({
104 | message: "Item removed from cart",
105 | total: response?.cartItems?.length,
106 | });
107 | } else {
108 | res.status(404);
109 | throw new Error("item not found");
110 | }
111 | });
112 |
113 | const addCartQty = asyncHandler(async (req, res) => {
114 | const { userId } = req;
115 | const { productId } = req.body;
116 | const cart = await cartModel.findOne({
117 | user: userId,
118 | "cartItems.product.id": productId,
119 | });
120 | if (cart) {
121 | await cartModel.findOneAndUpdate(
122 | { "cartItems.product.id": productId },
123 | { $inc: { "cartItems.$.quantity": 1 } },
124 | { new: true }
125 | );
126 | res.status(200).json({ message: "Added qty" });
127 | } else {
128 | res.status(404);
129 | throw new Error("Item not found");
130 | }
131 | });
132 |
133 | const decreaseCartQty = asyncHandler(async (req, res) => {
134 | const { userId } = req;
135 | const { productId } = req.body;
136 | const cart = await cartModel.findOne({
137 | user: userId,
138 | "cartItems.product.id": productId,
139 | });
140 | if (cart) {
141 | await cartModel.findOneAndUpdate(
142 | { "cartItems.product.id": productId },
143 | { $inc: { "cartItems.$.quantity": -1 } },
144 | { new: true }
145 | );
146 | res.status(200).json({ message: "Decreased qty" });
147 | } else {
148 | res.status(404);
149 | throw new Error("Item not found");
150 | }
151 | });
152 |
153 | const getUserCart = asyncHandler(async (req, res) => {
154 | const { userId } = req;
155 | const cart = await cartModel.findOne({ user: userId });
156 | if (!cart) {
157 | res.status(404);
158 | throw new Error("Item not found");
159 | } else {
160 | res.status(200).json(cart);
161 | }
162 | });
163 |
164 | const getCartNumber = asyncHandler(async (req, res) => {
165 | const { userId } = req;
166 | // console.log(userId);
167 | const resPonse = await cartModel.findOne({ user: userId });
168 | if (resPonse) {
169 | res.status(200).json(resPonse?.cartItems.length);
170 | } else res.status(200).json(0);
171 | });
172 |
173 | module.exports = {
174 | login,
175 | register,
176 | logout,
177 | addCart,
178 | removeCart,
179 | decreaseCartQty,
180 | addCartQty,
181 | getUserCart,
182 | getCartNumber,
183 | };
184 |
--------------------------------------------------------------------------------
/frontend/store/appStore.js:
--------------------------------------------------------------------------------
1 | import { create } from "zustand";
2 | import API from "./../utils/axios";
3 | import { toast } from "react-toastify";
4 |
5 | const user = localStorage.getItem("user")
6 | ? JSON.parse(localStorage.getItem("user"))
7 | : null;
8 |
9 | export const useAppStore = create((set, get) => ({
10 | user: user,
11 | loading: false,
12 | cart: null,
13 | totalCart: null,
14 | loginUser: async (details, navigate) => {
15 | try {
16 | set((state) => ({ loading: true }));
17 | const { data, status } = await API("/api/user/login", {
18 | method: "POST",
19 | data: { ...details },
20 | });
21 | if (status === 200) {
22 | toast.success("Login successfully");
23 | set((state) => ({ loading: false, user: data.user }));
24 | localStorage.setItem("user", JSON.stringify(data.user));
25 | navigate("/");
26 | }
27 | } catch (error) {
28 | set((state) => ({ loading: false }));
29 | toast, error(error?.response?.data?.message);
30 | console.log(error);
31 | }
32 | },
33 | registerUser: async (details, navigate) => {
34 | try {
35 | set(() => ({ loading: true }));
36 | const { data, status } = await API("/api/user/register", {
37 | method: "POST",
38 | data: { ...details },
39 | });
40 |
41 | if (status === 200) {
42 | set(() => ({ loading: false, user: data.user }));
43 | localStorage.setItem("user", JSON.stringify(data.user));
44 | navigate("/");
45 | toast.success("Register successfully");
46 | }
47 | } catch (error) {
48 | set((state) => ({ loading: false }));
49 | toast, error(error?.response?.data?.message);
50 | console.log(error);
51 | }
52 | },
53 |
54 | addCart: async (product, navigate) => {
55 | try {
56 | set((state) => ({ loading: true }));
57 | const { data, status } = await API("/api/user/add-cart", {
58 | method: "POST",
59 | data: {
60 | product: { ...product },
61 | },
62 | });
63 | if (status === 200) {
64 | toast.success("Added to cart successfully");
65 | set((state) => ({
66 | loading: false,
67 | totalCart: data.total,
68 | }));
69 | }
70 | } catch (error) {
71 | set((state) => ({ loading: false }));
72 | if (error?.response?.status === 401) {
73 | navigate("/login");
74 | }
75 | toast.error(error?.response?.data?.message);
76 | console.log(error);
77 | }
78 | },
79 |
80 | addCartQty: async (id) => {
81 | try {
82 | set((state) => ({ loading: true }));
83 | const { data, status } = await API("/api/user/add-qty", {
84 | method: "POST",
85 | data: { productId: id },
86 | });
87 | if (status === 200) {
88 | toast.success("Added to cart successfully");
89 | let cart = get().cart;
90 | const updatedCart = cart.map((item) =>
91 | item.product.id === id
92 | ? { ...item, quantity: item.quantity + 1 }
93 | : item
94 | );
95 | set((state) => ({
96 | loading: false,
97 | cart: updatedCart,
98 | }));
99 | // set((state) => ({ loading: false, cart: [...state.cart.] }));
100 | }
101 | } catch (error) {
102 | set((state) => ({ loading: false }));
103 | toast.error(error?.response?.data?.message);
104 | console.log(error);
105 | }
106 | },
107 | removeCartQty: async (id) => {
108 | try {
109 | set((state) => ({ loading: true }));
110 | const { data, status } = await API("/api/user/decrease-qty", {
111 | method: "POST",
112 | data: { productId: id },
113 | });
114 | if (status === 200) {
115 | toast.success("Added to cart successfully");
116 | let cart = get().cart;
117 | const updatedCart = cart.map((item) =>
118 | item.product.id === id
119 | ? { ...item, quantity: item.quantity - 1 }
120 | : item
121 | );
122 | set((state) => ({
123 | loading: false,
124 | cart: updatedCart,
125 | }));
126 | // set((state) => ({ loading: false, cart: [...state.cart.] }));
127 | }
128 | } catch (error) {
129 | toast.error(error?.response?.data?.message);
130 | console.log(error);
131 | set((state) => ({ loading: false }));
132 | }
133 | },
134 |
135 | getUserCart: async () => {
136 | try {
137 | set((state) => ({ loading: true }));
138 | const { data, status } = await API("/api/user/get-user-cart");
139 | if (status === 200) {
140 | set((state) => ({ cart: data.cartItems, loading: false }));
141 | }
142 | } catch (error) {
143 | set((state) => ({ loading: false }));
144 | toast.error(error?.response?.data?.message);
145 | console.log(error);
146 | }
147 | },
148 | // getUserCart: async () => {
149 | // try {
150 | // set((state) => ({ loading: true }));
151 | // const { data, status } = await API("/api/user/get-user-cart");
152 | // if (status === 200) {
153 | // set((state) => ({ cart: data.cartItems, loading: false }));
154 | // }
155 | // } catch (error) {
156 | // set((state) => ({ loading: false }));
157 | // toast.error(error?.response?.data?.message);
158 | // console.log(error);
159 | // }
160 | // },
161 |
162 | removeCart: async (id) => {
163 | try {
164 | set((state) => ({ loading: true }));
165 | const { data, status } = await API("/api/user/remove-cart", {
166 | method: "DELETE",
167 | data: { id },
168 | });
169 | if (status === 200) {
170 | toast.success("Item removed successfully");
171 | let cart = get().cart;
172 | const updatedCart = cart.filter((item) => item.product.id !== id);
173 | set((state) => ({
174 | loading: false,
175 | cart: updatedCart,
176 | totalCart: data.total,
177 | }));
178 | }
179 | } catch (error) {
180 | set((state) => ({ loading: false }));
181 | toast.error(error?.response?.data?.message);
182 | console.log(error);
183 | }
184 | },
185 |
186 | logout: async (navigate, setShowMenu) => {
187 | try {
188 | set(() => ({ loading: true }));
189 | const { status } = await API("/api/user/logout", {
190 | method: "POST",
191 | });
192 |
193 | if (status === 200) {
194 | setShowMenu(false);
195 | set(() => ({ loading: false, user: null }));
196 | localStorage.clear();
197 | navigate("/");
198 | toast.success("Logged out successfully");
199 | }
200 | } catch (error) {
201 | set((state) => ({ loading: false }));
202 | toast, error(error?.response?.data?.message);
203 | console.log(error);
204 | }
205 | },
206 | }));
207 |
--------------------------------------------------------------------------------
/backend/data/products.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": 1,
4 | "title": "iPhone 9",
5 | "description": "An apple mobile which is nothing like apple",
6 | "price": 549,
7 | "discountPercentage": 12.96,
8 | "rating": 4.69,
9 | "stock": 94,
10 | "brand": "Apple",
11 | "category": "smartphones",
12 | "thumbnail": "https://i.dummyjson.com/data/products/1/thumbnail.jpg",
13 | "images": [
14 | "https://i.dummyjson.com/data/products/1/1.jpg",
15 | "https://i.dummyjson.com/data/products/1/2.jpg",
16 | "https://i.dummyjson.com/data/products/1/3.jpg",
17 | "https://i.dummyjson.com/data/products/1/4.jpg",
18 | "https://i.dummyjson.com/data/products/1/thumbnail.jpg"
19 | ]
20 | },
21 | {
22 | "id": 2,
23 | "title": "iPhone X",
24 | "description": "SIM-Free, Model A19211 6.5-inch Super Retina HD display with OLED technology A12 Bionic chip with ...",
25 | "price": 899,
26 | "discountPercentage": 17.94,
27 | "rating": 4.44,
28 | "stock": 34,
29 | "brand": "Apple",
30 | "category": "smartphones",
31 | "thumbnail": "https://i.dummyjson.com/data/products/2/thumbnail.jpg",
32 | "images": [
33 | "https://i.dummyjson.com/data/products/2/1.jpg",
34 | "https://i.dummyjson.com/data/products/2/2.jpg",
35 | "https://i.dummyjson.com/data/products/2/3.jpg",
36 | "https://i.dummyjson.com/data/products/2/thumbnail.jpg"
37 | ]
38 | },
39 | {
40 | "id": 3,
41 | "title": "Samsung Universe 9",
42 | "description": "Samsung's new variant which goes beyond Galaxy to the Universe",
43 | "price": 1249,
44 | "discountPercentage": 15.46,
45 | "rating": 4.09,
46 | "stock": 36,
47 | "brand": "Samsung",
48 | "category": "smartphones",
49 | "thumbnail": "https://i.dummyjson.com/data/products/3/thumbnail.jpg",
50 | "images": ["https://i.dummyjson.com/data/products/3/1.jpg"]
51 | },
52 | {
53 | "id": 4,
54 | "title": "OPPOF19",
55 | "description": "OPPO F19 is officially announced on April 2021.",
56 | "price": 280,
57 | "discountPercentage": 17.91,
58 | "rating": 4.3,
59 | "stock": 123,
60 | "brand": "OPPO",
61 | "category": "smartphones",
62 | "thumbnail": "https://i.dummyjson.com/data/products/4/thumbnail.jpg",
63 | "images": [
64 | "https://i.dummyjson.com/data/products/4/1.jpg",
65 | "https://i.dummyjson.com/data/products/4/2.jpg",
66 | "https://i.dummyjson.com/data/products/4/3.jpg",
67 | "https://i.dummyjson.com/data/products/4/4.jpg",
68 | "https://i.dummyjson.com/data/products/4/thumbnail.jpg"
69 | ]
70 | },
71 | {
72 | "id": 5,
73 | "title": "Huawei P30",
74 | "description": "Huawei’s re-badged P30 Pro New Edition was officially unveiled yesterday in Germany and now the device has made its way to the UK.",
75 | "price": 499,
76 | "discountPercentage": 10.58,
77 | "rating": 4.09,
78 | "stock": 32,
79 | "brand": "Huawei",
80 | "category": "smartphones",
81 | "thumbnail": "https://i.dummyjson.com/data/products/5/thumbnail.jpg",
82 | "images": [
83 | "https://i.dummyjson.com/data/products/5/1.jpg",
84 | "https://i.dummyjson.com/data/products/5/2.jpg",
85 | "https://i.dummyjson.com/data/products/5/3.jpg"
86 | ]
87 | },
88 | {
89 | "id": 6,
90 | "title": "MacBook Pro",
91 | "description": "MacBook Pro 2021 with mini-LED display may launch between September, November",
92 | "price": 1749,
93 | "discountPercentage": 11.02,
94 | "rating": 4.57,
95 | "stock": 83,
96 | "brand": "Apple",
97 | "category": "laptops",
98 | "thumbnail": "https://i.dummyjson.com/data/products/6/thumbnail.png",
99 | "images": [
100 | "https://i.dummyjson.com/data/products/6/1.png",
101 | "https://i.dummyjson.com/data/products/6/2.jpg",
102 | "https://i.dummyjson.com/data/products/6/3.png",
103 | "https://i.dummyjson.com/data/products/6/4.jpg"
104 | ]
105 | },
106 | {
107 | "id": 7,
108 | "title": "Samsung Galaxy Book",
109 | "description": "Samsung Galaxy Book S (2020) Laptop With Intel Lakefield Chip, 8GB of RAM Launched",
110 | "price": 1499,
111 | "discountPercentage": 4.15,
112 | "rating": 4.25,
113 | "stock": 50,
114 | "brand": "Samsung",
115 | "category": "laptops",
116 | "thumbnail": "https://i.dummyjson.com/data/products/7/thumbnail.jpg",
117 | "images": [
118 | "https://i.dummyjson.com/data/products/7/1.jpg",
119 | "https://i.dummyjson.com/data/products/7/2.jpg",
120 | "https://i.dummyjson.com/data/products/7/3.jpg",
121 | "https://i.dummyjson.com/data/products/7/thumbnail.jpg"
122 | ]
123 | },
124 | {
125 | "id": 8,
126 | "title": "Microsoft Surface Laptop 4",
127 | "description": "Style and speed. Stand out on HD video calls backed by Studio Mics. Capture ideas on the vibrant touchscreen.",
128 | "price": 1499,
129 | "discountPercentage": 10.23,
130 | "rating": 4.43,
131 | "stock": 68,
132 | "brand": "Microsoft Surface",
133 | "category": "laptops",
134 | "thumbnail": "https://i.dummyjson.com/data/products/8/thumbnail.jpg",
135 | "images": [
136 | "https://i.dummyjson.com/data/products/8/1.jpg",
137 | "https://i.dummyjson.com/data/products/8/2.jpg",
138 | "https://i.dummyjson.com/data/products/8/3.jpg",
139 | "https://i.dummyjson.com/data/products/8/4.jpg",
140 | "https://i.dummyjson.com/data/products/8/thumbnail.jpg"
141 | ]
142 | },
143 | {
144 | "id": 9,
145 | "title": "Infinix INBOOK",
146 | "description": "Infinix Inbook X1 Ci3 10th 8GB 256GB 14 Win10 Grey – 1 Year Warranty",
147 | "price": 1099,
148 | "discountPercentage": 11.83,
149 | "rating": 4.54,
150 | "stock": 96,
151 | "brand": "Infinix",
152 | "category": "laptops",
153 | "thumbnail": "https://i.dummyjson.com/data/products/9/thumbnail.jpg",
154 | "images": [
155 | "https://i.dummyjson.com/data/products/9/1.jpg",
156 | "https://i.dummyjson.com/data/products/9/2.png",
157 | "https://i.dummyjson.com/data/products/9/3.png",
158 | "https://i.dummyjson.com/data/products/9/4.jpg",
159 | "https://i.dummyjson.com/data/products/9/thumbnail.jpg"
160 | ]
161 | },
162 | {
163 | "id": 10,
164 | "title": "HP Pavilion 15-DK1056WM",
165 | "description": "HP Pavilion 15-DK1056WM Gaming Laptop 10th Gen Core i5, 8GB, 256GB SSD, GTX 1650 4GB, Windows 10",
166 | "price": 1099,
167 | "discountPercentage": 6.18,
168 | "rating": 4.43,
169 | "stock": 89,
170 | "brand": "HP Pavilion",
171 | "category": "laptops",
172 | "thumbnail": "https://i.dummyjson.com/data/products/10/thumbnail.jpeg",
173 | "images": [
174 | "https://i.dummyjson.com/data/products/10/1.jpg",
175 | "https://i.dummyjson.com/data/products/10/2.jpg",
176 | "https://i.dummyjson.com/data/products/10/3.jpg",
177 | "https://i.dummyjson.com/data/products/10/thumbnail.jpeg"
178 | ]
179 | },
180 | {
181 | "id": 11,
182 | "title": "perfume Oil",
183 | "description": "Mega Discount, Impression of Acqua Di Gio by GiorgioArmani concentrated attar perfume Oil",
184 | "price": 13,
185 | "discountPercentage": 8.4,
186 | "rating": 4.26,
187 | "stock": 65,
188 | "brand": "Impression of Acqua Di Gio",
189 | "category": "fragrances",
190 | "thumbnail": "https://i.dummyjson.com/data/products/11/thumbnail.jpg",
191 | "images": [
192 | "https://i.dummyjson.com/data/products/11/1.jpg",
193 | "https://i.dummyjson.com/data/products/11/2.jpg",
194 | "https://i.dummyjson.com/data/products/11/3.jpg",
195 | "https://i.dummyjson.com/data/products/11/thumbnail.jpg"
196 | ]
197 | },
198 | {
199 | "id": 12,
200 | "title": "Brown Perfume",
201 | "description": "Royal_Mirage Sport Brown Perfume for Men & Women - 120ml",
202 | "price": 40,
203 | "discountPercentage": 15.66,
204 | "rating": 4,
205 | "stock": 52,
206 | "brand": "Royal_Mirage",
207 | "category": "fragrances",
208 | "thumbnail": "https://i.dummyjson.com/data/products/12/thumbnail.jpg",
209 | "images": [
210 | "https://i.dummyjson.com/data/products/12/1.jpg",
211 | "https://i.dummyjson.com/data/products/12/2.jpg",
212 | "https://i.dummyjson.com/data/products/12/3.png",
213 | "https://i.dummyjson.com/data/products/12/4.jpg",
214 | "https://i.dummyjson.com/data/products/12/thumbnail.jpg"
215 | ]
216 | },
217 | {
218 | "id": 13,
219 | "title": "Fog Scent Xpressio Perfume",
220 | "description": "Product details of Best Fog Scent Xpressio Perfume 100ml For Men cool long lasting perfumes for Men",
221 | "price": 13,
222 | "discountPercentage": 8.14,
223 | "rating": 4.59,
224 | "stock": 61,
225 | "brand": "Fog Scent Xpressio",
226 | "category": "fragrances",
227 | "thumbnail": "https://i.dummyjson.com/data/products/13/thumbnail.webp",
228 | "images": [
229 | "https://i.dummyjson.com/data/products/13/1.jpg",
230 | "https://i.dummyjson.com/data/products/13/2.png",
231 | "https://i.dummyjson.com/data/products/13/3.jpg",
232 | "https://i.dummyjson.com/data/products/13/4.jpg",
233 | "https://i.dummyjson.com/data/products/13/thumbnail.webp"
234 | ]
235 | },
236 | {
237 | "id": 14,
238 | "title": "Non-Alcoholic Concentrated Perfume Oil",
239 | "description": "Original Al Munakh® by Mahal Al Musk | Our Impression of Climate | 6ml Non-Alcoholic Concentrated Perfume Oil",
240 | "price": 120,
241 | "discountPercentage": 15.6,
242 | "rating": 4.21,
243 | "stock": 114,
244 | "brand": "Al Munakh",
245 | "category": "fragrances",
246 | "thumbnail": "https://i.dummyjson.com/data/products/14/thumbnail.jpg",
247 | "images": [
248 | "https://i.dummyjson.com/data/products/14/1.jpg",
249 | "https://i.dummyjson.com/data/products/14/2.jpg",
250 | "https://i.dummyjson.com/data/products/14/3.jpg",
251 | "https://i.dummyjson.com/data/products/14/thumbnail.jpg"
252 | ]
253 | },
254 | {
255 | "id": 15,
256 | "title": "Eau De Perfume Spray",
257 | "description": "Genuine Al-Rehab spray perfume from UAE/Saudi Arabia/Yemen High Quality",
258 | "price": 30,
259 | "discountPercentage": 10.99,
260 | "rating": 4.7,
261 | "stock": 105,
262 | "brand": "Lord - Al-Rehab",
263 | "category": "fragrances",
264 | "thumbnail": "https://i.dummyjson.com/data/products/15/thumbnail.jpg",
265 | "images": [
266 | "https://i.dummyjson.com/data/products/15/1.jpg",
267 | "https://i.dummyjson.com/data/products/15/2.jpg",
268 | "https://i.dummyjson.com/data/products/15/3.jpg",
269 | "https://i.dummyjson.com/data/products/15/4.jpg",
270 | "https://i.dummyjson.com/data/products/15/thumbnail.jpg"
271 | ]
272 | },
273 | {
274 | "id": 16,
275 | "title": "Hyaluronic Acid Serum",
276 | "description": "L'Oréal Paris introduces Hyaluron Expert Replumping Serum formulated with 1.5% Hyaluronic Acid",
277 | "price": 19,
278 | "discountPercentage": 13.31,
279 | "rating": 4.83,
280 | "stock": 110,
281 | "brand": "L'Oreal Paris",
282 | "category": "skincare",
283 | "thumbnail": "https://i.dummyjson.com/data/products/16/thumbnail.jpg",
284 | "images": [
285 | "https://i.dummyjson.com/data/products/16/1.png",
286 | "https://i.dummyjson.com/data/products/16/2.webp",
287 | "https://i.dummyjson.com/data/products/16/3.jpg",
288 | "https://i.dummyjson.com/data/products/16/4.jpg",
289 | "https://i.dummyjson.com/data/products/16/thumbnail.jpg"
290 | ]
291 | },
292 | {
293 | "id": 17,
294 | "title": "Tree Oil 30ml",
295 | "description": "Tea tree oil contains a number of compounds, including terpinen-4-ol, that have been shown to kill certain bacteria,",
296 | "price": 12,
297 | "discountPercentage": 4.09,
298 | "rating": 4.52,
299 | "stock": 78,
300 | "brand": "Hemani Tea",
301 | "category": "skincare",
302 | "thumbnail": "https://i.dummyjson.com/data/products/17/thumbnail.jpg",
303 | "images": [
304 | "https://i.dummyjson.com/data/products/17/1.jpg",
305 | "https://i.dummyjson.com/data/products/17/2.jpg",
306 | "https://i.dummyjson.com/data/products/17/3.jpg",
307 | "https://i.dummyjson.com/data/products/17/thumbnail.jpg"
308 | ]
309 | },
310 | {
311 | "id": 18,
312 | "title": "Oil Free Moisturizer 100ml",
313 | "description": "Dermive Oil Free Moisturizer with SPF 20 is specifically formulated with ceramides, hyaluronic acid & sunscreen.",
314 | "price": 40,
315 | "discountPercentage": 13.1,
316 | "rating": 4.56,
317 | "stock": 88,
318 | "brand": "Dermive",
319 | "category": "skincare",
320 | "thumbnail": "https://i.dummyjson.com/data/products/18/thumbnail.jpg",
321 | "images": [
322 | "https://i.dummyjson.com/data/products/18/1.jpg",
323 | "https://i.dummyjson.com/data/products/18/2.jpg",
324 | "https://i.dummyjson.com/data/products/18/3.jpg",
325 | "https://i.dummyjson.com/data/products/18/4.jpg",
326 | "https://i.dummyjson.com/data/products/18/thumbnail.jpg"
327 | ]
328 | },
329 | {
330 | "id": 19,
331 | "title": "Skin Beauty Serum.",
332 | "description": "Product name: rorec collagen hyaluronic acid white face serum riceNet weight: 15 m",
333 | "price": 46,
334 | "discountPercentage": 10.68,
335 | "rating": 4.42,
336 | "stock": 54,
337 | "brand": "ROREC White Rice",
338 | "category": "skincare",
339 | "thumbnail": "https://i.dummyjson.com/data/products/19/thumbnail.jpg",
340 | "images": [
341 | "https://i.dummyjson.com/data/products/19/1.jpg",
342 | "https://i.dummyjson.com/data/products/19/2.jpg",
343 | "https://i.dummyjson.com/data/products/19/3.png",
344 | "https://i.dummyjson.com/data/products/19/thumbnail.jpg"
345 | ]
346 | },
347 | {
348 | "id": 20,
349 | "title": "Freckle Treatment Cream- 15gm",
350 | "description": "Fair & Clear is Pakistan's only pure Freckle cream which helpsfade Freckles, Darkspots and pigments. Mercury level is 0%, so there are no side effects.",
351 | "price": 70,
352 | "discountPercentage": 16.99,
353 | "rating": 4.06,
354 | "stock": 140,
355 | "brand": "Fair & Clear",
356 | "category": "skincare",
357 | "thumbnail": "https://i.dummyjson.com/data/products/20/thumbnail.jpg",
358 | "images": [
359 | "https://i.dummyjson.com/data/products/20/1.jpg",
360 | "https://i.dummyjson.com/data/products/20/2.jpg",
361 | "https://i.dummyjson.com/data/products/20/3.jpg",
362 | "https://i.dummyjson.com/data/products/20/4.jpg",
363 | "https://i.dummyjson.com/data/products/20/thumbnail.jpg"
364 | ]
365 | },
366 | {
367 | "id": 21,
368 | "title": "- Daal Masoor 500 grams",
369 | "description": "Fine quality Branded Product Keep in a cool and dry place",
370 | "price": 20,
371 | "discountPercentage": 4.81,
372 | "rating": 4.44,
373 | "stock": 133,
374 | "brand": "Saaf & Khaas",
375 | "category": "groceries",
376 | "thumbnail": "https://i.dummyjson.com/data/products/21/thumbnail.png",
377 | "images": [
378 | "https://i.dummyjson.com/data/products/21/1.png",
379 | "https://i.dummyjson.com/data/products/21/2.jpg",
380 | "https://i.dummyjson.com/data/products/21/3.jpg"
381 | ]
382 | },
383 | {
384 | "id": 22,
385 | "title": "Elbow Macaroni - 400 gm",
386 | "description": "Product details of Bake Parlor Big Elbow Macaroni - 400 gm",
387 | "price": 14,
388 | "discountPercentage": 15.58,
389 | "rating": 4.57,
390 | "stock": 146,
391 | "brand": "Bake Parlor Big",
392 | "category": "groceries",
393 | "thumbnail": "https://i.dummyjson.com/data/products/22/thumbnail.jpg",
394 | "images": [
395 | "https://i.dummyjson.com/data/products/22/1.jpg",
396 | "https://i.dummyjson.com/data/products/22/2.jpg",
397 | "https://i.dummyjson.com/data/products/22/3.jpg"
398 | ]
399 | },
400 | {
401 | "id": 23,
402 | "title": "Orange Essence Food Flavou",
403 | "description": "Specifications of Orange Essence Food Flavour For Cakes and Baking Food Item",
404 | "price": 14,
405 | "discountPercentage": 8.04,
406 | "rating": 4.85,
407 | "stock": 26,
408 | "brand": "Baking Food Items",
409 | "category": "groceries",
410 | "thumbnail": "https://i.dummyjson.com/data/products/23/thumbnail.jpg",
411 | "images": [
412 | "https://i.dummyjson.com/data/products/23/1.jpg",
413 | "https://i.dummyjson.com/data/products/23/2.jpg",
414 | "https://i.dummyjson.com/data/products/23/3.jpg",
415 | "https://i.dummyjson.com/data/products/23/4.jpg",
416 | "https://i.dummyjson.com/data/products/23/thumbnail.jpg"
417 | ]
418 | },
419 | {
420 | "id": 24,
421 | "title": "cereals muesli fruit nuts",
422 | "description": "original fauji cereal muesli 250gm box pack original fauji cereals muesli fruit nuts flakes breakfast cereal break fast faujicereals cerels cerel foji fouji",
423 | "price": 46,
424 | "discountPercentage": 16.8,
425 | "rating": 4.94,
426 | "stock": 113,
427 | "brand": "fauji",
428 | "category": "groceries",
429 | "thumbnail": "https://i.dummyjson.com/data/products/24/thumbnail.jpg",
430 | "images": [
431 | "https://i.dummyjson.com/data/products/24/1.jpg",
432 | "https://i.dummyjson.com/data/products/24/2.jpg",
433 | "https://i.dummyjson.com/data/products/24/3.jpg",
434 | "https://i.dummyjson.com/data/products/24/4.jpg",
435 | "https://i.dummyjson.com/data/products/24/thumbnail.jpg"
436 | ]
437 | },
438 | {
439 | "id": 25,
440 | "title": "Gulab Powder 50 Gram",
441 | "description": "Dry Rose Flower Powder Gulab Powder 50 Gram • Treats Wounds",
442 | "price": 70,
443 | "discountPercentage": 13.58,
444 | "rating": 4.87,
445 | "stock": 47,
446 | "brand": "Dry Rose",
447 | "category": "groceries",
448 | "thumbnail": "https://i.dummyjson.com/data/products/25/thumbnail.jpg",
449 | "images": [
450 | "https://i.dummyjson.com/data/products/25/1.png",
451 | "https://i.dummyjson.com/data/products/25/2.jpg",
452 | "https://i.dummyjson.com/data/products/25/3.png",
453 | "https://i.dummyjson.com/data/products/25/4.jpg",
454 | "https://i.dummyjson.com/data/products/25/thumbnail.jpg"
455 | ]
456 | },
457 | {
458 | "id": 26,
459 | "title": "Plant Hanger For Home",
460 | "description": "Boho Decor Plant Hanger For Home Wall Decoration Macrame Wall Hanging Shelf",
461 | "price": 41,
462 | "discountPercentage": 17.86,
463 | "rating": 4.08,
464 | "stock": 131,
465 | "brand": "Boho Decor",
466 | "category": "home-decoration",
467 | "thumbnail": "https://i.dummyjson.com/data/products/26/thumbnail.jpg",
468 | "images": [
469 | "https://i.dummyjson.com/data/products/26/1.jpg",
470 | "https://i.dummyjson.com/data/products/26/2.jpg",
471 | "https://i.dummyjson.com/data/products/26/3.jpg",
472 | "https://i.dummyjson.com/data/products/26/4.jpg",
473 | "https://i.dummyjson.com/data/products/26/5.jpg",
474 | "https://i.dummyjson.com/data/products/26/thumbnail.jpg"
475 | ]
476 | },
477 | {
478 | "id": 27,
479 | "title": "Flying Wooden Bird",
480 | "description": "Package Include 6 Birds with Adhesive Tape Shape: 3D Shaped Wooden Birds Material: Wooden MDF, Laminated 3.5mm",
481 | "price": 51,
482 | "discountPercentage": 15.58,
483 | "rating": 4.41,
484 | "stock": 17,
485 | "brand": "Flying Wooden",
486 | "category": "home-decoration",
487 | "thumbnail": "https://i.dummyjson.com/data/products/27/thumbnail.webp",
488 | "images": [
489 | "https://i.dummyjson.com/data/products/27/1.jpg",
490 | "https://i.dummyjson.com/data/products/27/2.jpg",
491 | "https://i.dummyjson.com/data/products/27/3.jpg",
492 | "https://i.dummyjson.com/data/products/27/4.jpg",
493 | "https://i.dummyjson.com/data/products/27/thumbnail.webp"
494 | ]
495 | },
496 | {
497 | "id": 28,
498 | "title": "3D Embellishment Art Lamp",
499 | "description": "3D led lamp sticker Wall sticker 3d wall art light on/off button cell operated (included)",
500 | "price": 20,
501 | "discountPercentage": 16.49,
502 | "rating": 4.82,
503 | "stock": 54,
504 | "brand": "LED Lights",
505 | "category": "home-decoration",
506 | "thumbnail": "https://i.dummyjson.com/data/products/28/thumbnail.jpg",
507 | "images": [
508 | "https://i.dummyjson.com/data/products/28/1.jpg",
509 | "https://i.dummyjson.com/data/products/28/2.jpg",
510 | "https://i.dummyjson.com/data/products/28/3.png",
511 | "https://i.dummyjson.com/data/products/28/4.jpg",
512 | "https://i.dummyjson.com/data/products/28/thumbnail.jpg"
513 | ]
514 | },
515 | {
516 | "id": 29,
517 | "title": "Handcraft Chinese style",
518 | "description": "Handcraft Chinese style art luxury palace hotel villa mansion home decor ceramic vase with brass fruit plate",
519 | "price": 60,
520 | "discountPercentage": 15.34,
521 | "rating": 4.44,
522 | "stock": 7,
523 | "brand": "luxury palace",
524 | "category": "home-decoration",
525 | "thumbnail": "https://i.dummyjson.com/data/products/29/thumbnail.webp",
526 | "images": [
527 | "https://i.dummyjson.com/data/products/29/1.jpg",
528 | "https://i.dummyjson.com/data/products/29/2.jpg",
529 | "https://i.dummyjson.com/data/products/29/3.webp",
530 | "https://i.dummyjson.com/data/products/29/4.webp",
531 | "https://i.dummyjson.com/data/products/29/thumbnail.webp"
532 | ]
533 | },
534 | {
535 | "id": 30,
536 | "title": "Key Holder",
537 | "description": "Attractive DesignMetallic materialFour key hooksReliable & DurablePremium Quality",
538 | "price": 30,
539 | "discountPercentage": 2.92,
540 | "rating": 4.92,
541 | "stock": 54,
542 | "brand": "Golden",
543 | "category": "home-decoration",
544 | "thumbnail": "https://i.dummyjson.com/data/products/30/thumbnail.jpg",
545 | "images": [
546 | "https://i.dummyjson.com/data/products/30/1.jpg",
547 | "https://i.dummyjson.com/data/products/30/2.jpg",
548 | "https://i.dummyjson.com/data/products/30/3.jpg",
549 | "https://i.dummyjson.com/data/products/30/thumbnail.jpg"
550 | ]
551 | },
552 | {
553 | "id": 31,
554 | "title": "Mornadi Velvet Bed",
555 | "description": "Mornadi Velvet Bed Base with Headboard Slats Support Classic Style Bedroom Furniture Bed Set",
556 | "price": 40,
557 | "discountPercentage": 17,
558 | "rating": 4.16,
559 | "stock": 140,
560 | "brand": "Furniture Bed Set",
561 | "category": "furniture",
562 | "thumbnail": "https://i.dummyjson.com/data/products/31/thumbnail.jpg",
563 | "images": [
564 | "https://i.dummyjson.com/data/products/31/1.jpg",
565 | "https://i.dummyjson.com/data/products/31/2.jpg",
566 | "https://i.dummyjson.com/data/products/31/3.jpg",
567 | "https://i.dummyjson.com/data/products/31/4.jpg",
568 | "https://i.dummyjson.com/data/products/31/thumbnail.jpg"
569 | ]
570 | },
571 | {
572 | "id": 32,
573 | "title": "Sofa for Coffe Cafe",
574 | "description": "Ratttan Outdoor furniture Set Waterproof Rattan Sofa for Coffe Cafe",
575 | "price": 50,
576 | "discountPercentage": 15.59,
577 | "rating": 4.74,
578 | "stock": 30,
579 | "brand": "Ratttan Outdoor",
580 | "category": "furniture",
581 | "thumbnail": "https://i.dummyjson.com/data/products/32/thumbnail.jpg",
582 | "images": [
583 | "https://i.dummyjson.com/data/products/32/1.jpg",
584 | "https://i.dummyjson.com/data/products/32/2.jpg",
585 | "https://i.dummyjson.com/data/products/32/3.jpg",
586 | "https://i.dummyjson.com/data/products/32/thumbnail.jpg"
587 | ]
588 | },
589 | {
590 | "id": 33,
591 | "title": "3 Tier Corner Shelves",
592 | "description": "3 Tier Corner Shelves | 3 PCs Wall Mount Kitchen Shelf | Floating Bedroom Shelf",
593 | "price": 700,
594 | "discountPercentage": 17,
595 | "rating": 4.31,
596 | "stock": 106,
597 | "brand": "Kitchen Shelf",
598 | "category": "furniture",
599 | "thumbnail": "https://i.dummyjson.com/data/products/33/thumbnail.jpg",
600 | "images": [
601 | "https://i.dummyjson.com/data/products/33/1.jpg",
602 | "https://i.dummyjson.com/data/products/33/2.jpg",
603 | "https://i.dummyjson.com/data/products/33/3.jpg",
604 | "https://i.dummyjson.com/data/products/33/4.jpg",
605 | "https://i.dummyjson.com/data/products/33/thumbnail.jpg"
606 | ]
607 | },
608 | {
609 | "id": 34,
610 | "title": "Plastic Table",
611 | "description": "Very good quality plastic table for multi purpose now in reasonable price",
612 | "price": 50,
613 | "discountPercentage": 4,
614 | "rating": 4.01,
615 | "stock": 136,
616 | "brand": "Multi Purpose",
617 | "category": "furniture",
618 | "thumbnail": "https://i.dummyjson.com/data/products/34/thumbnail.jpg",
619 | "images": [
620 | "https://i.dummyjson.com/data/products/34/1.jpg",
621 | "https://i.dummyjson.com/data/products/34/2.jpg",
622 | "https://i.dummyjson.com/data/products/34/3.jpg",
623 | "https://i.dummyjson.com/data/products/34/4.jpg",
624 | "https://i.dummyjson.com/data/products/34/thumbnail.jpg"
625 | ]
626 | },
627 | {
628 | "id": 35,
629 | "title": "3 DOOR PORTABLE",
630 | "description": "Material: Stainless Steel and Fabric Item Size: 110 cm x 45 cm x 175 cm Package Contents: 1 Storage Wardrobe",
631 | "price": 41,
632 | "discountPercentage": 7.98,
633 | "rating": 4.06,
634 | "stock": 68,
635 | "brand": "AmnaMart",
636 | "category": "furniture",
637 | "thumbnail": "https://i.dummyjson.com/data/products/35/thumbnail.jpg",
638 | "images": [
639 | "https://i.dummyjson.com/data/products/35/1.jpg",
640 | "https://i.dummyjson.com/data/products/35/2.jpg",
641 | "https://i.dummyjson.com/data/products/35/3.jpg",
642 | "https://i.dummyjson.com/data/products/35/4.jpg",
643 | "https://i.dummyjson.com/data/products/35/thumbnail.jpg"
644 | ]
645 | },
646 | {
647 | "id": 36,
648 | "title": "Sleeve Shirt Womens",
649 | "description": "Cotton Solid Color Professional Wear Sleeve Shirt Womens Work Blouses Wholesale Clothing Casual Plain Custom Top OEM Customized",
650 | "price": 90,
651 | "discountPercentage": 10.89,
652 | "rating": 4.26,
653 | "stock": 39,
654 | "brand": "Professional Wear",
655 | "category": "tops",
656 | "thumbnail": "https://i.dummyjson.com/data/products/36/thumbnail.jpg",
657 | "images": [
658 | "https://i.dummyjson.com/data/products/36/1.jpg",
659 | "https://i.dummyjson.com/data/products/36/2.webp",
660 | "https://i.dummyjson.com/data/products/36/3.webp",
661 | "https://i.dummyjson.com/data/products/36/4.jpg",
662 | "https://i.dummyjson.com/data/products/36/thumbnail.jpg"
663 | ]
664 | },
665 | {
666 | "id": 37,
667 | "title": "ank Tops for Womens/Girls",
668 | "description": "PACK OF 3 CAMISOLES ,VERY COMFORTABLE SOFT COTTON STUFF, COMFORTABLE IN ALL FOUR SEASONS",
669 | "price": 50,
670 | "discountPercentage": 12.05,
671 | "rating": 4.52,
672 | "stock": 107,
673 | "brand": "Soft Cotton",
674 | "category": "tops",
675 | "thumbnail": "https://i.dummyjson.com/data/products/37/thumbnail.jpg",
676 | "images": [
677 | "https://i.dummyjson.com/data/products/37/1.jpg",
678 | "https://i.dummyjson.com/data/products/37/2.jpg",
679 | "https://i.dummyjson.com/data/products/37/3.jpg",
680 | "https://i.dummyjson.com/data/products/37/4.jpg",
681 | "https://i.dummyjson.com/data/products/37/thumbnail.jpg"
682 | ]
683 | },
684 | {
685 | "id": 38,
686 | "title": "sublimation plain kids tank",
687 | "description": "sublimation plain kids tank tops wholesale",
688 | "price": 100,
689 | "discountPercentage": 11.12,
690 | "rating": 4.8,
691 | "stock": 20,
692 | "brand": "Soft Cotton",
693 | "category": "tops",
694 | "thumbnail": "https://i.dummyjson.com/data/products/38/thumbnail.jpg",
695 | "images": [
696 | "https://i.dummyjson.com/data/products/38/1.png",
697 | "https://i.dummyjson.com/data/products/38/2.jpg",
698 | "https://i.dummyjson.com/data/products/38/3.jpg",
699 | "https://i.dummyjson.com/data/products/38/4.jpg"
700 | ]
701 | },
702 | {
703 | "id": 39,
704 | "title": "Women Sweaters Wool",
705 | "description": "2021 Custom Winter Fall Zebra Knit Crop Top Women Sweaters Wool Mohair Cos Customize Crew Neck Women' S Crop Top Sweater",
706 | "price": 600,
707 | "discountPercentage": 17.2,
708 | "rating": 4.55,
709 | "stock": 55,
710 | "brand": "Top Sweater",
711 | "category": "tops",
712 | "thumbnail": "https://i.dummyjson.com/data/products/39/thumbnail.jpg",
713 | "images": [
714 | "https://i.dummyjson.com/data/products/39/1.jpg",
715 | "https://i.dummyjson.com/data/products/39/2.jpg",
716 | "https://i.dummyjson.com/data/products/39/3.jpg",
717 | "https://i.dummyjson.com/data/products/39/4.jpg",
718 | "https://i.dummyjson.com/data/products/39/thumbnail.jpg"
719 | ]
720 | },
721 | {
722 | "id": 40,
723 | "title": "women winter clothes",
724 | "description": "women winter clothes thick fleece hoodie top with sweat pantjogger women sweatsuit set joggers pants two piece pants set",
725 | "price": 57,
726 | "discountPercentage": 13.39,
727 | "rating": 4.91,
728 | "stock": 84,
729 | "brand": "Top Sweater",
730 | "category": "tops",
731 | "thumbnail": "https://i.dummyjson.com/data/products/40/thumbnail.jpg",
732 | "images": [
733 | "https://i.dummyjson.com/data/products/40/1.jpg",
734 | "https://i.dummyjson.com/data/products/40/2.jpg"
735 | ]
736 | },
737 | {
738 | "id": 41,
739 | "title": "NIGHT SUIT",
740 | "description": "NIGHT SUIT RED MICKY MOUSE.. For Girls. Fantastic Suits.",
741 | "price": 55,
742 | "discountPercentage": 15.05,
743 | "rating": 4.65,
744 | "stock": 21,
745 | "brand": "RED MICKY MOUSE..",
746 | "category": "womens-dresses",
747 | "thumbnail": "https://i.dummyjson.com/data/products/41/thumbnail.webp",
748 | "images": [
749 | "https://i.dummyjson.com/data/products/41/1.jpg",
750 | "https://i.dummyjson.com/data/products/41/2.webp",
751 | "https://i.dummyjson.com/data/products/41/3.jpg",
752 | "https://i.dummyjson.com/data/products/41/4.jpg",
753 | "https://i.dummyjson.com/data/products/41/thumbnail.webp"
754 | ]
755 | },
756 | {
757 | "id": 42,
758 | "title": "Stiched Kurta plus trouser",
759 | "description": "FABRIC: LILEIN CHEST: 21 LENGHT: 37 TROUSER: (38) :ARABIC LILEIN",
760 | "price": 80,
761 | "discountPercentage": 15.37,
762 | "rating": 4.05,
763 | "stock": 148,
764 | "brand": "Digital Printed",
765 | "category": "womens-dresses",
766 | "thumbnail": "https://i.dummyjson.com/data/products/42/thumbnail.jpg",
767 | "images": [
768 | "https://i.dummyjson.com/data/products/42/1.png",
769 | "https://i.dummyjson.com/data/products/42/2.png",
770 | "https://i.dummyjson.com/data/products/42/3.png",
771 | "https://i.dummyjson.com/data/products/42/4.jpg",
772 | "https://i.dummyjson.com/data/products/42/thumbnail.jpg"
773 | ]
774 | },
775 | {
776 | "id": 43,
777 | "title": "frock gold printed",
778 | "description": "Ghazi fabric long frock gold printed ready to wear stitched collection (G992)",
779 | "price": 600,
780 | "discountPercentage": 15.55,
781 | "rating": 4.31,
782 | "stock": 150,
783 | "brand": "Ghazi Fabric",
784 | "category": "womens-dresses",
785 | "thumbnail": "https://i.dummyjson.com/data/products/43/thumbnail.jpg",
786 | "images": [
787 | "https://i.dummyjson.com/data/products/43/1.jpg",
788 | "https://i.dummyjson.com/data/products/43/2.jpg",
789 | "https://i.dummyjson.com/data/products/43/3.jpg",
790 | "https://i.dummyjson.com/data/products/43/4.jpg",
791 | "https://i.dummyjson.com/data/products/43/thumbnail.jpg"
792 | ]
793 | },
794 | {
795 | "id": 44,
796 | "title": "Ladies Multicolored Dress",
797 | "description": "This classy shirt for women gives you a gorgeous look on everyday wear and specially for semi-casual wears.",
798 | "price": 79,
799 | "discountPercentage": 16.88,
800 | "rating": 4.03,
801 | "stock": 2,
802 | "brand": "Ghazi Fabric",
803 | "category": "womens-dresses",
804 | "thumbnail": "https://i.dummyjson.com/data/products/44/thumbnail.jpg",
805 | "images": [
806 | "https://i.dummyjson.com/data/products/44/1.jpg",
807 | "https://i.dummyjson.com/data/products/44/2.jpg",
808 | "https://i.dummyjson.com/data/products/44/3.jpg",
809 | "https://i.dummyjson.com/data/products/44/4.jpg",
810 | "https://i.dummyjson.com/data/products/44/thumbnail.jpg"
811 | ]
812 | },
813 | {
814 | "id": 45,
815 | "title": "Malai Maxi Dress",
816 | "description": "Ready to wear, Unique design according to modern standard fashion, Best fitting ,Imported stuff",
817 | "price": 50,
818 | "discountPercentage": 5.07,
819 | "rating": 4.67,
820 | "stock": 96,
821 | "brand": "IELGY",
822 | "category": "womens-dresses",
823 | "thumbnail": "https://i.dummyjson.com/data/products/45/thumbnail.jpg",
824 | "images": [
825 | "https://i.dummyjson.com/data/products/45/1.jpg",
826 | "https://i.dummyjson.com/data/products/45/2.webp",
827 | "https://i.dummyjson.com/data/products/45/3.jpg",
828 | "https://i.dummyjson.com/data/products/45/4.jpg",
829 | "https://i.dummyjson.com/data/products/45/thumbnail.jpg"
830 | ]
831 | },
832 | {
833 | "id": 46,
834 | "title": "women's shoes",
835 | "description": "Close: Lace, Style with bottom: Increased inside, Sole Material: Rubber",
836 | "price": 40,
837 | "discountPercentage": 16.96,
838 | "rating": 4.14,
839 | "stock": 72,
840 | "brand": "IELGY fashion",
841 | "category": "womens-shoes",
842 | "thumbnail": "https://i.dummyjson.com/data/products/46/thumbnail.jpg",
843 | "images": [
844 | "https://i.dummyjson.com/data/products/46/1.webp",
845 | "https://i.dummyjson.com/data/products/46/2.jpg",
846 | "https://i.dummyjson.com/data/products/46/3.jpg",
847 | "https://i.dummyjson.com/data/products/46/4.jpg",
848 | "https://i.dummyjson.com/data/products/46/thumbnail.jpg"
849 | ]
850 | },
851 | {
852 | "id": 47,
853 | "title": "Sneaker shoes",
854 | "description": "Synthetic Leather Casual Sneaker shoes for Women/girls Sneakers For Women",
855 | "price": 120,
856 | "discountPercentage": 10.37,
857 | "rating": 4.19,
858 | "stock": 50,
859 | "brand": "Synthetic Leather",
860 | "category": "womens-shoes",
861 | "thumbnail": "https://i.dummyjson.com/data/products/47/thumbnail.jpeg",
862 | "images": [
863 | "https://i.dummyjson.com/data/products/47/1.jpg",
864 | "https://i.dummyjson.com/data/products/47/2.jpg",
865 | "https://i.dummyjson.com/data/products/47/3.jpg",
866 | "https://i.dummyjson.com/data/products/47/thumbnail.jpeg"
867 | ]
868 | },
869 | {
870 | "id": 48,
871 | "title": "Women Strip Heel",
872 | "description": "Features: Flip-flops, Mid Heel, Comfortable, Striped Heel, Antiskid, Striped",
873 | "price": 40,
874 | "discountPercentage": 10.83,
875 | "rating": 4.02,
876 | "stock": 25,
877 | "brand": "Sandals Flip Flops",
878 | "category": "womens-shoes",
879 | "thumbnail": "https://i.dummyjson.com/data/products/48/thumbnail.jpg",
880 | "images": [
881 | "https://i.dummyjson.com/data/products/48/1.jpg",
882 | "https://i.dummyjson.com/data/products/48/2.jpg",
883 | "https://i.dummyjson.com/data/products/48/3.jpg",
884 | "https://i.dummyjson.com/data/products/48/4.jpg",
885 | "https://i.dummyjson.com/data/products/48/thumbnail.jpg"
886 | ]
887 | },
888 | {
889 | "id": 49,
890 | "title": "Chappals & Shoe Ladies Metallic",
891 | "description": "Womens Chappals & Shoe Ladies Metallic Tong Thong Sandal Flat Summer 2020 Maasai Sandals",
892 | "price": 23,
893 | "discountPercentage": 2.62,
894 | "rating": 4.72,
895 | "stock": 107,
896 | "brand": "Maasai Sandals",
897 | "category": "womens-shoes",
898 | "thumbnail": "https://i.dummyjson.com/data/products/49/thumbnail.jpg",
899 | "images": [
900 | "https://i.dummyjson.com/data/products/49/1.jpg",
901 | "https://i.dummyjson.com/data/products/49/2.jpg",
902 | "https://i.dummyjson.com/data/products/49/3.webp",
903 | "https://i.dummyjson.com/data/products/49/thumbnail.jpg"
904 | ]
905 | },
906 | {
907 | "id": 50,
908 | "title": "Women Shoes",
909 | "description": "2020 New Arrivals Genuine Leather Fashion Trend Platform Summer Women Shoes",
910 | "price": 36,
911 | "discountPercentage": 16.87,
912 | "rating": 4.33,
913 | "stock": 46,
914 | "brand": "Arrivals Genuine",
915 | "category": "womens-shoes",
916 | "thumbnail": "https://i.dummyjson.com/data/products/50/thumbnail.jpg",
917 | "images": [
918 | "https://i.dummyjson.com/data/products/50/1.jpeg",
919 | "https://i.dummyjson.com/data/products/50/2.jpg",
920 | "https://i.dummyjson.com/data/products/50/3.jpg"
921 | ]
922 | },
923 | {
924 | "id": 51,
925 | "title": "half sleeves T shirts",
926 | "description": "Many store is creating new designs and trend every month and every year. Daraz.pk have a beautiful range of men fashion brands",
927 | "price": 23,
928 | "discountPercentage": 12.76,
929 | "rating": 4.26,
930 | "stock": 132,
931 | "brand": "Vintage Apparel",
932 | "category": "mens-shirts",
933 | "thumbnail": "https://i.dummyjson.com/data/products/51/thumbnail.jpg",
934 | "images": [
935 | "https://i.dummyjson.com/data/products/51/1.png",
936 | "https://i.dummyjson.com/data/products/51/2.jpg",
937 | "https://i.dummyjson.com/data/products/51/3.jpg",
938 | "https://i.dummyjson.com/data/products/51/thumbnail.jpg"
939 | ]
940 | },
941 | {
942 | "id": 52,
943 | "title": "FREE FIRE T Shirt",
944 | "description": "quality and professional print - It doesn't just look high quality, it is high quality.",
945 | "price": 10,
946 | "discountPercentage": 14.72,
947 | "rating": 4.52,
948 | "stock": 128,
949 | "brand": "FREE FIRE",
950 | "category": "mens-shirts",
951 | "thumbnail": "https://i.dummyjson.com/data/products/52/thumbnail.jpg",
952 | "images": [
953 | "https://i.dummyjson.com/data/products/52/1.png",
954 | "https://i.dummyjson.com/data/products/52/2.png",
955 | "https://i.dummyjson.com/data/products/52/3.jpg",
956 | "https://i.dummyjson.com/data/products/52/4.jpg",
957 | "https://i.dummyjson.com/data/products/52/thumbnail.jpg"
958 | ]
959 | },
960 | {
961 | "id": 53,
962 | "title": "printed high quality T shirts",
963 | "description": "Brand: vintage Apparel ,Export quality",
964 | "price": 35,
965 | "discountPercentage": 7.54,
966 | "rating": 4.89,
967 | "stock": 6,
968 | "brand": "Vintage Apparel",
969 | "category": "mens-shirts",
970 | "thumbnail": "https://i.dummyjson.com/data/products/53/thumbnail.jpg",
971 | "images": [
972 | "https://i.dummyjson.com/data/products/53/1.webp",
973 | "https://i.dummyjson.com/data/products/53/2.jpg",
974 | "https://i.dummyjson.com/data/products/53/3.jpg",
975 | "https://i.dummyjson.com/data/products/53/4.jpg",
976 | "https://i.dummyjson.com/data/products/53/thumbnail.jpg"
977 | ]
978 | },
979 | {
980 | "id": 54,
981 | "title": "Pubg Printed Graphic T-Shirt",
982 | "description": "Product Description Features: 100% Ultra soft Polyester Jersey. Vibrant & colorful printing on front. Feels soft as cotton without ever cracking",
983 | "price": 46,
984 | "discountPercentage": 16.44,
985 | "rating": 4.62,
986 | "stock": 136,
987 | "brand": "The Warehouse",
988 | "category": "mens-shirts",
989 | "thumbnail": "https://i.dummyjson.com/data/products/54/thumbnail.jpg",
990 | "images": [
991 | "https://i.dummyjson.com/data/products/54/1.jpg",
992 | "https://i.dummyjson.com/data/products/54/2.jpg",
993 | "https://i.dummyjson.com/data/products/54/3.jpg",
994 | "https://i.dummyjson.com/data/products/54/4.jpg",
995 | "https://i.dummyjson.com/data/products/54/thumbnail.jpg"
996 | ]
997 | },
998 | {
999 | "id": 55,
1000 | "title": "Money Heist Printed Summer T Shirts",
1001 | "description": "Fabric Jercy, Size: M & L Wear Stylish Dual Stiched",
1002 | "price": 66,
1003 | "discountPercentage": 15.97,
1004 | "rating": 4.9,
1005 | "stock": 122,
1006 | "brand": "The Warehouse",
1007 | "category": "mens-shirts",
1008 | "thumbnail": "https://i.dummyjson.com/data/products/55/thumbnail.jpg",
1009 | "images": [
1010 | "https://i.dummyjson.com/data/products/55/1.jpg",
1011 | "https://i.dummyjson.com/data/products/55/2.webp",
1012 | "https://i.dummyjson.com/data/products/55/3.jpg",
1013 | "https://i.dummyjson.com/data/products/55/4.jpg",
1014 | "https://i.dummyjson.com/data/products/55/thumbnail.jpg"
1015 | ]
1016 | },
1017 | {
1018 | "id": 56,
1019 | "title": "Sneakers Joggers Shoes",
1020 | "description": "Gender: Men , Colors: Same as DisplayedCondition: 100% Brand New",
1021 | "price": 40,
1022 | "discountPercentage": 12.57,
1023 | "rating": 4.38,
1024 | "stock": 6,
1025 | "brand": "Sneakers",
1026 | "category": "mens-shoes",
1027 | "thumbnail": "https://i.dummyjson.com/data/products/56/thumbnail.jpg",
1028 | "images": [
1029 | "https://i.dummyjson.com/data/products/56/1.jpg",
1030 | "https://i.dummyjson.com/data/products/56/2.jpg",
1031 | "https://i.dummyjson.com/data/products/56/3.jpg",
1032 | "https://i.dummyjson.com/data/products/56/4.jpg",
1033 | "https://i.dummyjson.com/data/products/56/5.jpg",
1034 | "https://i.dummyjson.com/data/products/56/thumbnail.jpg"
1035 | ]
1036 | },
1037 | {
1038 | "id": 57,
1039 | "title": "Loafers for men",
1040 | "description": "Men Shoes - Loafers for men - Rubber Shoes - Nylon Shoes - Shoes for men - Moccassion - Pure Nylon (Rubber) Expot Quality.",
1041 | "price": 47,
1042 | "discountPercentage": 10.91,
1043 | "rating": 4.91,
1044 | "stock": 20,
1045 | "brand": "Rubber",
1046 | "category": "mens-shoes",
1047 | "thumbnail": "https://i.dummyjson.com/data/products/57/thumbnail.jpg",
1048 | "images": [
1049 | "https://i.dummyjson.com/data/products/57/1.jpg",
1050 | "https://i.dummyjson.com/data/products/57/2.jpg",
1051 | "https://i.dummyjson.com/data/products/57/3.jpg",
1052 | "https://i.dummyjson.com/data/products/57/4.jpg",
1053 | "https://i.dummyjson.com/data/products/57/thumbnail.jpg"
1054 | ]
1055 | },
1056 | {
1057 | "id": 58,
1058 | "title": "formal offices shoes",
1059 | "description": "Pattern Type: Solid, Material: PU, Toe Shape: Pointed Toe ,Outsole Material: Rubber",
1060 | "price": 57,
1061 | "discountPercentage": 12,
1062 | "rating": 4.41,
1063 | "stock": 68,
1064 | "brand": "The Warehouse",
1065 | "category": "mens-shoes",
1066 | "thumbnail": "https://i.dummyjson.com/data/products/58/thumbnail.jpg",
1067 | "images": [
1068 | "https://i.dummyjson.com/data/products/58/1.jpg",
1069 | "https://i.dummyjson.com/data/products/58/2.jpg",
1070 | "https://i.dummyjson.com/data/products/58/3.jpg",
1071 | "https://i.dummyjson.com/data/products/58/4.jpg",
1072 | "https://i.dummyjson.com/data/products/58/thumbnail.jpg"
1073 | ]
1074 | },
1075 | {
1076 | "id": 59,
1077 | "title": "Spring and summershoes",
1078 | "description": "Comfortable stretch cloth, lightweight body; ,rubber sole, anti-skid wear;",
1079 | "price": 20,
1080 | "discountPercentage": 8.71,
1081 | "rating": 4.33,
1082 | "stock": 137,
1083 | "brand": "Sneakers",
1084 | "category": "mens-shoes",
1085 | "thumbnail": "https://i.dummyjson.com/data/products/59/thumbnail.jpg",
1086 | "images": [
1087 | "https://i.dummyjson.com/data/products/59/1.jpg",
1088 | "https://i.dummyjson.com/data/products/59/2.jpg",
1089 | "https://i.dummyjson.com/data/products/59/3.jpg",
1090 | "https://i.dummyjson.com/data/products/59/4.jpg",
1091 | "https://i.dummyjson.com/data/products/59/thumbnail.jpg"
1092 | ]
1093 | },
1094 | {
1095 | "id": 60,
1096 | "title": "Stylish Casual Jeans Shoes",
1097 | "description": "High Quality ,Stylish design ,Comfortable wear ,FAshion ,Durable",
1098 | "price": 58,
1099 | "discountPercentage": 7.55,
1100 | "rating": 4.55,
1101 | "stock": 129,
1102 | "brand": "Sneakers",
1103 | "category": "mens-shoes",
1104 | "thumbnail": "https://i.dummyjson.com/data/products/60/thumbnail.jpg",
1105 | "images": [
1106 | "https://i.dummyjson.com/data/products/60/1.jpg",
1107 | "https://i.dummyjson.com/data/products/60/2.jpg",
1108 | "https://i.dummyjson.com/data/products/60/3.jpg",
1109 | "https://i.dummyjson.com/data/products/60/thumbnail.jpg"
1110 | ]
1111 | },
1112 | {
1113 | "id": 61,
1114 | "title": "Leather Straps Wristwatch",
1115 | "description": "Style:Sport ,Clasp:Buckles ,Water Resistance Depth:3Bar",
1116 | "price": 120,
1117 | "discountPercentage": 7.14,
1118 | "rating": 4.63,
1119 | "stock": 91,
1120 | "brand": "Naviforce",
1121 | "category": "mens-watches",
1122 | "thumbnail": "https://i.dummyjson.com/data/products/61/thumbnail.jpg",
1123 | "images": [
1124 | "https://i.dummyjson.com/data/products/61/1.jpg",
1125 | "https://i.dummyjson.com/data/products/61/2.png",
1126 | "https://i.dummyjson.com/data/products/61/3.jpg"
1127 | ]
1128 | },
1129 | {
1130 | "id": 62,
1131 | "title": "Waterproof Leather Brand Watch",
1132 | "description": "Watch Crown With Environmental IPS Bronze Electroplating; Display system of 12 hours",
1133 | "price": 46,
1134 | "discountPercentage": 3.15,
1135 | "rating": 4.05,
1136 | "stock": 95,
1137 | "brand": "SKMEI 9117",
1138 | "category": "mens-watches",
1139 | "thumbnail": "https://i.dummyjson.com/data/products/62/thumbnail.jpg",
1140 | "images": [
1141 | "https://i.dummyjson.com/data/products/62/1.jpg",
1142 | "https://i.dummyjson.com/data/products/62/2.jpg"
1143 | ]
1144 | },
1145 | {
1146 | "id": 63,
1147 | "title": "Royal Blue Premium Watch",
1148 | "description": "Men Silver Chain Royal Blue Premium Watch Latest Analog Watch",
1149 | "price": 50,
1150 | "discountPercentage": 2.56,
1151 | "rating": 4.89,
1152 | "stock": 142,
1153 | "brand": "SKMEI 9117",
1154 | "category": "mens-watches",
1155 | "thumbnail": "https://i.dummyjson.com/data/products/63/thumbnail.webp",
1156 | "images": [
1157 | "https://i.dummyjson.com/data/products/63/1.jpg",
1158 | "https://i.dummyjson.com/data/products/63/2.jpg",
1159 | "https://i.dummyjson.com/data/products/63/3.png",
1160 | "https://i.dummyjson.com/data/products/63/4.jpeg"
1161 | ]
1162 | },
1163 | {
1164 | "id": 64,
1165 | "title": "Leather Strap Skeleton Watch",
1166 | "description": "Leather Strap Skeleton Watch for Men - Stylish and Latest Design",
1167 | "price": 46,
1168 | "discountPercentage": 10.2,
1169 | "rating": 4.98,
1170 | "stock": 61,
1171 | "brand": "Strap Skeleton",
1172 | "category": "mens-watches",
1173 | "thumbnail": "https://i.dummyjson.com/data/products/64/thumbnail.jpg",
1174 | "images": [
1175 | "https://i.dummyjson.com/data/products/64/1.jpg",
1176 | "https://i.dummyjson.com/data/products/64/2.webp",
1177 | "https://i.dummyjson.com/data/products/64/3.jpg",
1178 | "https://i.dummyjson.com/data/products/64/thumbnail.jpg"
1179 | ]
1180 | },
1181 | {
1182 | "id": 65,
1183 | "title": "Stainless Steel Wrist Watch",
1184 | "description": "Stylish Watch For Man (Luxury) Classy Men's Stainless Steel Wrist Watch - Box Packed",
1185 | "price": 47,
1186 | "discountPercentage": 17.79,
1187 | "rating": 4.79,
1188 | "stock": 94,
1189 | "brand": "Stainless",
1190 | "category": "mens-watches",
1191 | "thumbnail": "https://i.dummyjson.com/data/products/65/thumbnail.webp",
1192 | "images": [
1193 | "https://i.dummyjson.com/data/products/65/1.jpg",
1194 | "https://i.dummyjson.com/data/products/65/2.webp",
1195 | "https://i.dummyjson.com/data/products/65/3.jpg",
1196 | "https://i.dummyjson.com/data/products/65/4.webp",
1197 | "https://i.dummyjson.com/data/products/65/thumbnail.webp"
1198 | ]
1199 | },
1200 | {
1201 | "id": 66,
1202 | "title": "Steel Analog Couple Watches",
1203 | "description": "Elegant design, Stylish ,Unique & Trendy,Comfortable wear",
1204 | "price": 35,
1205 | "discountPercentage": 3.23,
1206 | "rating": 4.79,
1207 | "stock": 24,
1208 | "brand": "Eastern Watches",
1209 | "category": "womens-watches",
1210 | "thumbnail": "https://i.dummyjson.com/data/products/66/thumbnail.jpg",
1211 | "images": [
1212 | "https://i.dummyjson.com/data/products/66/1.jpg",
1213 | "https://i.dummyjson.com/data/products/66/2.jpg",
1214 | "https://i.dummyjson.com/data/products/66/3.jpg",
1215 | "https://i.dummyjson.com/data/products/66/4.JPG",
1216 | "https://i.dummyjson.com/data/products/66/thumbnail.jpg"
1217 | ]
1218 | },
1219 | {
1220 | "id": 67,
1221 | "title": "Fashion Magnetic Wrist Watch",
1222 | "description": "Buy this awesome The product is originally manufactured by the company and it's a top selling product with a very reasonable",
1223 | "price": 60,
1224 | "discountPercentage": 16.69,
1225 | "rating": 4.03,
1226 | "stock": 46,
1227 | "brand": "Eastern Watches",
1228 | "category": "womens-watches",
1229 | "thumbnail": "https://i.dummyjson.com/data/products/67/thumbnail.jpg",
1230 | "images": [
1231 | "https://i.dummyjson.com/data/products/67/1.jpg",
1232 | "https://i.dummyjson.com/data/products/67/2.jpg",
1233 | "https://i.dummyjson.com/data/products/67/3.jpg",
1234 | "https://i.dummyjson.com/data/products/67/4.jpg",
1235 | "https://i.dummyjson.com/data/products/67/thumbnail.jpg"
1236 | ]
1237 | },
1238 | {
1239 | "id": 68,
1240 | "title": "Stylish Luxury Digital Watch",
1241 | "description": "Stylish Luxury Digital Watch For Girls / Women - Led Smart Ladies Watches For Girls",
1242 | "price": 57,
1243 | "discountPercentage": 9.03,
1244 | "rating": 4.55,
1245 | "stock": 77,
1246 | "brand": "Luxury Digital",
1247 | "category": "womens-watches",
1248 | "thumbnail": "https://i.dummyjson.com/data/products/68/thumbnail.webp",
1249 | "images": [
1250 | "https://i.dummyjson.com/data/products/68/1.jpg",
1251 | "https://i.dummyjson.com/data/products/68/2.jpg"
1252 | ]
1253 | },
1254 | {
1255 | "id": 69,
1256 | "title": "Golden Watch Pearls Bracelet Watch",
1257 | "description": "Product details of Golden Watch Pearls Bracelet Watch For Girls - Golden Chain Ladies Bracelate Watch for Women",
1258 | "price": 47,
1259 | "discountPercentage": 17.55,
1260 | "rating": 4.77,
1261 | "stock": 89,
1262 | "brand": "Watch Pearls",
1263 | "category": "womens-watches",
1264 | "thumbnail": "https://i.dummyjson.com/data/products/69/thumbnail.jpg",
1265 | "images": [
1266 | "https://i.dummyjson.com/data/products/69/1.jpg",
1267 | "https://i.dummyjson.com/data/products/69/2.jpg",
1268 | "https://i.dummyjson.com/data/products/69/3.webp",
1269 | "https://i.dummyjson.com/data/products/69/4.jpg",
1270 | "https://i.dummyjson.com/data/products/69/thumbnail.jpg"
1271 | ]
1272 | },
1273 | {
1274 | "id": 70,
1275 | "title": "Stainless Steel Women",
1276 | "description": "Fashion Skmei 1830 Shell Dial Stainless Steel Women Wrist Watch Lady Bracelet Watch Quartz Watches Ladies",
1277 | "price": 35,
1278 | "discountPercentage": 8.98,
1279 | "rating": 4.08,
1280 | "stock": 111,
1281 | "brand": "Bracelet",
1282 | "category": "womens-watches",
1283 | "thumbnail": "https://i.dummyjson.com/data/products/70/thumbnail.jpg",
1284 | "images": [
1285 | "https://i.dummyjson.com/data/products/70/1.jpg",
1286 | "https://i.dummyjson.com/data/products/70/2.jpg",
1287 | "https://i.dummyjson.com/data/products/70/thumbnail.jpg"
1288 | ]
1289 | },
1290 | {
1291 | "id": 71,
1292 | "title": "Women Shoulder Bags",
1293 | "description": "LouisWill Women Shoulder Bags Long Clutches Cross Body Bags Phone Bags PU Leather Hand Bags Large Capacity Card Holders Zipper Coin Purses Fashion Crossbody Bags for Girls Ladies",
1294 | "price": 46,
1295 | "discountPercentage": 14.65,
1296 | "rating": 4.71,
1297 | "stock": 17,
1298 | "brand": "LouisWill",
1299 | "category": "womens-bags",
1300 | "thumbnail": "https://i.dummyjson.com/data/products/71/thumbnail.jpg",
1301 | "images": [
1302 | "https://i.dummyjson.com/data/products/71/1.jpg",
1303 | "https://i.dummyjson.com/data/products/71/2.jpg",
1304 | "https://i.dummyjson.com/data/products/71/3.webp",
1305 | "https://i.dummyjson.com/data/products/71/thumbnail.jpg"
1306 | ]
1307 | },
1308 | {
1309 | "id": 72,
1310 | "title": "Handbag For Girls",
1311 | "description": "This fashion is designed to add a charming effect to your casual outfit. This Bag is made of synthetic leather.",
1312 | "price": 23,
1313 | "discountPercentage": 17.5,
1314 | "rating": 4.91,
1315 | "stock": 27,
1316 | "brand": "LouisWill",
1317 | "category": "womens-bags",
1318 | "thumbnail": "https://i.dummyjson.com/data/products/72/thumbnail.webp",
1319 | "images": [
1320 | "https://i.dummyjson.com/data/products/72/1.jpg",
1321 | "https://i.dummyjson.com/data/products/72/2.png",
1322 | "https://i.dummyjson.com/data/products/72/3.webp",
1323 | "https://i.dummyjson.com/data/products/72/4.jpg",
1324 | "https://i.dummyjson.com/data/products/72/thumbnail.webp"
1325 | ]
1326 | },
1327 | {
1328 | "id": 73,
1329 | "title": "Fancy hand clutch",
1330 | "description": "This fashion is designed to add a charming effect to your casual outfit. This Bag is made of synthetic leather.",
1331 | "price": 44,
1332 | "discountPercentage": 10.39,
1333 | "rating": 4.18,
1334 | "stock": 101,
1335 | "brand": "Bracelet",
1336 | "category": "womens-bags",
1337 | "thumbnail": "https://i.dummyjson.com/data/products/73/thumbnail.jpg",
1338 | "images": [
1339 | "https://i.dummyjson.com/data/products/73/1.jpg",
1340 | "https://i.dummyjson.com/data/products/73/2.webp",
1341 | "https://i.dummyjson.com/data/products/73/3.jpg",
1342 | "https://i.dummyjson.com/data/products/73/thumbnail.jpg"
1343 | ]
1344 | },
1345 | {
1346 | "id": 74,
1347 | "title": "Leather Hand Bag",
1348 | "description": "It features an attractive design that makes it a must have accessory in your collection. We sell different kind of bags for boys, kids, women, girls and also for unisex.",
1349 | "price": 57,
1350 | "discountPercentage": 11.19,
1351 | "rating": 4.01,
1352 | "stock": 43,
1353 | "brand": "Copenhagen Luxe",
1354 | "category": "womens-bags",
1355 | "thumbnail": "https://i.dummyjson.com/data/products/74/thumbnail.jpg",
1356 | "images": [
1357 | "https://i.dummyjson.com/data/products/74/1.jpg",
1358 | "https://i.dummyjson.com/data/products/74/2.jpg",
1359 | "https://i.dummyjson.com/data/products/74/3.jpg",
1360 | "https://i.dummyjson.com/data/products/74/4.jpg",
1361 | "https://i.dummyjson.com/data/products/74/thumbnail.jpg"
1362 | ]
1363 | },
1364 | {
1365 | "id": 75,
1366 | "title": "Seven Pocket Women Bag",
1367 | "description": "Seven Pocket Women Bag Handbags Lady Shoulder Crossbody Bag Female Purse Seven Pocket Bag",
1368 | "price": 68,
1369 | "discountPercentage": 14.87,
1370 | "rating": 4.93,
1371 | "stock": 13,
1372 | "brand": "Steal Frame",
1373 | "category": "womens-bags",
1374 | "thumbnail": "https://i.dummyjson.com/data/products/75/thumbnail.jpg",
1375 | "images": [
1376 | "https://i.dummyjson.com/data/products/75/1.jpg",
1377 | "https://i.dummyjson.com/data/products/75/2.jpg",
1378 | "https://i.dummyjson.com/data/products/75/3.jpg",
1379 | "https://i.dummyjson.com/data/products/75/thumbnail.jpg"
1380 | ]
1381 | },
1382 | {
1383 | "id": 76,
1384 | "title": "Silver Ring Set Women",
1385 | "description": "Jewelry Type:RingsCertificate Type:NonePlating:Silver PlatedShapeattern:noneStyle:CLASSICReligious",
1386 | "price": 70,
1387 | "discountPercentage": 13.57,
1388 | "rating": 4.61,
1389 | "stock": 51,
1390 | "brand": "Darojay",
1391 | "category": "womens-jewellery",
1392 | "thumbnail": "https://i.dummyjson.com/data/products/76/thumbnail.jpg",
1393 | "images": [
1394 | "https://i.dummyjson.com/data/products/76/1.jpg",
1395 | "https://i.dummyjson.com/data/products/76/2.jpg",
1396 | "https://i.dummyjson.com/data/products/76/thumbnail.jpg"
1397 | ]
1398 | },
1399 | {
1400 | "id": 77,
1401 | "title": "Rose Ring",
1402 | "description": "Brand: The Greetings Flower Colour: RedRing Colour: GoldenSize: Adjustable",
1403 | "price": 100,
1404 | "discountPercentage": 3.22,
1405 | "rating": 4.21,
1406 | "stock": 149,
1407 | "brand": "Copenhagen Luxe",
1408 | "category": "womens-jewellery",
1409 | "thumbnail": "https://i.dummyjson.com/data/products/77/thumbnail.jpg",
1410 | "images": [
1411 | "https://i.dummyjson.com/data/products/77/1.jpg",
1412 | "https://i.dummyjson.com/data/products/77/2.jpg",
1413 | "https://i.dummyjson.com/data/products/77/3.jpg",
1414 | "https://i.dummyjson.com/data/products/77/thumbnail.jpg"
1415 | ]
1416 | },
1417 | {
1418 | "id": 78,
1419 | "title": "Rhinestone Korean Style Open Rings",
1420 | "description": "Fashion Jewellery 3Pcs Adjustable Pearl Rhinestone Korean Style Open Rings For Women",
1421 | "price": 30,
1422 | "discountPercentage": 8.02,
1423 | "rating": 4.69,
1424 | "stock": 9,
1425 | "brand": "Fashion Jewellery",
1426 | "category": "womens-jewellery",
1427 | "thumbnail": "https://i.dummyjson.com/data/products/78/thumbnail.jpg",
1428 | "images": ["https://i.dummyjson.com/data/products/78/thumbnail.jpg"]
1429 | },
1430 | {
1431 | "id": 79,
1432 | "title": "Elegant Female Pearl Earrings",
1433 | "description": "Elegant Female Pearl Earrings Set Zircon Pearl Earings Women Party Accessories 9 Pairs/Set",
1434 | "price": 30,
1435 | "discountPercentage": 12.8,
1436 | "rating": 4.74,
1437 | "stock": 16,
1438 | "brand": "Fashion Jewellery",
1439 | "category": "womens-jewellery",
1440 | "thumbnail": "https://i.dummyjson.com/data/products/79/thumbnail.jpg",
1441 | "images": ["https://i.dummyjson.com/data/products/79/1.jpg"]
1442 | },
1443 | {
1444 | "id": 80,
1445 | "title": "Chain Pin Tassel Earrings",
1446 | "description": "Pair Of Ear Cuff Butterfly Long Chain Pin Tassel Earrings - Silver ( Long Life Quality Product)",
1447 | "price": 45,
1448 | "discountPercentage": 17.75,
1449 | "rating": 4.59,
1450 | "stock": 9,
1451 | "brand": "Cuff Butterfly",
1452 | "category": "womens-jewellery",
1453 | "thumbnail": "https://i.dummyjson.com/data/products/80/thumbnail.jpg",
1454 | "images": [
1455 | "https://i.dummyjson.com/data/products/80/1.jpg",
1456 | "https://i.dummyjson.com/data/products/80/2.jpg",
1457 | "https://i.dummyjson.com/data/products/80/3.png",
1458 | "https://i.dummyjson.com/data/products/80/4.jpg",
1459 | "https://i.dummyjson.com/data/products/80/thumbnail.jpg"
1460 | ]
1461 | },
1462 | {
1463 | "id": 81,
1464 | "title": "Round Silver Frame Sun Glasses",
1465 | "description": "A pair of sunglasses can protect your eyes from being hurt. For car driving, vacation travel, outdoor activities, social gatherings,",
1466 | "price": 19,
1467 | "discountPercentage": 10.1,
1468 | "rating": 4.94,
1469 | "stock": 78,
1470 | "brand": "Designer Sun Glasses",
1471 | "category": "sunglasses",
1472 | "thumbnail": "https://i.dummyjson.com/data/products/81/thumbnail.jpg",
1473 | "images": [
1474 | "https://i.dummyjson.com/data/products/81/1.jpg",
1475 | "https://i.dummyjson.com/data/products/81/2.jpg",
1476 | "https://i.dummyjson.com/data/products/81/3.jpg",
1477 | "https://i.dummyjson.com/data/products/81/4.webp",
1478 | "https://i.dummyjson.com/data/products/81/thumbnail.jpg"
1479 | ]
1480 | },
1481 | {
1482 | "id": 82,
1483 | "title": "Kabir Singh Square Sunglass",
1484 | "description": "Orignal Metal Kabir Singh design 2020 Sunglasses Men Brand Designer Sun Glasses Kabir Singh Square Sunglass",
1485 | "price": 50,
1486 | "discountPercentage": 15.6,
1487 | "rating": 4.62,
1488 | "stock": 78,
1489 | "brand": "Designer Sun Glasses",
1490 | "category": "sunglasses",
1491 | "thumbnail": "https://i.dummyjson.com/data/products/82/thumbnail.jpg",
1492 | "images": [
1493 | "https://i.dummyjson.com/data/products/82/1.jpg",
1494 | "https://i.dummyjson.com/data/products/82/2.webp",
1495 | "https://i.dummyjson.com/data/products/82/3.jpg",
1496 | "https://i.dummyjson.com/data/products/82/4.jpg",
1497 | "https://i.dummyjson.com/data/products/82/thumbnail.jpg"
1498 | ]
1499 | },
1500 | {
1501 | "id": 83,
1502 | "title": "Wiley X Night Vision Yellow Glasses",
1503 | "description": "Wiley X Night Vision Yellow Glasses for Riders - Night Vision Anti Fog Driving Glasses - Free Night Glass Cover - Shield Eyes From Dust and Virus- For Night Sport Matches",
1504 | "price": 30,
1505 | "discountPercentage": 6.33,
1506 | "rating": 4.97,
1507 | "stock": 115,
1508 | "brand": "mastar watch",
1509 | "category": "sunglasses",
1510 | "thumbnail": "https://i.dummyjson.com/data/products/83/thumbnail.jpg",
1511 | "images": [
1512 | "https://i.dummyjson.com/data/products/83/1.jpg",
1513 | "https://i.dummyjson.com/data/products/83/2.jpg",
1514 | "https://i.dummyjson.com/data/products/83/3.jpg",
1515 | "https://i.dummyjson.com/data/products/83/4.jpg",
1516 | "https://i.dummyjson.com/data/products/83/thumbnail.jpg"
1517 | ]
1518 | },
1519 | {
1520 | "id": 84,
1521 | "title": "Square Sunglasses",
1522 | "description": "Fashion Oversized Square Sunglasses Retro Gradient Big Frame Sunglasses For Women One Piece Gafas Shade Mirror Clear Lens 17059",
1523 | "price": 28,
1524 | "discountPercentage": 13.89,
1525 | "rating": 4.64,
1526 | "stock": 64,
1527 | "brand": "mastar watch",
1528 | "category": "sunglasses",
1529 | "thumbnail": "https://i.dummyjson.com/data/products/84/thumbnail.jpg",
1530 | "images": [
1531 | "https://i.dummyjson.com/data/products/84/1.jpg",
1532 | "https://i.dummyjson.com/data/products/84/2.jpg",
1533 | "https://i.dummyjson.com/data/products/84/thumbnail.jpg"
1534 | ]
1535 | },
1536 | {
1537 | "id": 85,
1538 | "title": "LouisWill Men Sunglasses",
1539 | "description": "LouisWill Men Sunglasses Polarized Sunglasses UV400 Sunglasses Day Night Dual Use Safety Driving Night Vision Eyewear AL-MG Frame Sun Glasses with Free Box for Drivers",
1540 | "price": 50,
1541 | "discountPercentage": 11.27,
1542 | "rating": 4.98,
1543 | "stock": 92,
1544 | "brand": "LouisWill",
1545 | "category": "sunglasses",
1546 | "thumbnail": "https://i.dummyjson.com/data/products/85/thumbnail.jpg",
1547 | "images": [
1548 | "https://i.dummyjson.com/data/products/85/1.jpg",
1549 | "https://i.dummyjson.com/data/products/85/2.jpg",
1550 | "https://i.dummyjson.com/data/products/85/thumbnail.jpg"
1551 | ]
1552 | },
1553 | {
1554 | "id": 86,
1555 | "title": "Bluetooth Aux",
1556 | "description": "Bluetooth Aux Bluetooth Car Aux Car Bluetooth Transmitter Aux Audio Receiver Handfree Car Bluetooth Music Receiver Universal 3.5mm Streaming A2DP Wireless Auto AUX Audio Adapter With Mic For Phone MP3",
1557 | "price": 25,
1558 | "discountPercentage": 10.56,
1559 | "rating": 4.57,
1560 | "stock": 22,
1561 | "brand": "Car Aux",
1562 | "category": "automotive",
1563 | "thumbnail": "https://i.dummyjson.com/data/products/86/thumbnail.jpg",
1564 | "images": [
1565 | "https://i.dummyjson.com/data/products/86/1.jpg",
1566 | "https://i.dummyjson.com/data/products/86/2.webp",
1567 | "https://i.dummyjson.com/data/products/86/3.jpg",
1568 | "https://i.dummyjson.com/data/products/86/4.jpg",
1569 | "https://i.dummyjson.com/data/products/86/thumbnail.jpg"
1570 | ]
1571 | },
1572 | {
1573 | "id": 87,
1574 | "title": "t Temperature Controller Incubator Controller",
1575 | "description": "Both Heat and Cool Purpose, Temperature control range; -50 to +110, Temperature measurement accuracy; 0.1, Control accuracy; 0.1",
1576 | "price": 40,
1577 | "discountPercentage": 11.3,
1578 | "rating": 4.54,
1579 | "stock": 37,
1580 | "brand": "W1209 DC12V",
1581 | "category": "automotive",
1582 | "thumbnail": "https://i.dummyjson.com/data/products/87/thumbnail.jpg",
1583 | "images": [
1584 | "https://i.dummyjson.com/data/products/87/1.jpg",
1585 | "https://i.dummyjson.com/data/products/87/2.jpg",
1586 | "https://i.dummyjson.com/data/products/87/3.jpg",
1587 | "https://i.dummyjson.com/data/products/87/4.jpg",
1588 | "https://i.dummyjson.com/data/products/87/thumbnail.jpg"
1589 | ]
1590 | },
1591 | {
1592 | "id": 88,
1593 | "title": "TC Reusable Silicone Magic Washing Gloves",
1594 | "description": "TC Reusable Silicone Magic Washing Gloves with Scrubber, Cleaning Brush Scrubber Gloves Heat Resistant Pair for Cleaning of Kitchen, Dishes, Vegetables and Fruits, Bathroom, Car Wash, Pet Care and Multipurpose",
1595 | "price": 29,
1596 | "discountPercentage": 3.19,
1597 | "rating": 4.98,
1598 | "stock": 42,
1599 | "brand": "TC Reusable",
1600 | "category": "automotive",
1601 | "thumbnail": "https://i.dummyjson.com/data/products/88/thumbnail.jpg",
1602 | "images": [
1603 | "https://i.dummyjson.com/data/products/88/1.jpg",
1604 | "https://i.dummyjson.com/data/products/88/2.jpg",
1605 | "https://i.dummyjson.com/data/products/88/3.jpg",
1606 | "https://i.dummyjson.com/data/products/88/4.webp",
1607 | "https://i.dummyjson.com/data/products/88/thumbnail.jpg"
1608 | ]
1609 | },
1610 | {
1611 | "id": 89,
1612 | "title": "Qualcomm original Car Charger",
1613 | "description": "best Quality CHarger , Highly Recommended to all best Quality CHarger , Highly Recommended to all",
1614 | "price": 40,
1615 | "discountPercentage": 17.53,
1616 | "rating": 4.2,
1617 | "stock": 79,
1618 | "brand": "TC Reusable",
1619 | "category": "automotive",
1620 | "thumbnail": "https://i.dummyjson.com/data/products/89/thumbnail.jpg",
1621 | "images": [
1622 | "https://i.dummyjson.com/data/products/89/1.jpg",
1623 | "https://i.dummyjson.com/data/products/89/2.jpg",
1624 | "https://i.dummyjson.com/data/products/89/3.jpg",
1625 | "https://i.dummyjson.com/data/products/89/4.jpg",
1626 | "https://i.dummyjson.com/data/products/89/thumbnail.jpg"
1627 | ]
1628 | },
1629 | {
1630 | "id": 90,
1631 | "title": "Cycle Bike Glow",
1632 | "description": "Universal fitment and easy to install no special wires, can be easily installed and removed. Fits most standard tyre air stem valves of road, mountain bicycles, motocycles and cars.Bright led will turn on w",
1633 | "price": 35,
1634 | "discountPercentage": 11.08,
1635 | "rating": 4.1,
1636 | "stock": 63,
1637 | "brand": "Neon LED Light",
1638 | "category": "automotive",
1639 | "thumbnail": "https://i.dummyjson.com/data/products/90/thumbnail.jpg",
1640 | "images": [
1641 | "https://i.dummyjson.com/data/products/90/1.jpg",
1642 | "https://i.dummyjson.com/data/products/90/2.jpg",
1643 | "https://i.dummyjson.com/data/products/90/3.jpg",
1644 | "https://i.dummyjson.com/data/products/90/4.jpg",
1645 | "https://i.dummyjson.com/data/products/90/thumbnail.jpg"
1646 | ]
1647 | },
1648 | {
1649 | "id": 91,
1650 | "title": "Black Motorbike",
1651 | "description": "Engine Type:Wet sump, Single Cylinder, Four Stroke, Two Valves, Air Cooled with SOHC (Single Over Head Cam) Chain Drive Bore & Stroke:47.0 x 49.5 MM",
1652 | "price": 569,
1653 | "discountPercentage": 13.63,
1654 | "rating": 4.04,
1655 | "stock": 115,
1656 | "brand": "METRO 70cc Motorcycle - MR70",
1657 | "category": "motorcycle",
1658 | "thumbnail": "https://i.dummyjson.com/data/products/91/thumbnail.jpg",
1659 | "images": [
1660 | "https://i.dummyjson.com/data/products/91/1.jpg",
1661 | "https://i.dummyjson.com/data/products/91/2.jpg",
1662 | "https://i.dummyjson.com/data/products/91/3.jpg",
1663 | "https://i.dummyjson.com/data/products/91/4.jpg",
1664 | "https://i.dummyjson.com/data/products/91/thumbnail.jpg"
1665 | ]
1666 | },
1667 | {
1668 | "id": 92,
1669 | "title": "HOT SALE IN EUROPE electric racing motorcycle",
1670 | "description": "HOT SALE IN EUROPE electric racing motorcycle electric motorcycle for sale adult electric motorcycles",
1671 | "price": 920,
1672 | "discountPercentage": 14.4,
1673 | "rating": 4.19,
1674 | "stock": 22,
1675 | "brand": "BRAVE BULL",
1676 | "category": "motorcycle",
1677 | "thumbnail": "https://i.dummyjson.com/data/products/92/thumbnail.jpg",
1678 | "images": [
1679 | "https://i.dummyjson.com/data/products/92/1.jpg",
1680 | "https://i.dummyjson.com/data/products/92/2.jpg",
1681 | "https://i.dummyjson.com/data/products/92/3.jpg",
1682 | "https://i.dummyjson.com/data/products/92/4.jpg"
1683 | ]
1684 | },
1685 | {
1686 | "id": 93,
1687 | "title": "Automatic Motor Gas Motorcycles",
1688 | "description": "150cc 4-Stroke Motorcycle Automatic Motor Gas Motorcycles Scooter motorcycles 150cc scooter",
1689 | "price": 1050,
1690 | "discountPercentage": 3.34,
1691 | "rating": 4.84,
1692 | "stock": 127,
1693 | "brand": "shock absorber",
1694 | "category": "motorcycle",
1695 | "thumbnail": "https://i.dummyjson.com/data/products/93/thumbnail.jpg",
1696 | "images": [
1697 | "https://i.dummyjson.com/data/products/93/1.jpg",
1698 | "https://i.dummyjson.com/data/products/93/2.jpg",
1699 | "https://i.dummyjson.com/data/products/93/3.jpg",
1700 | "https://i.dummyjson.com/data/products/93/4.jpg",
1701 | "https://i.dummyjson.com/data/products/93/thumbnail.jpg"
1702 | ]
1703 | },
1704 | {
1705 | "id": 94,
1706 | "title": "new arrivals Fashion motocross goggles",
1707 | "description": "new arrivals Fashion motocross goggles motorcycle motocross racing motorcycle",
1708 | "price": 900,
1709 | "discountPercentage": 3.85,
1710 | "rating": 4.06,
1711 | "stock": 109,
1712 | "brand": "JIEPOLLY",
1713 | "category": "motorcycle",
1714 | "thumbnail": "https://i.dummyjson.com/data/products/94/thumbnail.webp",
1715 | "images": [
1716 | "https://i.dummyjson.com/data/products/94/1.webp",
1717 | "https://i.dummyjson.com/data/products/94/2.jpg",
1718 | "https://i.dummyjson.com/data/products/94/3.jpg",
1719 | "https://i.dummyjson.com/data/products/94/thumbnail.webp"
1720 | ]
1721 | },
1722 | {
1723 | "id": 95,
1724 | "title": "Wholesale cargo lashing Belt",
1725 | "description": "Wholesale cargo lashing Belt Tie Down end Ratchet strap customized strap 25mm motorcycle 1500kgs with rubber handle",
1726 | "price": 930,
1727 | "discountPercentage": 17.67,
1728 | "rating": 4.21,
1729 | "stock": 144,
1730 | "brand": "Xiangle",
1731 | "category": "motorcycle",
1732 | "thumbnail": "https://i.dummyjson.com/data/products/95/thumbnail.jpg",
1733 | "images": [
1734 | "https://i.dummyjson.com/data/products/95/1.jpg",
1735 | "https://i.dummyjson.com/data/products/95/2.jpg",
1736 | "https://i.dummyjson.com/data/products/95/3.jpg",
1737 | "https://i.dummyjson.com/data/products/95/4.jpg",
1738 | "https://i.dummyjson.com/data/products/95/thumbnail.jpg"
1739 | ]
1740 | },
1741 | {
1742 | "id": 96,
1743 | "title": "lighting ceiling kitchen",
1744 | "description": "Wholesale slim hanging decorative kid room lighting ceiling kitchen chandeliers pendant light modern",
1745 | "price": 30,
1746 | "discountPercentage": 14.89,
1747 | "rating": 4.83,
1748 | "stock": 96,
1749 | "brand": "lightingbrilliance",
1750 | "category": "lighting",
1751 | "thumbnail": "https://i.dummyjson.com/data/products/96/thumbnail.jpg",
1752 | "images": [
1753 | "https://i.dummyjson.com/data/products/96/1.jpg",
1754 | "https://i.dummyjson.com/data/products/96/2.jpg",
1755 | "https://i.dummyjson.com/data/products/96/3.jpg",
1756 | "https://i.dummyjson.com/data/products/96/4.jpg",
1757 | "https://i.dummyjson.com/data/products/96/thumbnail.jpg"
1758 | ]
1759 | },
1760 | {
1761 | "id": 97,
1762 | "title": "Metal Ceramic Flower",
1763 | "description": "Metal Ceramic Flower Chandelier Home Lighting American Vintage Hanging Lighting Pendant Lamp",
1764 | "price": 35,
1765 | "discountPercentage": 10.94,
1766 | "rating": 4.93,
1767 | "stock": 146,
1768 | "brand": "Ifei Home",
1769 | "category": "lighting",
1770 | "thumbnail": "https://i.dummyjson.com/data/products/97/thumbnail.jpg",
1771 | "images": [
1772 | "https://i.dummyjson.com/data/products/97/1.jpg",
1773 | "https://i.dummyjson.com/data/products/97/2.jpg",
1774 | "https://i.dummyjson.com/data/products/97/3.jpg",
1775 | "https://i.dummyjson.com/data/products/97/4.webp",
1776 | "https://i.dummyjson.com/data/products/97/thumbnail.jpg"
1777 | ]
1778 | },
1779 | {
1780 | "id": 98,
1781 | "title": "3 lights lndenpant kitchen islang",
1782 | "description": "3 lights lndenpant kitchen islang dining room pendant rice paper chandelier contemporary led pendant light modern chandelier",
1783 | "price": 34,
1784 | "discountPercentage": 5.92,
1785 | "rating": 4.99,
1786 | "stock": 44,
1787 | "brand": "DADAWU",
1788 | "category": "lighting",
1789 | "thumbnail": "https://i.dummyjson.com/data/products/98/thumbnail.jpg",
1790 | "images": [
1791 | "https://i.dummyjson.com/data/products/98/1.jpg",
1792 | "https://i.dummyjson.com/data/products/98/2.jpg",
1793 | "https://i.dummyjson.com/data/products/98/3.jpg",
1794 | "https://i.dummyjson.com/data/products/98/4.jpg",
1795 | "https://i.dummyjson.com/data/products/98/thumbnail.jpg"
1796 | ]
1797 | },
1798 | {
1799 | "id": 99,
1800 | "title": "American Vintage Wood Pendant Light",
1801 | "description": "American Vintage Wood Pendant Light Farmhouse Antique Hanging Lamp Lampara Colgante",
1802 | "price": 46,
1803 | "discountPercentage": 8.84,
1804 | "rating": 4.32,
1805 | "stock": 138,
1806 | "brand": "Ifei Home",
1807 | "category": "lighting",
1808 | "thumbnail": "https://i.dummyjson.com/data/products/99/thumbnail.jpg",
1809 | "images": [
1810 | "https://i.dummyjson.com/data/products/99/1.jpg",
1811 | "https://i.dummyjson.com/data/products/99/2.jpg",
1812 | "https://i.dummyjson.com/data/products/99/3.jpg",
1813 | "https://i.dummyjson.com/data/products/99/4.jpg",
1814 | "https://i.dummyjson.com/data/products/99/thumbnail.jpg"
1815 | ]
1816 | },
1817 | {
1818 | "id": 100,
1819 | "title": "Crystal chandelier maria theresa for 12 light",
1820 | "description": "Crystal chandelier maria theresa for 12 light",
1821 | "price": 47,
1822 | "discountPercentage": 16,
1823 | "rating": 4.74,
1824 | "stock": 133,
1825 | "brand": "YIOSI",
1826 | "category": "lighting",
1827 | "thumbnail": "https://i.dummyjson.com/data/products/100/thumbnail.jpg",
1828 | "images": [
1829 | "https://i.dummyjson.com/data/products/100/1.jpg",
1830 | "https://i.dummyjson.com/data/products/100/2.jpg",
1831 | "https://i.dummyjson.com/data/products/100/3.jpg",
1832 | "https://i.dummyjson.com/data/products/100/thumbnail.jpg"
1833 | ]
1834 | }
1835 | ]
1836 |
--------------------------------------------------------------------------------
/backend/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "backend",
3 | "version": "1.0.0",
4 | "lockfileVersion": 3,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "backend",
9 | "version": "1.0.0",
10 | "license": "ISC",
11 | "dependencies": {
12 | "bcrypt": "^5.1.1",
13 | "cookie-parser": "^1.4.6",
14 | "cors": "^2.8.5",
15 | "dotenv": "^16.3.1",
16 | "express": "^4.18.2",
17 | "jsonwebtoken": "^9.0.2",
18 | "mongoose": "^7.6.2"
19 | },
20 | "devDependencies": {
21 | "nodemon": "^3.0.1"
22 | }
23 | },
24 | "node_modules/@mapbox/node-pre-gyp": {
25 | "version": "1.0.11",
26 | "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz",
27 | "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==",
28 | "dependencies": {
29 | "detect-libc": "^2.0.0",
30 | "https-proxy-agent": "^5.0.0",
31 | "make-dir": "^3.1.0",
32 | "node-fetch": "^2.6.7",
33 | "nopt": "^5.0.0",
34 | "npmlog": "^5.0.1",
35 | "rimraf": "^3.0.2",
36 | "semver": "^7.3.5",
37 | "tar": "^6.1.11"
38 | },
39 | "bin": {
40 | "node-pre-gyp": "bin/node-pre-gyp"
41 | }
42 | },
43 | "node_modules/@mapbox/node-pre-gyp/node_modules/nopt": {
44 | "version": "5.0.0",
45 | "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
46 | "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
47 | "dependencies": {
48 | "abbrev": "1"
49 | },
50 | "bin": {
51 | "nopt": "bin/nopt.js"
52 | },
53 | "engines": {
54 | "node": ">=6"
55 | }
56 | },
57 | "node_modules/@mongodb-js/saslprep": {
58 | "version": "1.1.0",
59 | "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.0.tgz",
60 | "integrity": "sha512-Xfijy7HvfzzqiOAhAepF4SGN5e9leLkMvg/OPOF97XemjfVCYN/oWa75wnkc6mltMSTwY+XlbhWgUOJmkFspSw==",
61 | "optional": true,
62 | "dependencies": {
63 | "sparse-bitfield": "^3.0.3"
64 | }
65 | },
66 | "node_modules/@types/node": {
67 | "version": "20.8.6",
68 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.6.tgz",
69 | "integrity": "sha512-eWO4K2Ji70QzKUqRy6oyJWUeB7+g2cRagT3T/nxYibYcT4y2BDL8lqolRXjTHmkZCdJfIPaY73KbJAZmcryxTQ==",
70 | "dependencies": {
71 | "undici-types": "~5.25.1"
72 | }
73 | },
74 | "node_modules/@types/webidl-conversions": {
75 | "version": "7.0.1",
76 | "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.1.tgz",
77 | "integrity": "sha512-8hKOnOan+Uu+NgMaCouhg3cT9x5fFZ92Jwf+uDLXLu/MFRbXxlWwGeQY7KVHkeSft6RvY+tdxklUBuyY9eIEKg=="
78 | },
79 | "node_modules/@types/whatwg-url": {
80 | "version": "8.2.2",
81 | "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.2.tgz",
82 | "integrity": "sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA==",
83 | "dependencies": {
84 | "@types/node": "*",
85 | "@types/webidl-conversions": "*"
86 | }
87 | },
88 | "node_modules/abbrev": {
89 | "version": "1.1.1",
90 | "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
91 | "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
92 | },
93 | "node_modules/accepts": {
94 | "version": "1.3.8",
95 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
96 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
97 | "dependencies": {
98 | "mime-types": "~2.1.34",
99 | "negotiator": "0.6.3"
100 | },
101 | "engines": {
102 | "node": ">= 0.6"
103 | }
104 | },
105 | "node_modules/agent-base": {
106 | "version": "6.0.2",
107 | "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
108 | "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
109 | "dependencies": {
110 | "debug": "4"
111 | },
112 | "engines": {
113 | "node": ">= 6.0.0"
114 | }
115 | },
116 | "node_modules/agent-base/node_modules/debug": {
117 | "version": "4.3.4",
118 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
119 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
120 | "dependencies": {
121 | "ms": "2.1.2"
122 | },
123 | "engines": {
124 | "node": ">=6.0"
125 | },
126 | "peerDependenciesMeta": {
127 | "supports-color": {
128 | "optional": true
129 | }
130 | }
131 | },
132 | "node_modules/agent-base/node_modules/ms": {
133 | "version": "2.1.2",
134 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
135 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
136 | },
137 | "node_modules/ansi-regex": {
138 | "version": "5.0.1",
139 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
140 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
141 | "engines": {
142 | "node": ">=8"
143 | }
144 | },
145 | "node_modules/anymatch": {
146 | "version": "3.1.3",
147 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
148 | "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
149 | "dev": true,
150 | "dependencies": {
151 | "normalize-path": "^3.0.0",
152 | "picomatch": "^2.0.4"
153 | },
154 | "engines": {
155 | "node": ">= 8"
156 | }
157 | },
158 | "node_modules/aproba": {
159 | "version": "2.0.0",
160 | "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz",
161 | "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ=="
162 | },
163 | "node_modules/are-we-there-yet": {
164 | "version": "2.0.0",
165 | "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz",
166 | "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==",
167 | "dependencies": {
168 | "delegates": "^1.0.0",
169 | "readable-stream": "^3.6.0"
170 | },
171 | "engines": {
172 | "node": ">=10"
173 | }
174 | },
175 | "node_modules/array-flatten": {
176 | "version": "1.1.1",
177 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
178 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
179 | },
180 | "node_modules/balanced-match": {
181 | "version": "1.0.2",
182 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
183 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
184 | },
185 | "node_modules/bcrypt": {
186 | "version": "5.1.1",
187 | "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.1.tgz",
188 | "integrity": "sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww==",
189 | "hasInstallScript": true,
190 | "dependencies": {
191 | "@mapbox/node-pre-gyp": "^1.0.11",
192 | "node-addon-api": "^5.0.0"
193 | },
194 | "engines": {
195 | "node": ">= 10.0.0"
196 | }
197 | },
198 | "node_modules/binary-extensions": {
199 | "version": "2.2.0",
200 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
201 | "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
202 | "dev": true,
203 | "engines": {
204 | "node": ">=8"
205 | }
206 | },
207 | "node_modules/body-parser": {
208 | "version": "1.20.1",
209 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
210 | "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
211 | "dependencies": {
212 | "bytes": "3.1.2",
213 | "content-type": "~1.0.4",
214 | "debug": "2.6.9",
215 | "depd": "2.0.0",
216 | "destroy": "1.2.0",
217 | "http-errors": "2.0.0",
218 | "iconv-lite": "0.4.24",
219 | "on-finished": "2.4.1",
220 | "qs": "6.11.0",
221 | "raw-body": "2.5.1",
222 | "type-is": "~1.6.18",
223 | "unpipe": "1.0.0"
224 | },
225 | "engines": {
226 | "node": ">= 0.8",
227 | "npm": "1.2.8000 || >= 1.4.16"
228 | }
229 | },
230 | "node_modules/body-parser/node_modules/debug": {
231 | "version": "2.6.9",
232 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
233 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
234 | "dependencies": {
235 | "ms": "2.0.0"
236 | }
237 | },
238 | "node_modules/body-parser/node_modules/ms": {
239 | "version": "2.0.0",
240 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
241 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
242 | },
243 | "node_modules/brace-expansion": {
244 | "version": "1.1.11",
245 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
246 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
247 | "dependencies": {
248 | "balanced-match": "^1.0.0",
249 | "concat-map": "0.0.1"
250 | }
251 | },
252 | "node_modules/braces": {
253 | "version": "3.0.2",
254 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
255 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
256 | "dev": true,
257 | "dependencies": {
258 | "fill-range": "^7.0.1"
259 | },
260 | "engines": {
261 | "node": ">=8"
262 | }
263 | },
264 | "node_modules/bson": {
265 | "version": "5.5.0",
266 | "resolved": "https://registry.npmjs.org/bson/-/bson-5.5.0.tgz",
267 | "integrity": "sha512-B+QB4YmDx9RStKv8LLSl/aVIEV3nYJc3cJNNTK2Cd1TL+7P+cNpw9mAPeCgc5K+j01Dv6sxUzcITXDx7ZU3F0w==",
268 | "engines": {
269 | "node": ">=14.20.1"
270 | }
271 | },
272 | "node_modules/buffer-equal-constant-time": {
273 | "version": "1.0.1",
274 | "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
275 | "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
276 | },
277 | "node_modules/bytes": {
278 | "version": "3.1.2",
279 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
280 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
281 | "engines": {
282 | "node": ">= 0.8"
283 | }
284 | },
285 | "node_modules/call-bind": {
286 | "version": "1.0.2",
287 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
288 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
289 | "dependencies": {
290 | "function-bind": "^1.1.1",
291 | "get-intrinsic": "^1.0.2"
292 | },
293 | "funding": {
294 | "url": "https://github.com/sponsors/ljharb"
295 | }
296 | },
297 | "node_modules/chokidar": {
298 | "version": "3.5.3",
299 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
300 | "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
301 | "dev": true,
302 | "funding": [
303 | {
304 | "type": "individual",
305 | "url": "https://paulmillr.com/funding/"
306 | }
307 | ],
308 | "dependencies": {
309 | "anymatch": "~3.1.2",
310 | "braces": "~3.0.2",
311 | "glob-parent": "~5.1.2",
312 | "is-binary-path": "~2.1.0",
313 | "is-glob": "~4.0.1",
314 | "normalize-path": "~3.0.0",
315 | "readdirp": "~3.6.0"
316 | },
317 | "engines": {
318 | "node": ">= 8.10.0"
319 | },
320 | "optionalDependencies": {
321 | "fsevents": "~2.3.2"
322 | }
323 | },
324 | "node_modules/chownr": {
325 | "version": "2.0.0",
326 | "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
327 | "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
328 | "engines": {
329 | "node": ">=10"
330 | }
331 | },
332 | "node_modules/color-support": {
333 | "version": "1.1.3",
334 | "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
335 | "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
336 | "bin": {
337 | "color-support": "bin.js"
338 | }
339 | },
340 | "node_modules/concat-map": {
341 | "version": "0.0.1",
342 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
343 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
344 | },
345 | "node_modules/console-control-strings": {
346 | "version": "1.1.0",
347 | "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
348 | "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ=="
349 | },
350 | "node_modules/content-disposition": {
351 | "version": "0.5.4",
352 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
353 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
354 | "dependencies": {
355 | "safe-buffer": "5.2.1"
356 | },
357 | "engines": {
358 | "node": ">= 0.6"
359 | }
360 | },
361 | "node_modules/content-type": {
362 | "version": "1.0.5",
363 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
364 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
365 | "engines": {
366 | "node": ">= 0.6"
367 | }
368 | },
369 | "node_modules/cookie": {
370 | "version": "0.5.0",
371 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
372 | "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
373 | "engines": {
374 | "node": ">= 0.6"
375 | }
376 | },
377 | "node_modules/cookie-parser": {
378 | "version": "1.4.6",
379 | "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz",
380 | "integrity": "sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==",
381 | "dependencies": {
382 | "cookie": "0.4.1",
383 | "cookie-signature": "1.0.6"
384 | },
385 | "engines": {
386 | "node": ">= 0.8.0"
387 | }
388 | },
389 | "node_modules/cookie-parser/node_modules/cookie": {
390 | "version": "0.4.1",
391 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
392 | "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==",
393 | "engines": {
394 | "node": ">= 0.6"
395 | }
396 | },
397 | "node_modules/cookie-signature": {
398 | "version": "1.0.6",
399 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
400 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
401 | },
402 | "node_modules/cors": {
403 | "version": "2.8.5",
404 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
405 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
406 | "dependencies": {
407 | "object-assign": "^4",
408 | "vary": "^1"
409 | },
410 | "engines": {
411 | "node": ">= 0.10"
412 | }
413 | },
414 | "node_modules/debug": {
415 | "version": "3.2.7",
416 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
417 | "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
418 | "dev": true,
419 | "dependencies": {
420 | "ms": "^2.1.1"
421 | }
422 | },
423 | "node_modules/delegates": {
424 | "version": "1.0.0",
425 | "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
426 | "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ=="
427 | },
428 | "node_modules/depd": {
429 | "version": "2.0.0",
430 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
431 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
432 | "engines": {
433 | "node": ">= 0.8"
434 | }
435 | },
436 | "node_modules/destroy": {
437 | "version": "1.2.0",
438 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
439 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
440 | "engines": {
441 | "node": ">= 0.8",
442 | "npm": "1.2.8000 || >= 1.4.16"
443 | }
444 | },
445 | "node_modules/detect-libc": {
446 | "version": "2.0.2",
447 | "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz",
448 | "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==",
449 | "engines": {
450 | "node": ">=8"
451 | }
452 | },
453 | "node_modules/dotenv": {
454 | "version": "16.3.1",
455 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz",
456 | "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==",
457 | "engines": {
458 | "node": ">=12"
459 | },
460 | "funding": {
461 | "url": "https://github.com/motdotla/dotenv?sponsor=1"
462 | }
463 | },
464 | "node_modules/ecdsa-sig-formatter": {
465 | "version": "1.0.11",
466 | "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
467 | "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
468 | "dependencies": {
469 | "safe-buffer": "^5.0.1"
470 | }
471 | },
472 | "node_modules/ee-first": {
473 | "version": "1.1.1",
474 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
475 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
476 | },
477 | "node_modules/emoji-regex": {
478 | "version": "8.0.0",
479 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
480 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
481 | },
482 | "node_modules/encodeurl": {
483 | "version": "1.0.2",
484 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
485 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
486 | "engines": {
487 | "node": ">= 0.8"
488 | }
489 | },
490 | "node_modules/escape-html": {
491 | "version": "1.0.3",
492 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
493 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
494 | },
495 | "node_modules/etag": {
496 | "version": "1.8.1",
497 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
498 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
499 | "engines": {
500 | "node": ">= 0.6"
501 | }
502 | },
503 | "node_modules/express": {
504 | "version": "4.18.2",
505 | "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
506 | "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==",
507 | "dependencies": {
508 | "accepts": "~1.3.8",
509 | "array-flatten": "1.1.1",
510 | "body-parser": "1.20.1",
511 | "content-disposition": "0.5.4",
512 | "content-type": "~1.0.4",
513 | "cookie": "0.5.0",
514 | "cookie-signature": "1.0.6",
515 | "debug": "2.6.9",
516 | "depd": "2.0.0",
517 | "encodeurl": "~1.0.2",
518 | "escape-html": "~1.0.3",
519 | "etag": "~1.8.1",
520 | "finalhandler": "1.2.0",
521 | "fresh": "0.5.2",
522 | "http-errors": "2.0.0",
523 | "merge-descriptors": "1.0.1",
524 | "methods": "~1.1.2",
525 | "on-finished": "2.4.1",
526 | "parseurl": "~1.3.3",
527 | "path-to-regexp": "0.1.7",
528 | "proxy-addr": "~2.0.7",
529 | "qs": "6.11.0",
530 | "range-parser": "~1.2.1",
531 | "safe-buffer": "5.2.1",
532 | "send": "0.18.0",
533 | "serve-static": "1.15.0",
534 | "setprototypeof": "1.2.0",
535 | "statuses": "2.0.1",
536 | "type-is": "~1.6.18",
537 | "utils-merge": "1.0.1",
538 | "vary": "~1.1.2"
539 | },
540 | "engines": {
541 | "node": ">= 0.10.0"
542 | }
543 | },
544 | "node_modules/express/node_modules/debug": {
545 | "version": "2.6.9",
546 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
547 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
548 | "dependencies": {
549 | "ms": "2.0.0"
550 | }
551 | },
552 | "node_modules/express/node_modules/ms": {
553 | "version": "2.0.0",
554 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
555 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
556 | },
557 | "node_modules/fill-range": {
558 | "version": "7.0.1",
559 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
560 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
561 | "dev": true,
562 | "dependencies": {
563 | "to-regex-range": "^5.0.1"
564 | },
565 | "engines": {
566 | "node": ">=8"
567 | }
568 | },
569 | "node_modules/finalhandler": {
570 | "version": "1.2.0",
571 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
572 | "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
573 | "dependencies": {
574 | "debug": "2.6.9",
575 | "encodeurl": "~1.0.2",
576 | "escape-html": "~1.0.3",
577 | "on-finished": "2.4.1",
578 | "parseurl": "~1.3.3",
579 | "statuses": "2.0.1",
580 | "unpipe": "~1.0.0"
581 | },
582 | "engines": {
583 | "node": ">= 0.8"
584 | }
585 | },
586 | "node_modules/finalhandler/node_modules/debug": {
587 | "version": "2.6.9",
588 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
589 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
590 | "dependencies": {
591 | "ms": "2.0.0"
592 | }
593 | },
594 | "node_modules/finalhandler/node_modules/ms": {
595 | "version": "2.0.0",
596 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
597 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
598 | },
599 | "node_modules/forwarded": {
600 | "version": "0.2.0",
601 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
602 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
603 | "engines": {
604 | "node": ">= 0.6"
605 | }
606 | },
607 | "node_modules/fresh": {
608 | "version": "0.5.2",
609 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
610 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
611 | "engines": {
612 | "node": ">= 0.6"
613 | }
614 | },
615 | "node_modules/fs-minipass": {
616 | "version": "2.1.0",
617 | "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
618 | "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
619 | "dependencies": {
620 | "minipass": "^3.0.0"
621 | },
622 | "engines": {
623 | "node": ">= 8"
624 | }
625 | },
626 | "node_modules/fs-minipass/node_modules/minipass": {
627 | "version": "3.3.6",
628 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
629 | "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
630 | "dependencies": {
631 | "yallist": "^4.0.0"
632 | },
633 | "engines": {
634 | "node": ">=8"
635 | }
636 | },
637 | "node_modules/fs.realpath": {
638 | "version": "1.0.0",
639 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
640 | "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
641 | },
642 | "node_modules/fsevents": {
643 | "version": "2.3.3",
644 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
645 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
646 | "dev": true,
647 | "hasInstallScript": true,
648 | "optional": true,
649 | "os": [
650 | "darwin"
651 | ],
652 | "engines": {
653 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
654 | }
655 | },
656 | "node_modules/function-bind": {
657 | "version": "1.1.2",
658 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
659 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
660 | "funding": {
661 | "url": "https://github.com/sponsors/ljharb"
662 | }
663 | },
664 | "node_modules/gauge": {
665 | "version": "3.0.2",
666 | "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz",
667 | "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==",
668 | "dependencies": {
669 | "aproba": "^1.0.3 || ^2.0.0",
670 | "color-support": "^1.1.2",
671 | "console-control-strings": "^1.0.0",
672 | "has-unicode": "^2.0.1",
673 | "object-assign": "^4.1.1",
674 | "signal-exit": "^3.0.0",
675 | "string-width": "^4.2.3",
676 | "strip-ansi": "^6.0.1",
677 | "wide-align": "^1.1.2"
678 | },
679 | "engines": {
680 | "node": ">=10"
681 | }
682 | },
683 | "node_modules/get-intrinsic": {
684 | "version": "1.2.1",
685 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
686 | "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
687 | "dependencies": {
688 | "function-bind": "^1.1.1",
689 | "has": "^1.0.3",
690 | "has-proto": "^1.0.1",
691 | "has-symbols": "^1.0.3"
692 | },
693 | "funding": {
694 | "url": "https://github.com/sponsors/ljharb"
695 | }
696 | },
697 | "node_modules/glob": {
698 | "version": "7.2.3",
699 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
700 | "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
701 | "dependencies": {
702 | "fs.realpath": "^1.0.0",
703 | "inflight": "^1.0.4",
704 | "inherits": "2",
705 | "minimatch": "^3.1.1",
706 | "once": "^1.3.0",
707 | "path-is-absolute": "^1.0.0"
708 | },
709 | "engines": {
710 | "node": "*"
711 | },
712 | "funding": {
713 | "url": "https://github.com/sponsors/isaacs"
714 | }
715 | },
716 | "node_modules/glob-parent": {
717 | "version": "5.1.2",
718 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
719 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
720 | "dev": true,
721 | "dependencies": {
722 | "is-glob": "^4.0.1"
723 | },
724 | "engines": {
725 | "node": ">= 6"
726 | }
727 | },
728 | "node_modules/has": {
729 | "version": "1.0.4",
730 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz",
731 | "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==",
732 | "engines": {
733 | "node": ">= 0.4.0"
734 | }
735 | },
736 | "node_modules/has-flag": {
737 | "version": "3.0.0",
738 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
739 | "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
740 | "dev": true,
741 | "engines": {
742 | "node": ">=4"
743 | }
744 | },
745 | "node_modules/has-proto": {
746 | "version": "1.0.1",
747 | "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
748 | "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
749 | "engines": {
750 | "node": ">= 0.4"
751 | },
752 | "funding": {
753 | "url": "https://github.com/sponsors/ljharb"
754 | }
755 | },
756 | "node_modules/has-symbols": {
757 | "version": "1.0.3",
758 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
759 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
760 | "engines": {
761 | "node": ">= 0.4"
762 | },
763 | "funding": {
764 | "url": "https://github.com/sponsors/ljharb"
765 | }
766 | },
767 | "node_modules/has-unicode": {
768 | "version": "2.0.1",
769 | "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
770 | "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ=="
771 | },
772 | "node_modules/http-errors": {
773 | "version": "2.0.0",
774 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
775 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
776 | "dependencies": {
777 | "depd": "2.0.0",
778 | "inherits": "2.0.4",
779 | "setprototypeof": "1.2.0",
780 | "statuses": "2.0.1",
781 | "toidentifier": "1.0.1"
782 | },
783 | "engines": {
784 | "node": ">= 0.8"
785 | }
786 | },
787 | "node_modules/https-proxy-agent": {
788 | "version": "5.0.1",
789 | "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
790 | "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
791 | "dependencies": {
792 | "agent-base": "6",
793 | "debug": "4"
794 | },
795 | "engines": {
796 | "node": ">= 6"
797 | }
798 | },
799 | "node_modules/https-proxy-agent/node_modules/debug": {
800 | "version": "4.3.4",
801 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
802 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
803 | "dependencies": {
804 | "ms": "2.1.2"
805 | },
806 | "engines": {
807 | "node": ">=6.0"
808 | },
809 | "peerDependenciesMeta": {
810 | "supports-color": {
811 | "optional": true
812 | }
813 | }
814 | },
815 | "node_modules/https-proxy-agent/node_modules/ms": {
816 | "version": "2.1.2",
817 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
818 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
819 | },
820 | "node_modules/iconv-lite": {
821 | "version": "0.4.24",
822 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
823 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
824 | "dependencies": {
825 | "safer-buffer": ">= 2.1.2 < 3"
826 | },
827 | "engines": {
828 | "node": ">=0.10.0"
829 | }
830 | },
831 | "node_modules/ignore-by-default": {
832 | "version": "1.0.1",
833 | "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
834 | "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==",
835 | "dev": true
836 | },
837 | "node_modules/inflight": {
838 | "version": "1.0.6",
839 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
840 | "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
841 | "dependencies": {
842 | "once": "^1.3.0",
843 | "wrappy": "1"
844 | }
845 | },
846 | "node_modules/inherits": {
847 | "version": "2.0.4",
848 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
849 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
850 | },
851 | "node_modules/ip": {
852 | "version": "2.0.0",
853 | "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz",
854 | "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ=="
855 | },
856 | "node_modules/ipaddr.js": {
857 | "version": "1.9.1",
858 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
859 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
860 | "engines": {
861 | "node": ">= 0.10"
862 | }
863 | },
864 | "node_modules/is-binary-path": {
865 | "version": "2.1.0",
866 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
867 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
868 | "dev": true,
869 | "dependencies": {
870 | "binary-extensions": "^2.0.0"
871 | },
872 | "engines": {
873 | "node": ">=8"
874 | }
875 | },
876 | "node_modules/is-extglob": {
877 | "version": "2.1.1",
878 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
879 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
880 | "dev": true,
881 | "engines": {
882 | "node": ">=0.10.0"
883 | }
884 | },
885 | "node_modules/is-fullwidth-code-point": {
886 | "version": "3.0.0",
887 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
888 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
889 | "engines": {
890 | "node": ">=8"
891 | }
892 | },
893 | "node_modules/is-glob": {
894 | "version": "4.0.3",
895 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
896 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
897 | "dev": true,
898 | "dependencies": {
899 | "is-extglob": "^2.1.1"
900 | },
901 | "engines": {
902 | "node": ">=0.10.0"
903 | }
904 | },
905 | "node_modules/is-number": {
906 | "version": "7.0.0",
907 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
908 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
909 | "dev": true,
910 | "engines": {
911 | "node": ">=0.12.0"
912 | }
913 | },
914 | "node_modules/jsonwebtoken": {
915 | "version": "9.0.2",
916 | "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz",
917 | "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==",
918 | "dependencies": {
919 | "jws": "^3.2.2",
920 | "lodash.includes": "^4.3.0",
921 | "lodash.isboolean": "^3.0.3",
922 | "lodash.isinteger": "^4.0.4",
923 | "lodash.isnumber": "^3.0.3",
924 | "lodash.isplainobject": "^4.0.6",
925 | "lodash.isstring": "^4.0.1",
926 | "lodash.once": "^4.0.0",
927 | "ms": "^2.1.1",
928 | "semver": "^7.5.4"
929 | },
930 | "engines": {
931 | "node": ">=12",
932 | "npm": ">=6"
933 | }
934 | },
935 | "node_modules/jwa": {
936 | "version": "1.4.1",
937 | "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
938 | "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
939 | "dependencies": {
940 | "buffer-equal-constant-time": "1.0.1",
941 | "ecdsa-sig-formatter": "1.0.11",
942 | "safe-buffer": "^5.0.1"
943 | }
944 | },
945 | "node_modules/jws": {
946 | "version": "3.2.2",
947 | "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
948 | "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
949 | "dependencies": {
950 | "jwa": "^1.4.1",
951 | "safe-buffer": "^5.0.1"
952 | }
953 | },
954 | "node_modules/kareem": {
955 | "version": "2.5.1",
956 | "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.5.1.tgz",
957 | "integrity": "sha512-7jFxRVm+jD+rkq3kY0iZDJfsO2/t4BBPeEb2qKn2lR/9KhuksYk5hxzfRYWMPV8P/x2d0kHD306YyWLzjjH+uA==",
958 | "engines": {
959 | "node": ">=12.0.0"
960 | }
961 | },
962 | "node_modules/lodash.includes": {
963 | "version": "4.3.0",
964 | "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
965 | "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w=="
966 | },
967 | "node_modules/lodash.isboolean": {
968 | "version": "3.0.3",
969 | "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
970 | "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg=="
971 | },
972 | "node_modules/lodash.isinteger": {
973 | "version": "4.0.4",
974 | "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
975 | "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA=="
976 | },
977 | "node_modules/lodash.isnumber": {
978 | "version": "3.0.3",
979 | "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
980 | "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw=="
981 | },
982 | "node_modules/lodash.isplainobject": {
983 | "version": "4.0.6",
984 | "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
985 | "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="
986 | },
987 | "node_modules/lodash.isstring": {
988 | "version": "4.0.1",
989 | "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
990 | "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw=="
991 | },
992 | "node_modules/lodash.once": {
993 | "version": "4.1.1",
994 | "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
995 | "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="
996 | },
997 | "node_modules/lru-cache": {
998 | "version": "6.0.0",
999 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
1000 | "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
1001 | "dependencies": {
1002 | "yallist": "^4.0.0"
1003 | },
1004 | "engines": {
1005 | "node": ">=10"
1006 | }
1007 | },
1008 | "node_modules/make-dir": {
1009 | "version": "3.1.0",
1010 | "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
1011 | "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
1012 | "dependencies": {
1013 | "semver": "^6.0.0"
1014 | },
1015 | "engines": {
1016 | "node": ">=8"
1017 | },
1018 | "funding": {
1019 | "url": "https://github.com/sponsors/sindresorhus"
1020 | }
1021 | },
1022 | "node_modules/make-dir/node_modules/semver": {
1023 | "version": "6.3.1",
1024 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
1025 | "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
1026 | "bin": {
1027 | "semver": "bin/semver.js"
1028 | }
1029 | },
1030 | "node_modules/media-typer": {
1031 | "version": "0.3.0",
1032 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
1033 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
1034 | "engines": {
1035 | "node": ">= 0.6"
1036 | }
1037 | },
1038 | "node_modules/memory-pager": {
1039 | "version": "1.5.0",
1040 | "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
1041 | "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==",
1042 | "optional": true
1043 | },
1044 | "node_modules/merge-descriptors": {
1045 | "version": "1.0.1",
1046 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
1047 | "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
1048 | },
1049 | "node_modules/methods": {
1050 | "version": "1.1.2",
1051 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
1052 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
1053 | "engines": {
1054 | "node": ">= 0.6"
1055 | }
1056 | },
1057 | "node_modules/mime": {
1058 | "version": "1.6.0",
1059 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
1060 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
1061 | "bin": {
1062 | "mime": "cli.js"
1063 | },
1064 | "engines": {
1065 | "node": ">=4"
1066 | }
1067 | },
1068 | "node_modules/mime-db": {
1069 | "version": "1.52.0",
1070 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
1071 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
1072 | "engines": {
1073 | "node": ">= 0.6"
1074 | }
1075 | },
1076 | "node_modules/mime-types": {
1077 | "version": "2.1.35",
1078 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
1079 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
1080 | "dependencies": {
1081 | "mime-db": "1.52.0"
1082 | },
1083 | "engines": {
1084 | "node": ">= 0.6"
1085 | }
1086 | },
1087 | "node_modules/minimatch": {
1088 | "version": "3.1.2",
1089 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
1090 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
1091 | "dependencies": {
1092 | "brace-expansion": "^1.1.7"
1093 | },
1094 | "engines": {
1095 | "node": "*"
1096 | }
1097 | },
1098 | "node_modules/minipass": {
1099 | "version": "5.0.0",
1100 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
1101 | "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
1102 | "engines": {
1103 | "node": ">=8"
1104 | }
1105 | },
1106 | "node_modules/minizlib": {
1107 | "version": "2.1.2",
1108 | "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
1109 | "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
1110 | "dependencies": {
1111 | "minipass": "^3.0.0",
1112 | "yallist": "^4.0.0"
1113 | },
1114 | "engines": {
1115 | "node": ">= 8"
1116 | }
1117 | },
1118 | "node_modules/minizlib/node_modules/minipass": {
1119 | "version": "3.3.6",
1120 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
1121 | "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
1122 | "dependencies": {
1123 | "yallist": "^4.0.0"
1124 | },
1125 | "engines": {
1126 | "node": ">=8"
1127 | }
1128 | },
1129 | "node_modules/mkdirp": {
1130 | "version": "1.0.4",
1131 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
1132 | "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
1133 | "bin": {
1134 | "mkdirp": "bin/cmd.js"
1135 | },
1136 | "engines": {
1137 | "node": ">=10"
1138 | }
1139 | },
1140 | "node_modules/mongodb": {
1141 | "version": "5.9.0",
1142 | "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-5.9.0.tgz",
1143 | "integrity": "sha512-g+GCMHN1CoRUA+wb1Agv0TI4YTSiWr42B5ulkiAfLLHitGK1R+PkSAf3Lr5rPZwi/3F04LiaZEW0Kxro9Fi2TA==",
1144 | "dependencies": {
1145 | "bson": "^5.5.0",
1146 | "mongodb-connection-string-url": "^2.6.0",
1147 | "socks": "^2.7.1"
1148 | },
1149 | "engines": {
1150 | "node": ">=14.20.1"
1151 | },
1152 | "optionalDependencies": {
1153 | "@mongodb-js/saslprep": "^1.1.0"
1154 | },
1155 | "peerDependencies": {
1156 | "@aws-sdk/credential-providers": "^3.188.0",
1157 | "@mongodb-js/zstd": "^1.0.0",
1158 | "kerberos": "^1.0.0 || ^2.0.0",
1159 | "mongodb-client-encryption": ">=2.3.0 <3",
1160 | "snappy": "^7.2.2"
1161 | },
1162 | "peerDependenciesMeta": {
1163 | "@aws-sdk/credential-providers": {
1164 | "optional": true
1165 | },
1166 | "@mongodb-js/zstd": {
1167 | "optional": true
1168 | },
1169 | "kerberos": {
1170 | "optional": true
1171 | },
1172 | "mongodb-client-encryption": {
1173 | "optional": true
1174 | },
1175 | "snappy": {
1176 | "optional": true
1177 | }
1178 | }
1179 | },
1180 | "node_modules/mongodb-connection-string-url": {
1181 | "version": "2.6.0",
1182 | "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.6.0.tgz",
1183 | "integrity": "sha512-WvTZlI9ab0QYtTYnuMLgobULWhokRjtC7db9LtcVfJ+Hsnyr5eo6ZtNAt3Ly24XZScGMelOcGtm7lSn0332tPQ==",
1184 | "dependencies": {
1185 | "@types/whatwg-url": "^8.2.1",
1186 | "whatwg-url": "^11.0.0"
1187 | }
1188 | },
1189 | "node_modules/mongodb-connection-string-url/node_modules/tr46": {
1190 | "version": "3.0.0",
1191 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz",
1192 | "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==",
1193 | "dependencies": {
1194 | "punycode": "^2.1.1"
1195 | },
1196 | "engines": {
1197 | "node": ">=12"
1198 | }
1199 | },
1200 | "node_modules/mongodb-connection-string-url/node_modules/webidl-conversions": {
1201 | "version": "7.0.0",
1202 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
1203 | "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
1204 | "engines": {
1205 | "node": ">=12"
1206 | }
1207 | },
1208 | "node_modules/mongodb-connection-string-url/node_modules/whatwg-url": {
1209 | "version": "11.0.0",
1210 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz",
1211 | "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==",
1212 | "dependencies": {
1213 | "tr46": "^3.0.0",
1214 | "webidl-conversions": "^7.0.0"
1215 | },
1216 | "engines": {
1217 | "node": ">=12"
1218 | }
1219 | },
1220 | "node_modules/mongoose": {
1221 | "version": "7.6.2",
1222 | "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-7.6.2.tgz",
1223 | "integrity": "sha512-OVx6RWbfNOzBbfTvXoOkgZmaizdXDU/B/KbBjietXQoInSg/OSULjOavXJzL51XWFkbefqkOvbeE07DfvW6FkQ==",
1224 | "dependencies": {
1225 | "bson": "^5.5.0",
1226 | "kareem": "2.5.1",
1227 | "mongodb": "5.9.0",
1228 | "mpath": "0.9.0",
1229 | "mquery": "5.0.0",
1230 | "ms": "2.1.3",
1231 | "sift": "16.0.1"
1232 | },
1233 | "engines": {
1234 | "node": ">=14.20.1"
1235 | },
1236 | "funding": {
1237 | "type": "opencollective",
1238 | "url": "https://opencollective.com/mongoose"
1239 | }
1240 | },
1241 | "node_modules/mpath": {
1242 | "version": "0.9.0",
1243 | "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz",
1244 | "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==",
1245 | "engines": {
1246 | "node": ">=4.0.0"
1247 | }
1248 | },
1249 | "node_modules/mquery": {
1250 | "version": "5.0.0",
1251 | "resolved": "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz",
1252 | "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==",
1253 | "dependencies": {
1254 | "debug": "4.x"
1255 | },
1256 | "engines": {
1257 | "node": ">=14.0.0"
1258 | }
1259 | },
1260 | "node_modules/mquery/node_modules/debug": {
1261 | "version": "4.3.4",
1262 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
1263 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
1264 | "dependencies": {
1265 | "ms": "2.1.2"
1266 | },
1267 | "engines": {
1268 | "node": ">=6.0"
1269 | },
1270 | "peerDependenciesMeta": {
1271 | "supports-color": {
1272 | "optional": true
1273 | }
1274 | }
1275 | },
1276 | "node_modules/mquery/node_modules/ms": {
1277 | "version": "2.1.2",
1278 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
1279 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
1280 | },
1281 | "node_modules/ms": {
1282 | "version": "2.1.3",
1283 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
1284 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
1285 | },
1286 | "node_modules/negotiator": {
1287 | "version": "0.6.3",
1288 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
1289 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
1290 | "engines": {
1291 | "node": ">= 0.6"
1292 | }
1293 | },
1294 | "node_modules/node-addon-api": {
1295 | "version": "5.1.0",
1296 | "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz",
1297 | "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA=="
1298 | },
1299 | "node_modules/node-fetch": {
1300 | "version": "2.7.0",
1301 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
1302 | "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
1303 | "dependencies": {
1304 | "whatwg-url": "^5.0.0"
1305 | },
1306 | "engines": {
1307 | "node": "4.x || >=6.0.0"
1308 | },
1309 | "peerDependencies": {
1310 | "encoding": "^0.1.0"
1311 | },
1312 | "peerDependenciesMeta": {
1313 | "encoding": {
1314 | "optional": true
1315 | }
1316 | }
1317 | },
1318 | "node_modules/nodemon": {
1319 | "version": "3.0.1",
1320 | "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.0.1.tgz",
1321 | "integrity": "sha512-g9AZ7HmkhQkqXkRc20w+ZfQ73cHLbE8hnPbtaFbFtCumZsjyMhKk9LajQ07U5Ux28lvFjZ5X7HvWR1xzU8jHVw==",
1322 | "dev": true,
1323 | "dependencies": {
1324 | "chokidar": "^3.5.2",
1325 | "debug": "^3.2.7",
1326 | "ignore-by-default": "^1.0.1",
1327 | "minimatch": "^3.1.2",
1328 | "pstree.remy": "^1.1.8",
1329 | "semver": "^7.5.3",
1330 | "simple-update-notifier": "^2.0.0",
1331 | "supports-color": "^5.5.0",
1332 | "touch": "^3.1.0",
1333 | "undefsafe": "^2.0.5"
1334 | },
1335 | "bin": {
1336 | "nodemon": "bin/nodemon.js"
1337 | },
1338 | "engines": {
1339 | "node": ">=10"
1340 | },
1341 | "funding": {
1342 | "type": "opencollective",
1343 | "url": "https://opencollective.com/nodemon"
1344 | }
1345 | },
1346 | "node_modules/nopt": {
1347 | "version": "1.0.10",
1348 | "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
1349 | "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==",
1350 | "dev": true,
1351 | "dependencies": {
1352 | "abbrev": "1"
1353 | },
1354 | "bin": {
1355 | "nopt": "bin/nopt.js"
1356 | },
1357 | "engines": {
1358 | "node": "*"
1359 | }
1360 | },
1361 | "node_modules/normalize-path": {
1362 | "version": "3.0.0",
1363 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
1364 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
1365 | "dev": true,
1366 | "engines": {
1367 | "node": ">=0.10.0"
1368 | }
1369 | },
1370 | "node_modules/npmlog": {
1371 | "version": "5.0.1",
1372 | "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz",
1373 | "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==",
1374 | "dependencies": {
1375 | "are-we-there-yet": "^2.0.0",
1376 | "console-control-strings": "^1.1.0",
1377 | "gauge": "^3.0.0",
1378 | "set-blocking": "^2.0.0"
1379 | }
1380 | },
1381 | "node_modules/object-assign": {
1382 | "version": "4.1.1",
1383 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
1384 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
1385 | "engines": {
1386 | "node": ">=0.10.0"
1387 | }
1388 | },
1389 | "node_modules/object-inspect": {
1390 | "version": "1.13.0",
1391 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.0.tgz",
1392 | "integrity": "sha512-HQ4J+ic8hKrgIt3mqk6cVOVrW2ozL4KdvHlqpBv9vDYWx9ysAgENAdvy4FoGF+KFdhR7nQTNm5J0ctAeOwn+3g==",
1393 | "funding": {
1394 | "url": "https://github.com/sponsors/ljharb"
1395 | }
1396 | },
1397 | "node_modules/on-finished": {
1398 | "version": "2.4.1",
1399 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
1400 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
1401 | "dependencies": {
1402 | "ee-first": "1.1.1"
1403 | },
1404 | "engines": {
1405 | "node": ">= 0.8"
1406 | }
1407 | },
1408 | "node_modules/once": {
1409 | "version": "1.4.0",
1410 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
1411 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
1412 | "dependencies": {
1413 | "wrappy": "1"
1414 | }
1415 | },
1416 | "node_modules/parseurl": {
1417 | "version": "1.3.3",
1418 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
1419 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
1420 | "engines": {
1421 | "node": ">= 0.8"
1422 | }
1423 | },
1424 | "node_modules/path-is-absolute": {
1425 | "version": "1.0.1",
1426 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
1427 | "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
1428 | "engines": {
1429 | "node": ">=0.10.0"
1430 | }
1431 | },
1432 | "node_modules/path-to-regexp": {
1433 | "version": "0.1.7",
1434 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
1435 | "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
1436 | },
1437 | "node_modules/picomatch": {
1438 | "version": "2.3.1",
1439 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
1440 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
1441 | "dev": true,
1442 | "engines": {
1443 | "node": ">=8.6"
1444 | },
1445 | "funding": {
1446 | "url": "https://github.com/sponsors/jonschlinkert"
1447 | }
1448 | },
1449 | "node_modules/proxy-addr": {
1450 | "version": "2.0.7",
1451 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
1452 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
1453 | "dependencies": {
1454 | "forwarded": "0.2.0",
1455 | "ipaddr.js": "1.9.1"
1456 | },
1457 | "engines": {
1458 | "node": ">= 0.10"
1459 | }
1460 | },
1461 | "node_modules/pstree.remy": {
1462 | "version": "1.1.8",
1463 | "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
1464 | "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==",
1465 | "dev": true
1466 | },
1467 | "node_modules/punycode": {
1468 | "version": "2.3.0",
1469 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
1470 | "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
1471 | "engines": {
1472 | "node": ">=6"
1473 | }
1474 | },
1475 | "node_modules/qs": {
1476 | "version": "6.11.0",
1477 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
1478 | "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
1479 | "dependencies": {
1480 | "side-channel": "^1.0.4"
1481 | },
1482 | "engines": {
1483 | "node": ">=0.6"
1484 | },
1485 | "funding": {
1486 | "url": "https://github.com/sponsors/ljharb"
1487 | }
1488 | },
1489 | "node_modules/range-parser": {
1490 | "version": "1.2.1",
1491 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
1492 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
1493 | "engines": {
1494 | "node": ">= 0.6"
1495 | }
1496 | },
1497 | "node_modules/raw-body": {
1498 | "version": "2.5.1",
1499 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
1500 | "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
1501 | "dependencies": {
1502 | "bytes": "3.1.2",
1503 | "http-errors": "2.0.0",
1504 | "iconv-lite": "0.4.24",
1505 | "unpipe": "1.0.0"
1506 | },
1507 | "engines": {
1508 | "node": ">= 0.8"
1509 | }
1510 | },
1511 | "node_modules/readable-stream": {
1512 | "version": "3.6.2",
1513 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
1514 | "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
1515 | "dependencies": {
1516 | "inherits": "^2.0.3",
1517 | "string_decoder": "^1.1.1",
1518 | "util-deprecate": "^1.0.1"
1519 | },
1520 | "engines": {
1521 | "node": ">= 6"
1522 | }
1523 | },
1524 | "node_modules/readdirp": {
1525 | "version": "3.6.0",
1526 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
1527 | "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
1528 | "dev": true,
1529 | "dependencies": {
1530 | "picomatch": "^2.2.1"
1531 | },
1532 | "engines": {
1533 | "node": ">=8.10.0"
1534 | }
1535 | },
1536 | "node_modules/rimraf": {
1537 | "version": "3.0.2",
1538 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
1539 | "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
1540 | "dependencies": {
1541 | "glob": "^7.1.3"
1542 | },
1543 | "bin": {
1544 | "rimraf": "bin.js"
1545 | },
1546 | "funding": {
1547 | "url": "https://github.com/sponsors/isaacs"
1548 | }
1549 | },
1550 | "node_modules/safe-buffer": {
1551 | "version": "5.2.1",
1552 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
1553 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
1554 | "funding": [
1555 | {
1556 | "type": "github",
1557 | "url": "https://github.com/sponsors/feross"
1558 | },
1559 | {
1560 | "type": "patreon",
1561 | "url": "https://www.patreon.com/feross"
1562 | },
1563 | {
1564 | "type": "consulting",
1565 | "url": "https://feross.org/support"
1566 | }
1567 | ]
1568 | },
1569 | "node_modules/safer-buffer": {
1570 | "version": "2.1.2",
1571 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
1572 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
1573 | },
1574 | "node_modules/semver": {
1575 | "version": "7.5.4",
1576 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
1577 | "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
1578 | "dependencies": {
1579 | "lru-cache": "^6.0.0"
1580 | },
1581 | "bin": {
1582 | "semver": "bin/semver.js"
1583 | },
1584 | "engines": {
1585 | "node": ">=10"
1586 | }
1587 | },
1588 | "node_modules/send": {
1589 | "version": "0.18.0",
1590 | "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
1591 | "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
1592 | "dependencies": {
1593 | "debug": "2.6.9",
1594 | "depd": "2.0.0",
1595 | "destroy": "1.2.0",
1596 | "encodeurl": "~1.0.2",
1597 | "escape-html": "~1.0.3",
1598 | "etag": "~1.8.1",
1599 | "fresh": "0.5.2",
1600 | "http-errors": "2.0.0",
1601 | "mime": "1.6.0",
1602 | "ms": "2.1.3",
1603 | "on-finished": "2.4.1",
1604 | "range-parser": "~1.2.1",
1605 | "statuses": "2.0.1"
1606 | },
1607 | "engines": {
1608 | "node": ">= 0.8.0"
1609 | }
1610 | },
1611 | "node_modules/send/node_modules/debug": {
1612 | "version": "2.6.9",
1613 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
1614 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
1615 | "dependencies": {
1616 | "ms": "2.0.0"
1617 | }
1618 | },
1619 | "node_modules/send/node_modules/debug/node_modules/ms": {
1620 | "version": "2.0.0",
1621 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
1622 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
1623 | },
1624 | "node_modules/serve-static": {
1625 | "version": "1.15.0",
1626 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
1627 | "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
1628 | "dependencies": {
1629 | "encodeurl": "~1.0.2",
1630 | "escape-html": "~1.0.3",
1631 | "parseurl": "~1.3.3",
1632 | "send": "0.18.0"
1633 | },
1634 | "engines": {
1635 | "node": ">= 0.8.0"
1636 | }
1637 | },
1638 | "node_modules/set-blocking": {
1639 | "version": "2.0.0",
1640 | "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
1641 | "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="
1642 | },
1643 | "node_modules/setprototypeof": {
1644 | "version": "1.2.0",
1645 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
1646 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
1647 | },
1648 | "node_modules/side-channel": {
1649 | "version": "1.0.4",
1650 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
1651 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
1652 | "dependencies": {
1653 | "call-bind": "^1.0.0",
1654 | "get-intrinsic": "^1.0.2",
1655 | "object-inspect": "^1.9.0"
1656 | },
1657 | "funding": {
1658 | "url": "https://github.com/sponsors/ljharb"
1659 | }
1660 | },
1661 | "node_modules/sift": {
1662 | "version": "16.0.1",
1663 | "resolved": "https://registry.npmjs.org/sift/-/sift-16.0.1.tgz",
1664 | "integrity": "sha512-Wv6BjQ5zbhW7VFefWusVP33T/EM0vYikCaQ2qR8yULbsilAT8/wQaXvuQ3ptGLpoKx+lihJE3y2UTgKDyyNHZQ=="
1665 | },
1666 | "node_modules/signal-exit": {
1667 | "version": "3.0.7",
1668 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
1669 | "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
1670 | },
1671 | "node_modules/simple-update-notifier": {
1672 | "version": "2.0.0",
1673 | "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz",
1674 | "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==",
1675 | "dev": true,
1676 | "dependencies": {
1677 | "semver": "^7.5.3"
1678 | },
1679 | "engines": {
1680 | "node": ">=10"
1681 | }
1682 | },
1683 | "node_modules/smart-buffer": {
1684 | "version": "4.2.0",
1685 | "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
1686 | "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
1687 | "engines": {
1688 | "node": ">= 6.0.0",
1689 | "npm": ">= 3.0.0"
1690 | }
1691 | },
1692 | "node_modules/socks": {
1693 | "version": "2.7.1",
1694 | "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz",
1695 | "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==",
1696 | "dependencies": {
1697 | "ip": "^2.0.0",
1698 | "smart-buffer": "^4.2.0"
1699 | },
1700 | "engines": {
1701 | "node": ">= 10.13.0",
1702 | "npm": ">= 3.0.0"
1703 | }
1704 | },
1705 | "node_modules/sparse-bitfield": {
1706 | "version": "3.0.3",
1707 | "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
1708 | "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==",
1709 | "optional": true,
1710 | "dependencies": {
1711 | "memory-pager": "^1.0.2"
1712 | }
1713 | },
1714 | "node_modules/statuses": {
1715 | "version": "2.0.1",
1716 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
1717 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
1718 | "engines": {
1719 | "node": ">= 0.8"
1720 | }
1721 | },
1722 | "node_modules/string_decoder": {
1723 | "version": "1.3.0",
1724 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
1725 | "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
1726 | "dependencies": {
1727 | "safe-buffer": "~5.2.0"
1728 | }
1729 | },
1730 | "node_modules/string-width": {
1731 | "version": "4.2.3",
1732 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
1733 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
1734 | "dependencies": {
1735 | "emoji-regex": "^8.0.0",
1736 | "is-fullwidth-code-point": "^3.0.0",
1737 | "strip-ansi": "^6.0.1"
1738 | },
1739 | "engines": {
1740 | "node": ">=8"
1741 | }
1742 | },
1743 | "node_modules/strip-ansi": {
1744 | "version": "6.0.1",
1745 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
1746 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
1747 | "dependencies": {
1748 | "ansi-regex": "^5.0.1"
1749 | },
1750 | "engines": {
1751 | "node": ">=8"
1752 | }
1753 | },
1754 | "node_modules/supports-color": {
1755 | "version": "5.5.0",
1756 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
1757 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
1758 | "dev": true,
1759 | "dependencies": {
1760 | "has-flag": "^3.0.0"
1761 | },
1762 | "engines": {
1763 | "node": ">=4"
1764 | }
1765 | },
1766 | "node_modules/tar": {
1767 | "version": "6.2.0",
1768 | "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz",
1769 | "integrity": "sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==",
1770 | "dependencies": {
1771 | "chownr": "^2.0.0",
1772 | "fs-minipass": "^2.0.0",
1773 | "minipass": "^5.0.0",
1774 | "minizlib": "^2.1.1",
1775 | "mkdirp": "^1.0.3",
1776 | "yallist": "^4.0.0"
1777 | },
1778 | "engines": {
1779 | "node": ">=10"
1780 | }
1781 | },
1782 | "node_modules/to-regex-range": {
1783 | "version": "5.0.1",
1784 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
1785 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
1786 | "dev": true,
1787 | "dependencies": {
1788 | "is-number": "^7.0.0"
1789 | },
1790 | "engines": {
1791 | "node": ">=8.0"
1792 | }
1793 | },
1794 | "node_modules/toidentifier": {
1795 | "version": "1.0.1",
1796 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
1797 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
1798 | "engines": {
1799 | "node": ">=0.6"
1800 | }
1801 | },
1802 | "node_modules/touch": {
1803 | "version": "3.1.0",
1804 | "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz",
1805 | "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==",
1806 | "dev": true,
1807 | "dependencies": {
1808 | "nopt": "~1.0.10"
1809 | },
1810 | "bin": {
1811 | "nodetouch": "bin/nodetouch.js"
1812 | }
1813 | },
1814 | "node_modules/tr46": {
1815 | "version": "0.0.3",
1816 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
1817 | "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
1818 | },
1819 | "node_modules/type-is": {
1820 | "version": "1.6.18",
1821 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
1822 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
1823 | "dependencies": {
1824 | "media-typer": "0.3.0",
1825 | "mime-types": "~2.1.24"
1826 | },
1827 | "engines": {
1828 | "node": ">= 0.6"
1829 | }
1830 | },
1831 | "node_modules/undefsafe": {
1832 | "version": "2.0.5",
1833 | "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
1834 | "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==",
1835 | "dev": true
1836 | },
1837 | "node_modules/undici-types": {
1838 | "version": "5.25.3",
1839 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz",
1840 | "integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA=="
1841 | },
1842 | "node_modules/unpipe": {
1843 | "version": "1.0.0",
1844 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
1845 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
1846 | "engines": {
1847 | "node": ">= 0.8"
1848 | }
1849 | },
1850 | "node_modules/util-deprecate": {
1851 | "version": "1.0.2",
1852 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
1853 | "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
1854 | },
1855 | "node_modules/utils-merge": {
1856 | "version": "1.0.1",
1857 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
1858 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
1859 | "engines": {
1860 | "node": ">= 0.4.0"
1861 | }
1862 | },
1863 | "node_modules/vary": {
1864 | "version": "1.1.2",
1865 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
1866 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
1867 | "engines": {
1868 | "node": ">= 0.8"
1869 | }
1870 | },
1871 | "node_modules/webidl-conversions": {
1872 | "version": "3.0.1",
1873 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
1874 | "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
1875 | },
1876 | "node_modules/whatwg-url": {
1877 | "version": "5.0.0",
1878 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
1879 | "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
1880 | "dependencies": {
1881 | "tr46": "~0.0.3",
1882 | "webidl-conversions": "^3.0.0"
1883 | }
1884 | },
1885 | "node_modules/wide-align": {
1886 | "version": "1.1.5",
1887 | "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
1888 | "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
1889 | "dependencies": {
1890 | "string-width": "^1.0.2 || 2 || 3 || 4"
1891 | }
1892 | },
1893 | "node_modules/wrappy": {
1894 | "version": "1.0.2",
1895 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
1896 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
1897 | },
1898 | "node_modules/yallist": {
1899 | "version": "4.0.0",
1900 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
1901 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
1902 | }
1903 | }
1904 | }
1905 |
--------------------------------------------------------------------------------