├── .gitignore
├── backend
├── .env
├── routes
│ ├── wardenRoutes.js
│ ├── studentRoutes.js
│ ├── userRoutes.js
│ └── complaintRoutes.js
├── db.js
├── utils
│ └── jwtToken.js
├── controller
│ ├── wardenController.js
│ ├── studentController.js
│ ├── userController.js
│ └── complaintController.js
├── package.json
├── server.js
├── database.sql
├── middleware
│ └── auth.js
└── package-lock.json
├── images
├── login(1).png
├── signup(2).png
├── createComplaint(4).png
├── wardenDashboard(6).png
├── studentComplaint(5).png
├── studentDashboard(3).png
├── hostelDatabaseErDiagram.png
├── studentAccountInfo(9).png
├── studentDashboardUpdated(8).png
└── wardenResolvedComplaint(7).png
├── frontend
├── postcss.config.js
├── src
│ ├── testing
│ │ └── Headers.jsx
│ ├── index.css
│ ├── constants.jsx
│ ├── main.jsx
│ ├── utils
│ │ ├── PrivateRoute.jsx
│ │ └── Auth.jsx
│ ├── App.jsx
│ ├── pages
│ │ ├── Dashboard.jsx
│ │ ├── Navbar.jsx
│ │ ├── WardenComplaint.jsx
│ │ ├── AccountPage.jsx
│ │ ├── Login.jsx
│ │ ├── Complaint.jsx
│ │ └── Register.jsx
│ └── assets
│ │ └── react.svg
├── vite.config.js
├── tailwind.config.js
├── .gitignore
├── README.md
├── .eslintrc.cjs
├── index.html
├── package.json
└── public
│ └── vite.svg
├── docker-compose.yml
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | backend/node_modules
2 |
3 | node_modules
--------------------------------------------------------------------------------
/backend/.env:
--------------------------------------------------------------------------------
1 | ### added .env to github for reference only. add .env to gitignore
2 |
3 | JWTSECRET=abc123
4 |
--------------------------------------------------------------------------------
/images/login(1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chinmay-Ankolekar/Hostel-Grievance-Redressal/HEAD/images/login(1).png
--------------------------------------------------------------------------------
/images/signup(2).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chinmay-Ankolekar/Hostel-Grievance-Redressal/HEAD/images/signup(2).png
--------------------------------------------------------------------------------
/frontend/postcss.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/images/createComplaint(4).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chinmay-Ankolekar/Hostel-Grievance-Redressal/HEAD/images/createComplaint(4).png
--------------------------------------------------------------------------------
/images/wardenDashboard(6).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chinmay-Ankolekar/Hostel-Grievance-Redressal/HEAD/images/wardenDashboard(6).png
--------------------------------------------------------------------------------
/images/studentComplaint(5).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chinmay-Ankolekar/Hostel-Grievance-Redressal/HEAD/images/studentComplaint(5).png
--------------------------------------------------------------------------------
/images/studentDashboard(3).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chinmay-Ankolekar/Hostel-Grievance-Redressal/HEAD/images/studentDashboard(3).png
--------------------------------------------------------------------------------
/images/hostelDatabaseErDiagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chinmay-Ankolekar/Hostel-Grievance-Redressal/HEAD/images/hostelDatabaseErDiagram.png
--------------------------------------------------------------------------------
/images/studentAccountInfo(9).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chinmay-Ankolekar/Hostel-Grievance-Redressal/HEAD/images/studentAccountInfo(9).png
--------------------------------------------------------------------------------
/images/studentDashboardUpdated(8).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chinmay-Ankolekar/Hostel-Grievance-Redressal/HEAD/images/studentDashboardUpdated(8).png
--------------------------------------------------------------------------------
/images/wardenResolvedComplaint(7).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chinmay-Ankolekar/Hostel-Grievance-Redressal/HEAD/images/wardenResolvedComplaint(7).png
--------------------------------------------------------------------------------
/frontend/src/testing/Headers.jsx:
--------------------------------------------------------------------------------
1 | export const GetAuthHeader = () => {
2 | return { "content-Type": "application/json" , "Authorization" : localStorage.getItem("jwtToken") }
3 | }
4 |
5 |
--------------------------------------------------------------------------------
/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/src/index.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 |
6 | body {
7 | background-color: rgb(243 244 246 );
8 | }
9 |
10 | * {
11 | font-family: Lato;
12 | }
13 |
14 |
--------------------------------------------------------------------------------
/frontend/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | export default {
3 | content: [ "./index.html",
4 | "./src/**/*.{js,ts,jsx,tsx}",
5 | ],
6 | theme: {
7 | extend: {},
8 | },
9 | plugins: [],
10 | }
11 |
12 |
--------------------------------------------------------------------------------
/backend/routes/wardenRoutes.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const wardenRoutes = express.Router()
3 | const { getWardenByid } = require('../controller/wardenController');
4 |
5 | wardenRoutes.get("/warden/:warden_id",getWardenByid);
6 |
7 | module.exports = wardenRoutes
--------------------------------------------------------------------------------
/backend/routes/studentRoutes.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const studentRoutes = express.Router()
3 | const { getStudentByid } = require('../controller/studentController');
4 |
5 | studentRoutes.get("/student/:student_id",getStudentByid);
6 |
7 | module.exports = studentRoutes
--------------------------------------------------------------------------------
/frontend/src/constants.jsx:
--------------------------------------------------------------------------------
1 | export const Roles = {
2 | WARDEN : 'warden',
3 | STUDENT : 'student'
4 | }
5 |
6 | export const RoutesPathName = {
7 | SIGNUP_PAGE : '/signup',
8 | LOGIN_PAGE : '/login',
9 | DASHBOARD_PAGE : '/',
10 | ACCOUNT : "/account"
11 | }
12 |
--------------------------------------------------------------------------------
/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 |
7 | ReactDOM.createRoot(document.getElementById('root')).render(
8 |
9 |
10 | ,
11 | )
12 |
--------------------------------------------------------------------------------
/backend/routes/userRoutes.js:
--------------------------------------------------------------------------------
1 | const express = require("express");
2 | const userRoutes = express.Router();
3 |
4 | const { userRegister, userLogin } = require('../controller/userController');
5 |
6 | userRoutes.post("/register", userRegister);
7 |
8 | userRoutes.post("/login", userLogin);
9 |
10 | module.exports = userRoutes;
11 |
--------------------------------------------------------------------------------
/backend/db.js:
--------------------------------------------------------------------------------
1 | const Pool = require("pg").Pool;
2 |
3 | const pool = new Pool({
4 | user: "postgres",
5 | password: "chinmay.1221",
6 | host: "localhost",
7 | port: 5432,
8 | database: "hostel"
9 | });
10 |
11 | pool.on("error", (error, client) => {
12 | console.log(error);
13 | });
14 |
15 | module.exports = {
16 | pool
17 | };
18 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | # Use postgres/example user/password
2 | //github codespace database
3 | credentials
4 | version: '3.1'
5 |
6 | services:
7 |
8 | db:
9 | image: postgres
10 | restart: always
11 | ports:
12 | - 5432:5432
13 | environment:
14 | POSTGRES_PASSWORD: example
15 |
16 | adminer:
17 | image: adminer
18 | restart: always
19 | ports:
20 | - 8080:8080
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/backend/utils/jwtToken.js:
--------------------------------------------------------------------------------
1 | const jwt = require("jsonwebtoken");
2 | require("dotenv").config();
3 |
4 | function jwtGenerator(user_id, type) {
5 | const payload = {
6 | user: {
7 | user_id,
8 | type
9 | }
10 | };
11 |
12 | return jwt.sign(payload, process.env.JWTSECRET, { expiresIn: "1h" });
13 | }
14 |
15 | function jwtDecoder(token){
16 | return jwt.verify(token, process.env.JWTSECRET);
17 | }
18 |
19 | module.exports = {
20 | jwtDecoder,
21 | jwtGenerator
22 | };
23 |
--------------------------------------------------------------------------------
/frontend/src/utils/PrivateRoute.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Route, Navigate } from "react-router-dom";
3 | import Dashboard from "../pages/Dashboard";
4 | import { useAuth } from "./Auth";
5 |
6 | const PrivateRoute = () => {
7 | const { authToken, headers } = useAuth();
8 |
9 | console.log(authToken, headers);
10 |
11 | return authToken ? (
12 | <>
13 |
14 | >
15 | ) : (
16 |
17 | );
18 | };
19 |
20 | export default PrivateRoute;
21 |
--------------------------------------------------------------------------------
/backend/controller/wardenController.js:
--------------------------------------------------------------------------------
1 | const express = require("express");
2 | const cors = require("cors");
3 | const app = express();
4 | const db = require("../db");
5 |
6 | app.use(cors());
7 | app.use(express.json());
8 |
9 | exports.getWardenByid = async(req, res)=> {
10 | try {
11 | const {warden_id} = req.params;
12 | const warden = await db.pool.query(
13 | "select * from warden where warden_id = $1",
14 | [warden_id]
15 | );
16 | res.json(warden.rows)
17 | } catch (err) {
18 | console.log(err.message);
19 | }
20 | };
--------------------------------------------------------------------------------
/backend/controller/studentController.js:
--------------------------------------------------------------------------------
1 | const express = require("express");
2 | const cors = require("cors");
3 | const app = express();
4 | const db = require("../db");
5 | app.use(cors());
6 | app.use(express.json());
7 |
8 | exports.getStudentByid = async(req, res)=> {
9 | try {
10 | const {student_id} = req.params;
11 | const student = await db.pool.query(
12 | "select * from student where student_id = $1",
13 | [student_id]
14 | );
15 | res.json(student.rows)
16 | } catch (err) {
17 | console.log(err.message);
18 | }
19 | };
--------------------------------------------------------------------------------
/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/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "backend",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "server.js",
6 | "scripts": {
7 | "start": "nodemon server.js",
8 | "test": "echo \"Error: no test specified\" && exit 1"
9 | },
10 | "keywords": [],
11 | "author": "",
12 | "license": "ISC",
13 | "dependencies": {
14 | "bcrypt": "^5.1.1",
15 | "cookie-parser": "^1.4.6",
16 | "cors": "^2.8.5",
17 | "dotenv": "^16.3.1",
18 | "express": "^4.18.2",
19 | "express-async-handler": "^1.2.0",
20 | "jsonwebtoken": "^9.0.2",
21 | "nodemon": "^3.0.2",
22 | "pg": "^8.11.3"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/backend/server.js:
--------------------------------------------------------------------------------
1 | const express = require("express");
2 | const cors = require("cors");
3 | const app = express();
4 |
5 | const complaintRoutes = require("./routes/complaintRoutes");
6 | const studentRoutes = require("./routes/studentRoutes");
7 | const wardenRoutes = require("./routes/wardenRoutes");
8 | const userRoutes = require("./routes/userRoutes");
9 |
10 | app.use(cors());
11 | app.use(express.json());
12 |
13 | app.use('/', complaintRoutes);
14 | app.use('/', studentRoutes)
15 | app.use('/', wardenRoutes)
16 | app.use('/', userRoutes)
17 |
18 | app.listen(3000, () => {
19 | console.log("Application is running on port 3000");
20 | });
21 |
--------------------------------------------------------------------------------
/frontend/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | Vite + React
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/backend/routes/complaintRoutes.js:
--------------------------------------------------------------------------------
1 | const express = require("express");
2 | const complaintRoutes = express.Router();
3 | const {
4 | postComplaints,
5 | putComplaintsByid,
6 | getAllComplaintsByUser,
7 | getUserType,
8 | getUserDetails,
9 | deleteComplaints
10 | } = require("../controller/complaintController");
11 | const { authorizeWarden } = require("../middleware/auth");
12 |
13 | complaintRoutes.post("/complaints", postComplaints);
14 | complaintRoutes.get("/complaints", authorizeWarden, getAllComplaintsByUser);
15 | // complaintRoutes.get("/complaints", getAllComplaintsByUser);
16 | complaintRoutes.post("/complaints/:id", putComplaintsByid);
17 | complaintRoutes.delete("/complaints/:id", deleteComplaints);
18 |
19 | complaintRoutes.get("/userType", getUserType);
20 | complaintRoutes.get("/userDetails/:id", getUserDetails);
21 |
22 | module.exports = complaintRoutes;
23 |
--------------------------------------------------------------------------------
/frontend/src/App.jsx:
--------------------------------------------------------------------------------
1 | import Login from "./pages/Login";
2 | import Register from "./pages/Register";
3 | import { createBrowserRouter, Outlet, RouterProvider } from "react-router-dom";
4 | import { RoutesPathName } from "./constants";
5 | import PrivateRoute from "./utils/PrivateRoute";
6 | import AccountPage from "./pages/AccountPage";
7 |
8 | const routes = createBrowserRouter([
9 | {
10 | path: RoutesPathName.SIGNUP_PAGE,
11 | index: true,
12 | Component: Register,
13 | },
14 | {
15 | path: RoutesPathName.LOGIN_PAGE,
16 | element: ,
17 | },
18 | {
19 | path: RoutesPathName.ACCOUNT,
20 | element: ,
21 | },
22 | {
23 | path: RoutesPathName.DASHBOARD_PAGE,
24 | element: ,
25 | },
26 | ]);
27 |
28 | function App() {
29 | return ;
30 | }
31 |
32 | export default App;
33 |
--------------------------------------------------------------------------------
/frontend/src/utils/Auth.jsx:
--------------------------------------------------------------------------------
1 | // import React, { createContext, useContext, useState } from "react";
2 |
3 | // const AuthContext = createContext();
4 |
5 | // export const AuthProvider = ({ children }) => {
6 | // const [authToken, setAuthToken] = useState(localStorage.getItem("jwtToken"));
7 |
8 | // const headers = { "content-Type": "application/json" , "Authorization" : authToken }
9 |
10 | // return (
11 | //
12 | // {children}
13 | //
14 | // );
15 | // };
16 |
17 | // export const useAuth = () => useContext(AuthContext);
18 |
19 | import { useState } from "react";
20 |
21 | export const useAuth = () => {
22 | const [authToken, setAuthToken] = useState(localStorage.getItem("jwtToken"));
23 |
24 | const headers = {
25 | "Content-Type": "application/json",
26 | "Authorization": authToken
27 | };
28 |
29 | return { authToken, headers };
30 | };
31 |
32 |
--------------------------------------------------------------------------------
/frontend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "frontend",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite --host",
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 | "bootstrap": "^5.3.2",
14 | "clsx": "^2.0.0",
15 | "react": "^18.2.0",
16 | "react-bootstrap": "^2.9.1",
17 | "react-dom": "^18.2.0",
18 | "react-router-dom": "^6.20.1"
19 | },
20 | "devDependencies": {
21 | "@types/react": "^18.2.37",
22 | "@types/react-dom": "^18.2.15",
23 | "@vitejs/plugin-react": "^4.2.0",
24 | "autoprefixer": "^10.4.16",
25 | "eslint": "^8.53.0",
26 | "eslint-plugin-react": "^7.33.2",
27 | "eslint-plugin-react-hooks": "^4.6.0",
28 | "eslint-plugin-react-refresh": "^0.4.4",
29 | "postcss": "^8.4.32",
30 | "tailwindcss": "^3.3.6",
31 | "vite": "^5.0.0"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/frontend/src/pages/Dashboard.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from "react";
2 | import Navbar from "./Navbar";
3 | import Complaint from "./Complaint";
4 | import WardenComplaints from "./WardenComplaint";
5 | import { GetAuthHeader } from "../testing/Headers";
6 |
7 | function Dashboard() {
8 | const [userType, setUserType] = useState(null);
9 |
10 |
11 | useEffect(() => {
12 |
13 | const fetchUserType = async () => {
14 | try {
15 | const response = await fetch("http://localhost:3000/userType", {
16 | method: "GET",
17 | headers: GetAuthHeader(),
18 | });
19 |
20 | if (response.ok) {
21 | const data = await response.json();
22 | setUserType(data.userType);
23 | } else {
24 | console.error('Failed to fetch user type');
25 | }
26 | } catch (error) {
27 | console.error(error.message);
28 | }
29 | };
30 |
31 | fetchUserType();
32 | }, []);
33 |
34 | return (
35 | <>
36 |
37 | {userType === "student" ? : null}
38 | {userType === "warden" ? : null}
39 | >
40 | );
41 | }
42 |
43 | export default Dashboard;
44 |
--------------------------------------------------------------------------------
/backend/database.sql:
--------------------------------------------------------------------------------
1 | -- new database
2 |
3 | create table if not exists users (
4 | user_id serial primary key not null,
5 | full_name text not null,
6 | email text not null,
7 | phone text not null,
8 | password text not null,
9 | type text not null
10 | );
11 |
12 | create table if not exists block (
13 | block_id serial primary key not null,
14 | block_name text not null
15 | );
16 |
17 | create table if not exists student (
18 | student_id int primary key not null,
19 | block_id int,
20 | usn text ,
21 | room text,
22 | foreign key (student_id) references users(user_id) on delete cascade,
23 | foreign key (block_id) references block(block_id) on delete cascade
24 | );
25 |
26 | create table if not exists warden (
27 | warden_id int primary key not null,
28 | block_id int,
29 | foreign key (warden_id) references users(user_id) on delete cascade,
30 | foreign key (block_id) references block(block_id)
31 | on delete cascade
32 | );
33 |
34 | create table if not exists complaint (
35 | id SERIAL PRIMARY KEY,
36 | name text ,
37 | block_id int,
38 | student_id int ,
39 | description text,
40 | room text,
41 | is_completed BOOLEAN,
42 | created_at timestamp,
43 | assigned_at timestamp,
44 | foreign key (student_id) references student(student_id) on delete cascade,
45 | foreign key (block_id) references block(block_id) on delete cascade
46 | );
47 |
48 |
49 |
--------------------------------------------------------------------------------
/frontend/public/vite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/backend/middleware/auth.js:
--------------------------------------------------------------------------------
1 | const jwt = require("jsonwebtoken");
2 |
3 | const authorizeWarden = async (req, res, next) => {
4 | try {
5 | const token = req.headers.authorization;
6 | console.log("here", req.headers,token);
7 | const decodedToken = jwt.verify(token, process.env.JWTSECRET);
8 | console.log(decodedToken)
9 | if (decodedToken.user.type === "warden") {
10 | return next();
11 | } else {
12 | return res.status(403).json({ error: "only warden can access" });
13 | }
14 |
15 | } catch (err) {
16 | console.error("here1",err.message);
17 | return res.status(401).json({ error: "Unauthorized" });
18 | }
19 | };
20 |
21 | const authorizeStudent = async (req, res, next) => {
22 | try {
23 | const token = req.headers.authorization;
24 | console.log("here", req.headers,token);
25 | const decodedToken = jwt.verify(token, process.env.JWTSECRET);
26 | console.log(decodedToken)
27 | if (decodedToken.user.type === "student") {
28 | return next();
29 | } else {
30 | return res.status(403).json({ error: "Unauthorized for Student" });
31 | }
32 |
33 | } catch (err) {
34 | console.error("here13",err.message);
35 | return res.status(401).json({ error: "Unauthorized" });
36 | }
37 | };
38 |
39 | const authorizeComplaintRoute = async (req, res, next) => {
40 | try {
41 | const token = req.headers.authorization;
42 | console.log("here", req.headers, token);
43 | const decodedToken = jwt.verify(token, process.env.JWTSECRET);
44 | console.log(decodedToken);
45 |
46 | return next();
47 | } catch (err) {
48 | console.error("here11", err.message);
49 | return res.status(401).json({ error: "Unauthorized" });
50 | }
51 | };
52 |
53 |
54 | module.exports = {
55 | authorizeWarden,
56 | authorizeStudent,
57 | authorizeComplaintRoute
58 | };
59 |
--------------------------------------------------------------------------------
/frontend/src/pages/Navbar.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 | import { Link, useNavigate } from "react-router-dom";
3 |
4 | function Navbar() {
5 | const navigate = useNavigate();
6 | const [authToken, setAuthToken] = useState(localStorage.getItem("jwtToken"));
7 |
8 | const logout = () => {
9 | setAuthToken(null);
10 | localStorage.removeItem("jwtToken");
11 | navigate("/login");
12 | };
13 |
14 | return (
15 | <>
16 |
17 |
18 |
19 | SJCE Boy's Hostel
20 |
21 |
22 |
23 | Toggle Navigation
24 |
25 |
26 |
27 |
28 |
32 |
33 |
34 | Account Link>
35 |
36 |
37 |
41 | Logout
42 |
43 |
44 |
45 |
46 |
47 |
48 | >
49 | );
50 | }
51 |
52 | export default Navbar;
53 |
--------------------------------------------------------------------------------
/backend/controller/userController.js:
--------------------------------------------------------------------------------
1 | const express = require("express");
2 | const cors = require("cors");
3 | const app = express();
4 | const db = require("../db");
5 | const bcrypt = require("bcrypt");
6 | const { jwtGenerator, jwtDecoder } = require("../utils/jwtToken");
7 | app.use(cors());
8 | app.use(express.json());
9 |
10 | exports.userRegister = async (req, res) => {
11 | const { full_name, email, phone, password, type } = req.body;
12 |
13 | try {
14 | const user = await db.pool.query("SELECT * FROM users WHERE email = $1", [
15 | email,
16 | ]);
17 |
18 | if (user.rows.length > 0) {
19 | return res.status(401).json("User already exist!");
20 | }
21 |
22 | const salt = await bcrypt.genSalt(10);
23 | const bcryptPassword = await bcrypt.hash(password, salt);
24 |
25 | let newUser = await db.pool.query(
26 | "INSERT INTO users (full_name, email, phone, password, type) VALUES ($1, $2, $3, $4, $5) RETURNING *",
27 | [full_name, email, phone, bcryptPassword, type]
28 | );
29 |
30 | const jwtToken = jwtGenerator(
31 | newUser.rows[0].user_id,
32 | newUser.rows[0].type
33 | );
34 |
35 | if (type === "student") {
36 | const { block_id, usn, room } = req.body;
37 | console.log(newUser.rows);
38 | await db.pool.query(
39 | "INSERT INTO student (student_id, block_id, usn, room) VALUES ($1, $2, $3, $4)",
40 | [newUser.rows[0].user_id, block_id, usn, room]
41 | );
42 | } else if (type === "warden") {
43 | const { block_id } = req.body;
44 | await db.pool.query(
45 | "INSERT INTO warden (warden_id,block_id) VALUES ($1, $2)",
46 | [newUser.rows[0].user_id, block_id]
47 | );
48 | }
49 | console.log(jwtDecoder(jwtToken));
50 | return res.json({ jwtToken });
51 | } catch (err) {
52 | console.error(err.message);
53 | res.status(500).send("Server error");
54 | }
55 | };
56 |
57 | exports.userLogin = async (req, res) => {
58 | const { email, password } = req.body;
59 |
60 | try {
61 | const user = await db.pool.query("SELECT * FROM users WHERE email = $1", [
62 | email,
63 | ]);
64 |
65 | if (user.rows.length === 0) {
66 | return res.status(401).json("Invalid Credential");
67 | }
68 |
69 | const validPassword = await bcrypt.compare(password, user.rows[0].password);
70 |
71 | if (!validPassword) {
72 | return res.status(401).json("Invalid Credential");
73 | }
74 | const jwtToken = jwtGenerator(user.rows[0].user_id, user.rows[0].type);
75 | console.log(jwtDecoder(jwtToken));
76 | return res.json({ jwtToken });
77 | } catch (err) {
78 | console.error(err.message);
79 | res.status(500).send("Server error");
80 | }
81 | };
82 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Hostel Grievance Redressal System
2 |
3 | ## Overview
4 |
5 | The Hostel Grievance Redressal System is a web application that facilitates the submission, tracking, and resolution of grievances raised by hostel residents. The system provides a user-friendly interface for residents to report issues and for administrators to efficiently manage and resolve them.
6 |
7 | ## Features
8 |
9 | - **User-friendly Interface**: Simple and intuitive design for easy grievance submission by residents.
10 |
11 | - **Real-time Updates**: Residents receive real-time updates on the status of their submitted grievances.
12 |
13 | - **Admin Dashboard**: An administrative dashboard to manage and prioritize grievances effectively.
14 |
15 | ## Technology Stack
16 |
17 | - **Frontend**: Built with React.js for a responsive and dynamic user interface. Styled using Tailwind CSS for a modern look and feel.
18 |
19 | - **Backend**: Powered by Node.js and Express.js for server-side development.
20 |
21 | - **Database**: Utilizes PostgreSQL for reliable and scalable data storage.
22 |
23 | ## Styling with Tailwind CSS
24 |
25 | The application's UI is styled using Tailwind CSS.
26 |
27 | ## Component Library
28 |
29 | This project utilizes Component Library Preline, ComponentLand for cards, pages, and other components.
30 |
31 | ## Project Preview
32 |
33 | ### Login Page
34 |
35 | .png)
36 |
37 | ### Signup Page
38 |
39 | .png)
40 |
41 | ### Student Dashboard
42 |
43 | .png)
44 |
45 | ### Student Profile Info
46 |
47 | .png)
48 |
49 | ### Student submitting complaint
50 |
51 | .png)
52 |
53 | ### Student Dashboard after submitting complaint
54 |
55 | .png)
56 |
57 | ### Warden Dashboard
58 |
59 | .png)
60 |
61 | ### Warden Resolves complaint(clicking Not completed changes to Completed)
62 |
63 | .png)
64 |
65 | ### Student Dashboard Updated
66 |
67 | .png)
68 |
69 | ### Schema Diagram
70 |
71 | 
72 |
73 | ## Getting Started
74 |
75 | To run the Hostel Grievance Redressal System locally:
76 |
77 | 1. **Clone the repository:**
78 | ```bash
79 | git clone [repository_url]
80 | ```
81 |
82 | 2. **Navigate to the project directory:**
83 | ```bash
84 | cd [project_directory]
85 | ```
86 |
87 | 3. **Install dependencies:**
88 | ```bash
89 | npm install
90 | ```
91 |
92 | 4. **Configure the database:**
93 | - Set up PostgreSQL and update the database configuration.
94 | - For backend
95 | ```bash
96 | node server.js
97 | ```
98 |
99 | 5. **Run the application:**
100 | ```bash
101 | npm run dev
102 | ```
103 |
104 | ## Contributing
105 |
106 | Contributions are welcome!
107 |
108 |
109 |
110 |
--------------------------------------------------------------------------------
/frontend/src/assets/react.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/frontend/src/pages/WardenComplaint.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from "react";
2 | import { useAuth } from "../utils/Auth";
3 |
4 | const formatTimestamp = (timestamp) => {
5 | const date = new Date(timestamp);
6 | const options = {
7 | year: "numeric",
8 | month: "short",
9 | day: "numeric",
10 | hour: "numeric",
11 | minute: "numeric",
12 | second: "numeric",
13 | };
14 | return new Intl.DateTimeFormat("en-US", options).format(date);
15 | };
16 | const formatTimestamp1 = (timestamp) => {
17 | const date = new Date(timestamp);
18 | const options = {
19 | year: "numeric",
20 | month: "short",
21 | day: "numeric",
22 | };
23 | return new Intl.DateTimeFormat("en-US", options).format(date);
24 | };
25 |
26 | const WardenComplaints = () => {
27 | const { headers } = useAuth();
28 | const [complaints, setComplaints] = useState([]);
29 |
30 | const getComplaints = async (e) => {
31 | try {
32 | const response = await fetch("http://localhost:3000/complaints", {
33 | method: "GET",
34 | headers: headers,
35 | });
36 | const jsonData = await response.json();
37 |
38 | setComplaints(jsonData);
39 | } catch (err) {
40 | console.error(err.message);
41 | }
42 | };
43 |
44 | const handleApproval = async (id) => {
45 | try {
46 | const response = await fetch(`http://localhost:3000/complaints/${id}`, {
47 | method: "POST",
48 | headers: headers,
49 | });
50 |
51 | console.log(response);
52 | window.location = "/";
53 | } catch (err) {
54 | console.error(err.message);
55 | }
56 | };
57 |
58 | useEffect(() => {
59 | getComplaints();
60 | }, []);
61 |
62 | const deleteComplaint = async (id) => {
63 | try {
64 | const response = await fetch(`http://localhost:3000/complaints/${id}`, {
65 | method: "DELETE",
66 | headers: headers,
67 | });
68 |
69 | if (response.ok) {
70 | setComplaints(complaints.filter((complaint) => complaint.id !== id));
71 | } else {
72 | console.error("Failed to delete complaint");
73 | }
74 | } catch (error) {
75 | console.error("Error deleting complaint:", error);
76 | }
77 | };
78 |
79 | return (
80 | <>
81 |
82 |
Complaints
83 | {complaints.length === 0 ? (
84 |
85 | No complaints registered yet.
86 |
87 | ) : (
88 |
89 | {complaints.map((complaint) => (
90 |
94 |
95 | {complaint.name} (Room No.{complaint.room})
96 |
97 |
98 | Created on {formatTimestamp1(complaint.created_at)}
99 |
100 |
101 | {complaint.assigned_at
102 | ? `Completed on ${formatTimestamp(complaint.assigned_at)}`
103 | : null}
104 |
105 |
106 | {complaint.description}
107 |
108 |
109 |
handleApproval(complaint.id)}
114 | >
115 |
116 | {complaint.is_completed ? "Completed" : "Not Completed"}
117 |
118 |
119 |
120 |
deleteComplaint(complaint.id)}
123 | >
124 |
128 | Delete
129 |
130 |
131 |
132 |
133 | ))}
134 |
135 | )}
136 |
137 | >
138 | );
139 | };
140 |
141 | export default WardenComplaints;
142 |
--------------------------------------------------------------------------------
/frontend/src/pages/AccountPage.jsx:
--------------------------------------------------------------------------------
1 | import Navbar from "./Navbar";
2 | import { useState, useEffect } from "react";
3 | import { useAuth } from "../utils/Auth";
4 | import { Link } from "react-router-dom";
5 |
6 | function AccountPage() {
7 | const { headers } = useAuth();
8 | const [userName, setUserName] = useState("");
9 | const [useremail, setemail] = useState("");
10 | const [userphone, setphone] = useState("");
11 | const [userUsn, setUsn] = useState("");
12 | const [userRoom, setRoom] = useState("");
13 | const [userblockID, setblockID] = useState("");
14 | const [userblockname, setblockname] = useState("");
15 | const [userType, setUserType] = useState(null);
16 |
17 | useEffect(() => {
18 | const fetchUserType = async () => {
19 | try {
20 | const response = await fetch("http://localhost:3000/userType", {
21 | method: "GET",
22 | headers: headers,
23 | });
24 |
25 | if (response.ok) {
26 | const data = await response.json();
27 | setUserType(data.userType);
28 | console.log(data.userType);
29 | } else {
30 | console.error("Failed to fetch user type");
31 | }
32 | } catch (error) {
33 | console.error(error.message);
34 | }
35 | };
36 |
37 | fetchUserType();
38 | }, []);
39 |
40 | const getuserDetails = async (user_id) => {
41 | try {
42 | const response = await fetch(
43 | `http://localhost:3000/userDetails/${user_id}`,
44 | {
45 | method: "GET",
46 | headers: headers,
47 | }
48 | );
49 | const data = await response.json();
50 | console.log(data);
51 | setUserName(data[0].full_name);
52 | setemail(data[0].email);
53 | setphone(data[0].phone);
54 | setUsn(data[0].usn);
55 | setRoom(data[0].room);
56 | setblockID(data[0].block_id);
57 | setblockname(data[0].block_name);
58 | } catch (err) {
59 | console.error(err.message);
60 | }
61 | };
62 |
63 | useEffect(() => {
64 | getuserDetails();
65 | }, []);
66 |
67 | return (
68 | <>
69 |
70 | Profile
71 |
72 |
73 |
74 |
75 | Name
76 | {userName}
77 |
78 |
79 |
80 |
81 | Email
82 | {useremail}
83 |
84 |
85 |
86 |
87 | Phone
88 | {userphone}
89 |
90 |
91 | {userType !== "warden" && (
92 | <>
93 |
94 |
95 | USN
96 | {userUsn}
97 |
98 |
99 |
100 |
101 | Block ID
102 | {userblockID}
103 |
104 |
105 |
106 |
107 | Block Name
108 | {userblockname}
109 |
110 |
111 |
112 |
113 | Room
114 | {userRoom}
115 |
116 |
117 | >
118 | )}
119 |
120 |
121 |
125 | Back
126 |
127 |
128 | >
129 | );
130 | }
131 |
132 | export default AccountPage;
133 |
--------------------------------------------------------------------------------
/backend/controller/complaintController.js:
--------------------------------------------------------------------------------
1 | const express = require("express");
2 | const cors = require("cors");
3 | const app = express();
4 | const db = require("../db");
5 | const { jwtGenerator, jwtDecoder } = require("../utils/jwtToken");
6 |
7 | app.use(cors());
8 | app.use(express.json());
9 |
10 | const decodeUser = async (token) => {
11 | try {
12 | const decodedToken = jwtDecoder(token);
13 | console.log(decodedToken);
14 |
15 | const { user_id, type } = decodedToken.user;
16 | let userInfo;
17 |
18 | if (type === "student") {
19 | const query = `
20 | SELECT student_id, room, block_id
21 | FROM student
22 | WHERE student_id = $1
23 | `;
24 |
25 | const result = await db.pool.query(query, [user_id]);
26 | console.log(result.rows);
27 | if (result.rows.length > 0) {
28 | userInfo = result.rows[0];
29 | }
30 | }
31 |
32 | if (type === "warden") {
33 | const query = `
34 | SELECT warden_id, block_id
35 | FROM warden
36 | WHERE warden_id = $1
37 | `;
38 |
39 | const result = await db.pool.query(query, [user_id]);
40 |
41 | if (result.rows.length > 0) {
42 | userInfo = result.rows[0];
43 | }
44 | }
45 |
46 | return userInfo;
47 | } catch (err) {
48 | console.error("here111", err.message);
49 | }
50 | };
51 |
52 | exports.postComplaints = async (req, res) => {
53 | try {
54 | const token = req.headers.authorization;
55 | console.log(token);
56 | const userInfo = await decodeUser(token);
57 |
58 | const { student_id, block_id } = userInfo;
59 |
60 | const { name, description, room, is_completed, assigned_at } = req.body;
61 |
62 | const query = `insert into complaint
63 | (name, block_id,
64 | student_id,
65 | description, room, is_completed, created_at,
66 | assigned_at)
67 | values ($1,$2,$3,$4,$5,$6,$7,$8) returning *`;
68 |
69 | const newComplaint = await db.pool.query(query, [
70 | name,
71 | block_id,
72 | student_id,
73 | description,
74 | room,
75 | false,
76 | new Date().toISOString(),
77 | null,
78 | ]);
79 | res.json(newComplaint.rows[0]);
80 | } catch (err) {
81 | console.log(err.message);
82 | }
83 | };
84 |
85 | exports.putComplaintsByid = async (req, res) => {
86 | const token = req.headers.authorization;
87 | const decodedToken = jwtDecoder(token);
88 | console.log(decodedToken);
89 | const { user_id, type } = decodedToken.user;
90 |
91 | try {
92 | const { id } = req.params;
93 |
94 | if (type === "warden") {
95 | const result = await db.pool.query(
96 | "UPDATE complaint SET is_completed = NOT is_completed, assigned_at = CURRENT_TIMESTAMP WHERE id = $1 RETURNING *",
97 | [id]
98 | );
99 | res.json(result.rows[0]);
100 | } else {
101 | res.status(404).json({ error: "Complaint not found" });
102 | }
103 | } catch (err) {
104 | console.log(err.message);
105 | res.status(500).json({ error: "Internal Server Error" });
106 | }
107 | };
108 |
109 | exports.getAllComplaintsByUser = async (req, res) => {
110 | const token = req.headers.authorization;
111 | console.log(token);
112 | const decodedToken = jwtDecoder(token);
113 | console.log(decodedToken);
114 |
115 | const { user_id, type } = decodedToken.user;
116 |
117 | try {
118 | if (type === "warden") {
119 | const allComplaints = await db.pool.query(
120 | "SELECT * FROM complaint ORDER BY created_at DESC"
121 | );
122 | res.json(allComplaints.rows);
123 | } else if (type === "student") {
124 | const myComplaints = await db.pool.query(
125 | "SELECT * FROM complaint WHERE student_id = $1 ORDER BY created_at DESC",
126 | [user_id]
127 | );
128 | res.json(myComplaints.rows);
129 | } else {
130 | res.status(403).json({ error: "Unauthorized" });
131 | }
132 | } catch (err) {
133 | console.error(err.message);
134 | res.status(500).json({ error: "Internal Server Error" });
135 | }
136 | };
137 |
138 | exports.getUserType = async (req, res) => {
139 | try {
140 | const token = req.headers.authorization;
141 | console.log(token);
142 | const decodedToken = jwtDecoder(token);
143 | console.log(decodedToken);
144 | const { type } = decodedToken.user;
145 |
146 | res.json({ userType: type });
147 | } catch (err) {
148 | console.error(err.message);
149 | res.status(500).json({ error: "Internal Server Error" });
150 | }
151 | };
152 |
153 | exports.getUserDetails = async (req, res) => {
154 | try {
155 | const token = req.headers.authorization;
156 | console.log(token);
157 | const decodedToken = jwtDecoder(token);
158 | console.log(decodedToken);
159 | const { user_id, type } = decodedToken.user;
160 |
161 | console.log("Decoded Token:", decodedToken);
162 |
163 | console.log("User Type:", type);
164 |
165 | console.log("User ID:", user_id);
166 |
167 | if (type == "student") {
168 | const studentDetails = await db.pool.query(
169 | `SELECT u.full_name, u.email, u.phone, s.usn, b.block_id, b.block_name, s.room
170 | FROM users u, student s, block b
171 | WHERE u.user_id = $1 AND u.user_id = s.student_id AND s.block_id = b.block_id`,
172 | [user_id]
173 | );
174 | res.json(studentDetails.rows);
175 | }
176 | if (type == "warden") {
177 | const wardenDetails = await db.pool.query(
178 | `select u.full_name,u.email,u.phone
179 | from users u
180 | where user_id=$1 `,
181 | [user_id]
182 | );
183 | res.json(wardenDetails.rows);
184 | }
185 | } catch (err) {
186 | console.error(err.message);
187 | res.status(500).json({ error: "Internal Server Error" });
188 | }
189 | };
190 |
191 | exports.deleteComplaints = async (req, res) => {
192 | try {
193 | const token = req.headers.authorization;
194 | console.log(token);
195 | const decodedToken = jwtDecoder(token);
196 | console.log(decodedToken);
197 | const { type } = decodedToken.user;
198 | const { id } = req.params;
199 |
200 | if (type == "warden") {
201 | const deleteComplaint = await db.pool.query(
202 | `delete from complaint where id = $1`,
203 | [id]
204 | );
205 | res.json("complaint deleted");
206 | }
207 | } catch (err) {
208 | console.log(err.message);
209 | res.status(500).json({ error: "Internal Server Error" });
210 | }
211 | };
212 |
--------------------------------------------------------------------------------
/frontend/src/pages/Login.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 | import { Link, useNavigate } from "react-router-dom";
3 |
4 | function Login() {
5 | const navigate = useNavigate();
6 | const [email, setEmail] = useState("");
7 | const [password, setPassword] = useState("");
8 |
9 | const onSubmit = async (e) => {
10 | e.preventDefault();
11 |
12 | try {
13 | const body = { email, password };
14 | const response = await fetch("http://localhost:3000/login", {
15 | method: "POST",
16 | headers: { "content-type": "application/json" },
17 | body: JSON.stringify(body),
18 | });
19 | console.log(response);
20 | const data = await response.json();
21 | console.log(data);
22 |
23 | if (data.jwtToken) {
24 | localStorage.setItem("jwtToken", data.jwtToken);
25 | navigate("/");
26 | } else {
27 | alert("Invalid credentials. Please check your email and password.");
28 | }
29 | } catch (err) {
30 | console.log(err.message);
31 | }
32 | };
33 |
34 | return (
35 | <>
36 |
37 |
38 |
39 |
45 |
46 |
53 |
54 |
60 |
61 |
62 |
68 |
69 |
70 |
71 |
77 |
78 |
85 |
86 |
92 |
93 |
94 |
100 |
101 |
102 |
103 |
104 |
114 | {/* /Logo */}
115 |
116 | Welcome!
117 |
118 |
119 | Please sign-in to access your account
120 |
121 |
169 |
170 | Don't have an account yet?
171 |
175 | {" "}
176 | Create an account{" "}
177 |
178 |
179 |
180 |
181 |
182 |
183 | >
184 | );
185 | }
186 |
187 | export default Login;
188 |
--------------------------------------------------------------------------------
/frontend/src/pages/Complaint.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from "react";
2 | import { useAuth } from "../utils/Auth";
3 |
4 | const formatTimestamp = (timestamp) => {
5 | const date = new Date(timestamp);
6 | const options = {
7 | year: "numeric",
8 | month: "short",
9 | day: "numeric",
10 | hour: "numeric",
11 | minute: "numeric",
12 | second: "numeric",
13 | };
14 | return new Intl.DateTimeFormat("en-US", options).format(date);
15 | };
16 |
17 | const formatTimestamp1 = (timestamp) => {
18 | const date = new Date(timestamp);
19 | const options = {
20 | year: "numeric",
21 | month: "short",
22 | day: "numeric",
23 | };
24 | return new Intl.DateTimeFormat("en-US", options).format(date);
25 | };
26 |
27 | const ComplaintForm = () => {
28 | const { authToken, headers } = useAuth();
29 | const [name, setName] = useState("");
30 | const [description, setDescription] = useState("");
31 | const [room, setRoom] = useState("");
32 |
33 | const onSubmitForm = async (e) => {
34 | e.preventDefault();
35 |
36 | if (!name || name.trim() === "") {
37 | alert("Please enter a valid name.");
38 | return;
39 | }
40 | if (!room || room.trim() === "") {
41 | alert("Please enter Room No.");
42 | return;
43 | }
44 | if (!description || description.trim() === "") {
45 | alert("Please enter a valid complaint.");
46 | return;
47 | }
48 |
49 | try {
50 | const body = { name, description, room };
51 | const response = await fetch("http://localhost:3000/complaints", {
52 | method: "POST",
53 | headers: headers,
54 | body: JSON.stringify(body),
55 | });
56 | window.location = "/";
57 | } catch (err) {
58 | console.error(err.message);
59 | }
60 | };
61 |
62 | return (
63 | <>
64 |
65 |
66 |
67 |
Hostel Grievance Redressal
68 |
Submit Your Grievance
69 |
70 | Hostel Grievance Redressal ensures a swift and confidential
71 | resolution of student concerns. We guarantee a quick response to
72 | submitted complaints, fostering a secure and comfortable living
73 | environment for all hostel residents.
74 |
75 |
76 |
92 |
93 |
Swift Grievance Resolution
94 |
95 | Swift grievance resolution prioritizes timely and effective
96 | solutions, ensuring students' concerns are promptly addressed
97 | and resolved.
98 |
99 |
100 |
101 |
102 |
118 |
119 |
Confidentiality Assured
120 |
121 | Your grievances are handled with utmost confidentiality,
122 | ensuring privacy and trust throughout the hostel grievance
123 | redressal process .
124 |
125 |
126 |
127 |
128 |
144 |
145 |
Easy Communication
146 |
147 | Effortless communication is facilitated, providing a smooth
148 | and accessible channel for expressing and resolving grievances
149 | within the hostel community.
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 | Submit Complaint
158 |
159 | Quick Response
160 |
161 |
162 |
163 | Contact us for hostel grievance redressal
164 |
165 |
166 |
167 | setName(e.target.value)}
173 | />
174 | setRoom(e.target.value)}
180 | />
181 |
182 | Tell us about your grievance
183 |
184 |
189 |
193 | Submit
194 |
195 |
196 |
197 |
198 |
199 | >
200 | );
201 | };
202 |
203 | const Complaint = () => {
204 | const { headers } = useAuth();
205 | const [complaints, setComplaints] = useState([]);
206 |
207 | const getComplaints = async (e) => {
208 | try {
209 | const response = await fetch("http://localhost:3000/complaints", {
210 | method: "GET",
211 | headers: headers,
212 | });
213 | const jsonData = await response.json();
214 |
215 | setComplaints(jsonData);
216 | } catch (err) {
217 | console.error(err.message);
218 | }
219 | };
220 |
221 | useEffect(() => {
222 | getComplaints();
223 | }, []);
224 |
225 | console.log(complaints);
226 |
227 | return (
228 | <>
229 |
230 |
Complaints
231 | {complaints.length === 0 ? (
232 |
233 | No complaints registered yet.
234 |
235 | ) : (
236 |
237 | {complaints.map((complaint) => (
238 |
242 |
243 | {complaint.name}
244 |
245 |
246 | Created on {formatTimestamp1(complaint.created_at)}
247 |
248 |
249 | {complaint.assigned_at
250 | ? `Completed on ${formatTimestamp(complaint.assigned_at)}`
251 | : null}
252 |
253 |
257 | {complaint.description}
258 |
259 |
264 |
265 | {complaint.is_completed ? "Completed" : "Not Completed"}
266 |
267 |
268 |
269 | ))}
270 |
271 | )}
272 |
273 |
274 |
275 | >
276 | );
277 | };
278 |
279 | export default Complaint;
280 |
--------------------------------------------------------------------------------
/frontend/src/pages/Register.jsx:
--------------------------------------------------------------------------------
1 | import { useNavigate, Link } from "react-router-dom";
2 | import { Roles } from "../constants";
3 | import { useState } from "react";
4 |
5 | function Register() {
6 | const navigate = useNavigate()
7 | const [fullname, setFullname] = useState("");
8 | const [email, setEmail] = useState("");
9 | const [password, setPassword] = useState("");
10 | const [phone, setPhone] = useState("");
11 | const [role, setRole] = useState(Roles.STUDENT);
12 | const [block_id, setBlock_id] = useState("");
13 | const [usn, setUsn] = useState("");
14 | const [room, setRoom] = useState("");
15 |
16 | const onSubmit = async (e) => {
17 | e.preventDefault();
18 | try {
19 | let body;
20 | if (role === Roles.WARDEN) {
21 | body = {
22 | full_name: fullname,
23 | email,
24 | password,
25 | phone,
26 | type: role,
27 | block_id,
28 | };
29 | } else {
30 | body = {
31 | full_name: fullname,
32 | email,
33 | password,
34 | phone,
35 | type: role,
36 | block_id,
37 | usn,
38 | room,
39 | };
40 | }
41 | const response = await fetch("http://localhost:3000/register", {
42 | method: "POST",
43 | headers: { "content-type": "application/json " },
44 | body: JSON.stringify(body),
45 | });
46 | console.log(response);
47 | const data = await response.json();
48 | console.log(data);
49 | if (data.jwtToken) {
50 | alert("User registered successfully,login to proceed");
51 | navigate('/login')
52 | } else {
53 | alert("user already exists");
54 | }
55 | } catch (err) {
56 | console.log(err.message);
57 | }
58 | };
59 |
60 | return (
61 | <>
62 |
63 |
64 |
65 |
71 |
72 |
79 |
80 |
86 |
87 |
88 |
94 |
95 |
96 |
97 |
103 |
104 |
111 |
112 |
118 |
119 |
120 |
126 |
127 |
128 |
129 |
130 |
131 |
141 |
142 |
143 | Welcome!
144 |
145 |
146 | Please sign-in to access your account
147 |
148 |
149 |
323 |
324 |
325 | Already have an account?
326 |
330 | {" "}
331 | Login{" "}
332 |
333 |
334 |
335 |
336 |
337 |
338 | >
339 | );
340 | }
341 |
342 | export default Register;
343 |
--------------------------------------------------------------------------------
/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 | "express-async-handler": "^1.2.0",
18 | "jsonwebtoken": "^9.0.2",
19 | "nodemon": "^3.0.2",
20 | "pg": "^8.11.3"
21 | }
22 | },
23 | "node_modules/@mapbox/node-pre-gyp": {
24 | "version": "1.0.11",
25 | "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz",
26 | "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==",
27 | "dependencies": {
28 | "detect-libc": "^2.0.0",
29 | "https-proxy-agent": "^5.0.0",
30 | "make-dir": "^3.1.0",
31 | "node-fetch": "^2.6.7",
32 | "nopt": "^5.0.0",
33 | "npmlog": "^5.0.1",
34 | "rimraf": "^3.0.2",
35 | "semver": "^7.3.5",
36 | "tar": "^6.1.11"
37 | },
38 | "bin": {
39 | "node-pre-gyp": "bin/node-pre-gyp"
40 | }
41 | },
42 | "node_modules/@mapbox/node-pre-gyp/node_modules/nopt": {
43 | "version": "5.0.0",
44 | "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
45 | "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
46 | "dependencies": {
47 | "abbrev": "1"
48 | },
49 | "bin": {
50 | "nopt": "bin/nopt.js"
51 | },
52 | "engines": {
53 | "node": ">=6"
54 | }
55 | },
56 | "node_modules/abbrev": {
57 | "version": "1.1.1",
58 | "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
59 | "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
60 | },
61 | "node_modules/accepts": {
62 | "version": "1.3.8",
63 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
64 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
65 | "dependencies": {
66 | "mime-types": "~2.1.34",
67 | "negotiator": "0.6.3"
68 | },
69 | "engines": {
70 | "node": ">= 0.6"
71 | }
72 | },
73 | "node_modules/agent-base": {
74 | "version": "6.0.2",
75 | "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
76 | "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
77 | "dependencies": {
78 | "debug": "4"
79 | },
80 | "engines": {
81 | "node": ">= 6.0.0"
82 | }
83 | },
84 | "node_modules/agent-base/node_modules/debug": {
85 | "version": "4.3.4",
86 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
87 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
88 | "dependencies": {
89 | "ms": "2.1.2"
90 | },
91 | "engines": {
92 | "node": ">=6.0"
93 | },
94 | "peerDependenciesMeta": {
95 | "supports-color": {
96 | "optional": true
97 | }
98 | }
99 | },
100 | "node_modules/agent-base/node_modules/ms": {
101 | "version": "2.1.2",
102 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
103 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
104 | },
105 | "node_modules/ansi-regex": {
106 | "version": "5.0.1",
107 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
108 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
109 | "engines": {
110 | "node": ">=8"
111 | }
112 | },
113 | "node_modules/anymatch": {
114 | "version": "3.1.3",
115 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
116 | "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
117 | "dependencies": {
118 | "normalize-path": "^3.0.0",
119 | "picomatch": "^2.0.4"
120 | },
121 | "engines": {
122 | "node": ">= 8"
123 | }
124 | },
125 | "node_modules/aproba": {
126 | "version": "2.0.0",
127 | "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz",
128 | "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ=="
129 | },
130 | "node_modules/are-we-there-yet": {
131 | "version": "2.0.0",
132 | "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz",
133 | "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==",
134 | "dependencies": {
135 | "delegates": "^1.0.0",
136 | "readable-stream": "^3.6.0"
137 | },
138 | "engines": {
139 | "node": ">=10"
140 | }
141 | },
142 | "node_modules/array-flatten": {
143 | "version": "1.1.1",
144 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
145 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
146 | },
147 | "node_modules/balanced-match": {
148 | "version": "1.0.2",
149 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
150 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
151 | },
152 | "node_modules/bcrypt": {
153 | "version": "5.1.1",
154 | "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.1.tgz",
155 | "integrity": "sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww==",
156 | "hasInstallScript": true,
157 | "dependencies": {
158 | "@mapbox/node-pre-gyp": "^1.0.11",
159 | "node-addon-api": "^5.0.0"
160 | },
161 | "engines": {
162 | "node": ">= 10.0.0"
163 | }
164 | },
165 | "node_modules/binary-extensions": {
166 | "version": "2.2.0",
167 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
168 | "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
169 | "engines": {
170 | "node": ">=8"
171 | }
172 | },
173 | "node_modules/body-parser": {
174 | "version": "1.20.1",
175 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
176 | "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
177 | "dependencies": {
178 | "bytes": "3.1.2",
179 | "content-type": "~1.0.4",
180 | "debug": "2.6.9",
181 | "depd": "2.0.0",
182 | "destroy": "1.2.0",
183 | "http-errors": "2.0.0",
184 | "iconv-lite": "0.4.24",
185 | "on-finished": "2.4.1",
186 | "qs": "6.11.0",
187 | "raw-body": "2.5.1",
188 | "type-is": "~1.6.18",
189 | "unpipe": "1.0.0"
190 | },
191 | "engines": {
192 | "node": ">= 0.8",
193 | "npm": "1.2.8000 || >= 1.4.16"
194 | }
195 | },
196 | "node_modules/brace-expansion": {
197 | "version": "1.1.11",
198 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
199 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
200 | "dependencies": {
201 | "balanced-match": "^1.0.0",
202 | "concat-map": "0.0.1"
203 | }
204 | },
205 | "node_modules/braces": {
206 | "version": "3.0.2",
207 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
208 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
209 | "dependencies": {
210 | "fill-range": "^7.0.1"
211 | },
212 | "engines": {
213 | "node": ">=8"
214 | }
215 | },
216 | "node_modules/buffer-equal-constant-time": {
217 | "version": "1.0.1",
218 | "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
219 | "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
220 | },
221 | "node_modules/buffer-writer": {
222 | "version": "2.0.0",
223 | "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz",
224 | "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==",
225 | "engines": {
226 | "node": ">=4"
227 | }
228 | },
229 | "node_modules/bytes": {
230 | "version": "3.1.2",
231 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
232 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
233 | "engines": {
234 | "node": ">= 0.8"
235 | }
236 | },
237 | "node_modules/call-bind": {
238 | "version": "1.0.5",
239 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz",
240 | "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==",
241 | "dependencies": {
242 | "function-bind": "^1.1.2",
243 | "get-intrinsic": "^1.2.1",
244 | "set-function-length": "^1.1.1"
245 | },
246 | "funding": {
247 | "url": "https://github.com/sponsors/ljharb"
248 | }
249 | },
250 | "node_modules/chokidar": {
251 | "version": "3.5.3",
252 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
253 | "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
254 | "funding": [
255 | {
256 | "type": "individual",
257 | "url": "https://paulmillr.com/funding/"
258 | }
259 | ],
260 | "dependencies": {
261 | "anymatch": "~3.1.2",
262 | "braces": "~3.0.2",
263 | "glob-parent": "~5.1.2",
264 | "is-binary-path": "~2.1.0",
265 | "is-glob": "~4.0.1",
266 | "normalize-path": "~3.0.0",
267 | "readdirp": "~3.6.0"
268 | },
269 | "engines": {
270 | "node": ">= 8.10.0"
271 | },
272 | "optionalDependencies": {
273 | "fsevents": "~2.3.2"
274 | }
275 | },
276 | "node_modules/chownr": {
277 | "version": "2.0.0",
278 | "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
279 | "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
280 | "engines": {
281 | "node": ">=10"
282 | }
283 | },
284 | "node_modules/color-support": {
285 | "version": "1.1.3",
286 | "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
287 | "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
288 | "bin": {
289 | "color-support": "bin.js"
290 | }
291 | },
292 | "node_modules/concat-map": {
293 | "version": "0.0.1",
294 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
295 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
296 | },
297 | "node_modules/console-control-strings": {
298 | "version": "1.1.0",
299 | "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
300 | "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ=="
301 | },
302 | "node_modules/content-disposition": {
303 | "version": "0.5.4",
304 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
305 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
306 | "dependencies": {
307 | "safe-buffer": "5.2.1"
308 | },
309 | "engines": {
310 | "node": ">= 0.6"
311 | }
312 | },
313 | "node_modules/content-type": {
314 | "version": "1.0.5",
315 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
316 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
317 | "engines": {
318 | "node": ">= 0.6"
319 | }
320 | },
321 | "node_modules/cookie": {
322 | "version": "0.5.0",
323 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
324 | "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
325 | "engines": {
326 | "node": ">= 0.6"
327 | }
328 | },
329 | "node_modules/cookie-parser": {
330 | "version": "1.4.6",
331 | "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz",
332 | "integrity": "sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==",
333 | "dependencies": {
334 | "cookie": "0.4.1",
335 | "cookie-signature": "1.0.6"
336 | },
337 | "engines": {
338 | "node": ">= 0.8.0"
339 | }
340 | },
341 | "node_modules/cookie-parser/node_modules/cookie": {
342 | "version": "0.4.1",
343 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
344 | "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==",
345 | "engines": {
346 | "node": ">= 0.6"
347 | }
348 | },
349 | "node_modules/cookie-signature": {
350 | "version": "1.0.6",
351 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
352 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
353 | },
354 | "node_modules/cors": {
355 | "version": "2.8.5",
356 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
357 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
358 | "dependencies": {
359 | "object-assign": "^4",
360 | "vary": "^1"
361 | },
362 | "engines": {
363 | "node": ">= 0.10"
364 | }
365 | },
366 | "node_modules/debug": {
367 | "version": "2.6.9",
368 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
369 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
370 | "dependencies": {
371 | "ms": "2.0.0"
372 | }
373 | },
374 | "node_modules/define-data-property": {
375 | "version": "1.1.1",
376 | "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz",
377 | "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==",
378 | "dependencies": {
379 | "get-intrinsic": "^1.2.1",
380 | "gopd": "^1.0.1",
381 | "has-property-descriptors": "^1.0.0"
382 | },
383 | "engines": {
384 | "node": ">= 0.4"
385 | }
386 | },
387 | "node_modules/delegates": {
388 | "version": "1.0.0",
389 | "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
390 | "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ=="
391 | },
392 | "node_modules/depd": {
393 | "version": "2.0.0",
394 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
395 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
396 | "engines": {
397 | "node": ">= 0.8"
398 | }
399 | },
400 | "node_modules/destroy": {
401 | "version": "1.2.0",
402 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
403 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
404 | "engines": {
405 | "node": ">= 0.8",
406 | "npm": "1.2.8000 || >= 1.4.16"
407 | }
408 | },
409 | "node_modules/detect-libc": {
410 | "version": "2.0.2",
411 | "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz",
412 | "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==",
413 | "engines": {
414 | "node": ">=8"
415 | }
416 | },
417 | "node_modules/dotenv": {
418 | "version": "16.3.1",
419 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz",
420 | "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==",
421 | "engines": {
422 | "node": ">=12"
423 | },
424 | "funding": {
425 | "url": "https://github.com/motdotla/dotenv?sponsor=1"
426 | }
427 | },
428 | "node_modules/ecdsa-sig-formatter": {
429 | "version": "1.0.11",
430 | "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
431 | "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
432 | "dependencies": {
433 | "safe-buffer": "^5.0.1"
434 | }
435 | },
436 | "node_modules/ee-first": {
437 | "version": "1.1.1",
438 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
439 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
440 | },
441 | "node_modules/emoji-regex": {
442 | "version": "8.0.0",
443 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
444 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
445 | },
446 | "node_modules/encodeurl": {
447 | "version": "1.0.2",
448 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
449 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
450 | "engines": {
451 | "node": ">= 0.8"
452 | }
453 | },
454 | "node_modules/escape-html": {
455 | "version": "1.0.3",
456 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
457 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
458 | },
459 | "node_modules/etag": {
460 | "version": "1.8.1",
461 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
462 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
463 | "engines": {
464 | "node": ">= 0.6"
465 | }
466 | },
467 | "node_modules/express": {
468 | "version": "4.18.2",
469 | "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
470 | "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==",
471 | "dependencies": {
472 | "accepts": "~1.3.8",
473 | "array-flatten": "1.1.1",
474 | "body-parser": "1.20.1",
475 | "content-disposition": "0.5.4",
476 | "content-type": "~1.0.4",
477 | "cookie": "0.5.0",
478 | "cookie-signature": "1.0.6",
479 | "debug": "2.6.9",
480 | "depd": "2.0.0",
481 | "encodeurl": "~1.0.2",
482 | "escape-html": "~1.0.3",
483 | "etag": "~1.8.1",
484 | "finalhandler": "1.2.0",
485 | "fresh": "0.5.2",
486 | "http-errors": "2.0.0",
487 | "merge-descriptors": "1.0.1",
488 | "methods": "~1.1.2",
489 | "on-finished": "2.4.1",
490 | "parseurl": "~1.3.3",
491 | "path-to-regexp": "0.1.7",
492 | "proxy-addr": "~2.0.7",
493 | "qs": "6.11.0",
494 | "range-parser": "~1.2.1",
495 | "safe-buffer": "5.2.1",
496 | "send": "0.18.0",
497 | "serve-static": "1.15.0",
498 | "setprototypeof": "1.2.0",
499 | "statuses": "2.0.1",
500 | "type-is": "~1.6.18",
501 | "utils-merge": "1.0.1",
502 | "vary": "~1.1.2"
503 | },
504 | "engines": {
505 | "node": ">= 0.10.0"
506 | }
507 | },
508 | "node_modules/express-async-handler": {
509 | "version": "1.2.0",
510 | "resolved": "https://registry.npmjs.org/express-async-handler/-/express-async-handler-1.2.0.tgz",
511 | "integrity": "sha512-rCSVtPXRmQSW8rmik/AIb2P0op6l7r1fMW538yyvTMltCO4xQEWMmobfrIxN2V1/mVrgxB8Az3reYF6yUZw37w=="
512 | },
513 | "node_modules/fill-range": {
514 | "version": "7.0.1",
515 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
516 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
517 | "dependencies": {
518 | "to-regex-range": "^5.0.1"
519 | },
520 | "engines": {
521 | "node": ">=8"
522 | }
523 | },
524 | "node_modules/finalhandler": {
525 | "version": "1.2.0",
526 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
527 | "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
528 | "dependencies": {
529 | "debug": "2.6.9",
530 | "encodeurl": "~1.0.2",
531 | "escape-html": "~1.0.3",
532 | "on-finished": "2.4.1",
533 | "parseurl": "~1.3.3",
534 | "statuses": "2.0.1",
535 | "unpipe": "~1.0.0"
536 | },
537 | "engines": {
538 | "node": ">= 0.8"
539 | }
540 | },
541 | "node_modules/forwarded": {
542 | "version": "0.2.0",
543 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
544 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
545 | "engines": {
546 | "node": ">= 0.6"
547 | }
548 | },
549 | "node_modules/fresh": {
550 | "version": "0.5.2",
551 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
552 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
553 | "engines": {
554 | "node": ">= 0.6"
555 | }
556 | },
557 | "node_modules/fs-minipass": {
558 | "version": "2.1.0",
559 | "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
560 | "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
561 | "dependencies": {
562 | "minipass": "^3.0.0"
563 | },
564 | "engines": {
565 | "node": ">= 8"
566 | }
567 | },
568 | "node_modules/fs-minipass/node_modules/minipass": {
569 | "version": "3.3.6",
570 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
571 | "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
572 | "dependencies": {
573 | "yallist": "^4.0.0"
574 | },
575 | "engines": {
576 | "node": ">=8"
577 | }
578 | },
579 | "node_modules/fs.realpath": {
580 | "version": "1.0.0",
581 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
582 | "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
583 | },
584 | "node_modules/fsevents": {
585 | "version": "2.3.3",
586 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
587 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
588 | "hasInstallScript": true,
589 | "optional": true,
590 | "os": [
591 | "darwin"
592 | ],
593 | "engines": {
594 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
595 | }
596 | },
597 | "node_modules/function-bind": {
598 | "version": "1.1.2",
599 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
600 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
601 | "funding": {
602 | "url": "https://github.com/sponsors/ljharb"
603 | }
604 | },
605 | "node_modules/gauge": {
606 | "version": "3.0.2",
607 | "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz",
608 | "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==",
609 | "dependencies": {
610 | "aproba": "^1.0.3 || ^2.0.0",
611 | "color-support": "^1.1.2",
612 | "console-control-strings": "^1.0.0",
613 | "has-unicode": "^2.0.1",
614 | "object-assign": "^4.1.1",
615 | "signal-exit": "^3.0.0",
616 | "string-width": "^4.2.3",
617 | "strip-ansi": "^6.0.1",
618 | "wide-align": "^1.1.2"
619 | },
620 | "engines": {
621 | "node": ">=10"
622 | }
623 | },
624 | "node_modules/get-intrinsic": {
625 | "version": "1.2.2",
626 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz",
627 | "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==",
628 | "dependencies": {
629 | "function-bind": "^1.1.2",
630 | "has-proto": "^1.0.1",
631 | "has-symbols": "^1.0.3",
632 | "hasown": "^2.0.0"
633 | },
634 | "funding": {
635 | "url": "https://github.com/sponsors/ljharb"
636 | }
637 | },
638 | "node_modules/glob": {
639 | "version": "7.2.3",
640 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
641 | "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
642 | "dependencies": {
643 | "fs.realpath": "^1.0.0",
644 | "inflight": "^1.0.4",
645 | "inherits": "2",
646 | "minimatch": "^3.1.1",
647 | "once": "^1.3.0",
648 | "path-is-absolute": "^1.0.0"
649 | },
650 | "engines": {
651 | "node": "*"
652 | },
653 | "funding": {
654 | "url": "https://github.com/sponsors/isaacs"
655 | }
656 | },
657 | "node_modules/glob-parent": {
658 | "version": "5.1.2",
659 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
660 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
661 | "dependencies": {
662 | "is-glob": "^4.0.1"
663 | },
664 | "engines": {
665 | "node": ">= 6"
666 | }
667 | },
668 | "node_modules/gopd": {
669 | "version": "1.0.1",
670 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
671 | "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
672 | "dependencies": {
673 | "get-intrinsic": "^1.1.3"
674 | },
675 | "funding": {
676 | "url": "https://github.com/sponsors/ljharb"
677 | }
678 | },
679 | "node_modules/has-flag": {
680 | "version": "3.0.0",
681 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
682 | "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
683 | "engines": {
684 | "node": ">=4"
685 | }
686 | },
687 | "node_modules/has-property-descriptors": {
688 | "version": "1.0.1",
689 | "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz",
690 | "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==",
691 | "dependencies": {
692 | "get-intrinsic": "^1.2.2"
693 | },
694 | "funding": {
695 | "url": "https://github.com/sponsors/ljharb"
696 | }
697 | },
698 | "node_modules/has-proto": {
699 | "version": "1.0.1",
700 | "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
701 | "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
702 | "engines": {
703 | "node": ">= 0.4"
704 | },
705 | "funding": {
706 | "url": "https://github.com/sponsors/ljharb"
707 | }
708 | },
709 | "node_modules/has-symbols": {
710 | "version": "1.0.3",
711 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
712 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
713 | "engines": {
714 | "node": ">= 0.4"
715 | },
716 | "funding": {
717 | "url": "https://github.com/sponsors/ljharb"
718 | }
719 | },
720 | "node_modules/has-unicode": {
721 | "version": "2.0.1",
722 | "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
723 | "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ=="
724 | },
725 | "node_modules/hasown": {
726 | "version": "2.0.0",
727 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz",
728 | "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==",
729 | "dependencies": {
730 | "function-bind": "^1.1.2"
731 | },
732 | "engines": {
733 | "node": ">= 0.4"
734 | }
735 | },
736 | "node_modules/http-errors": {
737 | "version": "2.0.0",
738 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
739 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
740 | "dependencies": {
741 | "depd": "2.0.0",
742 | "inherits": "2.0.4",
743 | "setprototypeof": "1.2.0",
744 | "statuses": "2.0.1",
745 | "toidentifier": "1.0.1"
746 | },
747 | "engines": {
748 | "node": ">= 0.8"
749 | }
750 | },
751 | "node_modules/https-proxy-agent": {
752 | "version": "5.0.1",
753 | "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
754 | "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
755 | "dependencies": {
756 | "agent-base": "6",
757 | "debug": "4"
758 | },
759 | "engines": {
760 | "node": ">= 6"
761 | }
762 | },
763 | "node_modules/https-proxy-agent/node_modules/debug": {
764 | "version": "4.3.4",
765 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
766 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
767 | "dependencies": {
768 | "ms": "2.1.2"
769 | },
770 | "engines": {
771 | "node": ">=6.0"
772 | },
773 | "peerDependenciesMeta": {
774 | "supports-color": {
775 | "optional": true
776 | }
777 | }
778 | },
779 | "node_modules/https-proxy-agent/node_modules/ms": {
780 | "version": "2.1.2",
781 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
782 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
783 | },
784 | "node_modules/iconv-lite": {
785 | "version": "0.4.24",
786 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
787 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
788 | "dependencies": {
789 | "safer-buffer": ">= 2.1.2 < 3"
790 | },
791 | "engines": {
792 | "node": ">=0.10.0"
793 | }
794 | },
795 | "node_modules/ignore-by-default": {
796 | "version": "1.0.1",
797 | "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
798 | "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA=="
799 | },
800 | "node_modules/inflight": {
801 | "version": "1.0.6",
802 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
803 | "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
804 | "dependencies": {
805 | "once": "^1.3.0",
806 | "wrappy": "1"
807 | }
808 | },
809 | "node_modules/inherits": {
810 | "version": "2.0.4",
811 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
812 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
813 | },
814 | "node_modules/ipaddr.js": {
815 | "version": "1.9.1",
816 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
817 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
818 | "engines": {
819 | "node": ">= 0.10"
820 | }
821 | },
822 | "node_modules/is-binary-path": {
823 | "version": "2.1.0",
824 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
825 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
826 | "dependencies": {
827 | "binary-extensions": "^2.0.0"
828 | },
829 | "engines": {
830 | "node": ">=8"
831 | }
832 | },
833 | "node_modules/is-extglob": {
834 | "version": "2.1.1",
835 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
836 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
837 | "engines": {
838 | "node": ">=0.10.0"
839 | }
840 | },
841 | "node_modules/is-fullwidth-code-point": {
842 | "version": "3.0.0",
843 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
844 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
845 | "engines": {
846 | "node": ">=8"
847 | }
848 | },
849 | "node_modules/is-glob": {
850 | "version": "4.0.3",
851 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
852 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
853 | "dependencies": {
854 | "is-extglob": "^2.1.1"
855 | },
856 | "engines": {
857 | "node": ">=0.10.0"
858 | }
859 | },
860 | "node_modules/is-number": {
861 | "version": "7.0.0",
862 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
863 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
864 | "engines": {
865 | "node": ">=0.12.0"
866 | }
867 | },
868 | "node_modules/jsonwebtoken": {
869 | "version": "9.0.2",
870 | "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz",
871 | "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==",
872 | "dependencies": {
873 | "jws": "^3.2.2",
874 | "lodash.includes": "^4.3.0",
875 | "lodash.isboolean": "^3.0.3",
876 | "lodash.isinteger": "^4.0.4",
877 | "lodash.isnumber": "^3.0.3",
878 | "lodash.isplainobject": "^4.0.6",
879 | "lodash.isstring": "^4.0.1",
880 | "lodash.once": "^4.0.0",
881 | "ms": "^2.1.1",
882 | "semver": "^7.5.4"
883 | },
884 | "engines": {
885 | "node": ">=12",
886 | "npm": ">=6"
887 | }
888 | },
889 | "node_modules/jsonwebtoken/node_modules/ms": {
890 | "version": "2.1.3",
891 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
892 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
893 | },
894 | "node_modules/jwa": {
895 | "version": "1.4.1",
896 | "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
897 | "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
898 | "dependencies": {
899 | "buffer-equal-constant-time": "1.0.1",
900 | "ecdsa-sig-formatter": "1.0.11",
901 | "safe-buffer": "^5.0.1"
902 | }
903 | },
904 | "node_modules/jws": {
905 | "version": "3.2.2",
906 | "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
907 | "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
908 | "dependencies": {
909 | "jwa": "^1.4.1",
910 | "safe-buffer": "^5.0.1"
911 | }
912 | },
913 | "node_modules/lodash.includes": {
914 | "version": "4.3.0",
915 | "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
916 | "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w=="
917 | },
918 | "node_modules/lodash.isboolean": {
919 | "version": "3.0.3",
920 | "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
921 | "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg=="
922 | },
923 | "node_modules/lodash.isinteger": {
924 | "version": "4.0.4",
925 | "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
926 | "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA=="
927 | },
928 | "node_modules/lodash.isnumber": {
929 | "version": "3.0.3",
930 | "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
931 | "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw=="
932 | },
933 | "node_modules/lodash.isplainobject": {
934 | "version": "4.0.6",
935 | "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
936 | "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="
937 | },
938 | "node_modules/lodash.isstring": {
939 | "version": "4.0.1",
940 | "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
941 | "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw=="
942 | },
943 | "node_modules/lodash.once": {
944 | "version": "4.1.1",
945 | "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
946 | "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="
947 | },
948 | "node_modules/lru-cache": {
949 | "version": "6.0.0",
950 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
951 | "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
952 | "dependencies": {
953 | "yallist": "^4.0.0"
954 | },
955 | "engines": {
956 | "node": ">=10"
957 | }
958 | },
959 | "node_modules/make-dir": {
960 | "version": "3.1.0",
961 | "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
962 | "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
963 | "dependencies": {
964 | "semver": "^6.0.0"
965 | },
966 | "engines": {
967 | "node": ">=8"
968 | },
969 | "funding": {
970 | "url": "https://github.com/sponsors/sindresorhus"
971 | }
972 | },
973 | "node_modules/make-dir/node_modules/semver": {
974 | "version": "6.3.1",
975 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
976 | "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
977 | "bin": {
978 | "semver": "bin/semver.js"
979 | }
980 | },
981 | "node_modules/media-typer": {
982 | "version": "0.3.0",
983 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
984 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
985 | "engines": {
986 | "node": ">= 0.6"
987 | }
988 | },
989 | "node_modules/merge-descriptors": {
990 | "version": "1.0.1",
991 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
992 | "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
993 | },
994 | "node_modules/methods": {
995 | "version": "1.1.2",
996 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
997 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
998 | "engines": {
999 | "node": ">= 0.6"
1000 | }
1001 | },
1002 | "node_modules/mime": {
1003 | "version": "1.6.0",
1004 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
1005 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
1006 | "bin": {
1007 | "mime": "cli.js"
1008 | },
1009 | "engines": {
1010 | "node": ">=4"
1011 | }
1012 | },
1013 | "node_modules/mime-db": {
1014 | "version": "1.52.0",
1015 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
1016 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
1017 | "engines": {
1018 | "node": ">= 0.6"
1019 | }
1020 | },
1021 | "node_modules/mime-types": {
1022 | "version": "2.1.35",
1023 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
1024 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
1025 | "dependencies": {
1026 | "mime-db": "1.52.0"
1027 | },
1028 | "engines": {
1029 | "node": ">= 0.6"
1030 | }
1031 | },
1032 | "node_modules/minimatch": {
1033 | "version": "3.1.2",
1034 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
1035 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
1036 | "dependencies": {
1037 | "brace-expansion": "^1.1.7"
1038 | },
1039 | "engines": {
1040 | "node": "*"
1041 | }
1042 | },
1043 | "node_modules/minipass": {
1044 | "version": "5.0.0",
1045 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
1046 | "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
1047 | "engines": {
1048 | "node": ">=8"
1049 | }
1050 | },
1051 | "node_modules/minizlib": {
1052 | "version": "2.1.2",
1053 | "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
1054 | "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
1055 | "dependencies": {
1056 | "minipass": "^3.0.0",
1057 | "yallist": "^4.0.0"
1058 | },
1059 | "engines": {
1060 | "node": ">= 8"
1061 | }
1062 | },
1063 | "node_modules/minizlib/node_modules/minipass": {
1064 | "version": "3.3.6",
1065 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
1066 | "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
1067 | "dependencies": {
1068 | "yallist": "^4.0.0"
1069 | },
1070 | "engines": {
1071 | "node": ">=8"
1072 | }
1073 | },
1074 | "node_modules/mkdirp": {
1075 | "version": "1.0.4",
1076 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
1077 | "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
1078 | "bin": {
1079 | "mkdirp": "bin/cmd.js"
1080 | },
1081 | "engines": {
1082 | "node": ">=10"
1083 | }
1084 | },
1085 | "node_modules/ms": {
1086 | "version": "2.0.0",
1087 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
1088 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
1089 | },
1090 | "node_modules/negotiator": {
1091 | "version": "0.6.3",
1092 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
1093 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
1094 | "engines": {
1095 | "node": ">= 0.6"
1096 | }
1097 | },
1098 | "node_modules/node-addon-api": {
1099 | "version": "5.1.0",
1100 | "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz",
1101 | "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA=="
1102 | },
1103 | "node_modules/node-fetch": {
1104 | "version": "2.7.0",
1105 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
1106 | "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
1107 | "dependencies": {
1108 | "whatwg-url": "^5.0.0"
1109 | },
1110 | "engines": {
1111 | "node": "4.x || >=6.0.0"
1112 | },
1113 | "peerDependencies": {
1114 | "encoding": "^0.1.0"
1115 | },
1116 | "peerDependenciesMeta": {
1117 | "encoding": {
1118 | "optional": true
1119 | }
1120 | }
1121 | },
1122 | "node_modules/nodemon": {
1123 | "version": "3.0.2",
1124 | "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.0.2.tgz",
1125 | "integrity": "sha512-9qIN2LNTrEzpOPBaWHTm4Asy1LxXLSickZStAQ4IZe7zsoIpD/A7LWxhZV3t4Zu352uBcqVnRsDXSMR2Sc3lTA==",
1126 | "dependencies": {
1127 | "chokidar": "^3.5.2",
1128 | "debug": "^4",
1129 | "ignore-by-default": "^1.0.1",
1130 | "minimatch": "^3.1.2",
1131 | "pstree.remy": "^1.1.8",
1132 | "semver": "^7.5.3",
1133 | "simple-update-notifier": "^2.0.0",
1134 | "supports-color": "^5.5.0",
1135 | "touch": "^3.1.0",
1136 | "undefsafe": "^2.0.5"
1137 | },
1138 | "bin": {
1139 | "nodemon": "bin/nodemon.js"
1140 | },
1141 | "engines": {
1142 | "node": ">=10"
1143 | },
1144 | "funding": {
1145 | "type": "opencollective",
1146 | "url": "https://opencollective.com/nodemon"
1147 | }
1148 | },
1149 | "node_modules/nodemon/node_modules/debug": {
1150 | "version": "4.3.4",
1151 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
1152 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
1153 | "dependencies": {
1154 | "ms": "2.1.2"
1155 | },
1156 | "engines": {
1157 | "node": ">=6.0"
1158 | },
1159 | "peerDependenciesMeta": {
1160 | "supports-color": {
1161 | "optional": true
1162 | }
1163 | }
1164 | },
1165 | "node_modules/nodemon/node_modules/ms": {
1166 | "version": "2.1.2",
1167 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
1168 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
1169 | },
1170 | "node_modules/nopt": {
1171 | "version": "1.0.10",
1172 | "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
1173 | "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==",
1174 | "dependencies": {
1175 | "abbrev": "1"
1176 | },
1177 | "bin": {
1178 | "nopt": "bin/nopt.js"
1179 | },
1180 | "engines": {
1181 | "node": "*"
1182 | }
1183 | },
1184 | "node_modules/normalize-path": {
1185 | "version": "3.0.0",
1186 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
1187 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
1188 | "engines": {
1189 | "node": ">=0.10.0"
1190 | }
1191 | },
1192 | "node_modules/npmlog": {
1193 | "version": "5.0.1",
1194 | "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz",
1195 | "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==",
1196 | "dependencies": {
1197 | "are-we-there-yet": "^2.0.0",
1198 | "console-control-strings": "^1.1.0",
1199 | "gauge": "^3.0.0",
1200 | "set-blocking": "^2.0.0"
1201 | }
1202 | },
1203 | "node_modules/object-assign": {
1204 | "version": "4.1.1",
1205 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
1206 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
1207 | "engines": {
1208 | "node": ">=0.10.0"
1209 | }
1210 | },
1211 | "node_modules/object-inspect": {
1212 | "version": "1.13.1",
1213 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz",
1214 | "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==",
1215 | "funding": {
1216 | "url": "https://github.com/sponsors/ljharb"
1217 | }
1218 | },
1219 | "node_modules/on-finished": {
1220 | "version": "2.4.1",
1221 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
1222 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
1223 | "dependencies": {
1224 | "ee-first": "1.1.1"
1225 | },
1226 | "engines": {
1227 | "node": ">= 0.8"
1228 | }
1229 | },
1230 | "node_modules/once": {
1231 | "version": "1.4.0",
1232 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
1233 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
1234 | "dependencies": {
1235 | "wrappy": "1"
1236 | }
1237 | },
1238 | "node_modules/packet-reader": {
1239 | "version": "1.0.0",
1240 | "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz",
1241 | "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ=="
1242 | },
1243 | "node_modules/parseurl": {
1244 | "version": "1.3.3",
1245 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
1246 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
1247 | "engines": {
1248 | "node": ">= 0.8"
1249 | }
1250 | },
1251 | "node_modules/path-is-absolute": {
1252 | "version": "1.0.1",
1253 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
1254 | "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
1255 | "engines": {
1256 | "node": ">=0.10.0"
1257 | }
1258 | },
1259 | "node_modules/path-to-regexp": {
1260 | "version": "0.1.7",
1261 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
1262 | "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
1263 | },
1264 | "node_modules/pg": {
1265 | "version": "8.11.3",
1266 | "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.3.tgz",
1267 | "integrity": "sha512-+9iuvG8QfaaUrrph+kpF24cXkH1YOOUeArRNYIxq1viYHZagBxrTno7cecY1Fa44tJeZvaoG+Djpkc3JwehN5g==",
1268 | "dependencies": {
1269 | "buffer-writer": "2.0.0",
1270 | "packet-reader": "1.0.0",
1271 | "pg-connection-string": "^2.6.2",
1272 | "pg-pool": "^3.6.1",
1273 | "pg-protocol": "^1.6.0",
1274 | "pg-types": "^2.1.0",
1275 | "pgpass": "1.x"
1276 | },
1277 | "engines": {
1278 | "node": ">= 8.0.0"
1279 | },
1280 | "optionalDependencies": {
1281 | "pg-cloudflare": "^1.1.1"
1282 | },
1283 | "peerDependencies": {
1284 | "pg-native": ">=3.0.1"
1285 | },
1286 | "peerDependenciesMeta": {
1287 | "pg-native": {
1288 | "optional": true
1289 | }
1290 | }
1291 | },
1292 | "node_modules/pg-cloudflare": {
1293 | "version": "1.1.1",
1294 | "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz",
1295 | "integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==",
1296 | "optional": true
1297 | },
1298 | "node_modules/pg-connection-string": {
1299 | "version": "2.6.2",
1300 | "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz",
1301 | "integrity": "sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA=="
1302 | },
1303 | "node_modules/pg-int8": {
1304 | "version": "1.0.1",
1305 | "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
1306 | "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==",
1307 | "engines": {
1308 | "node": ">=4.0.0"
1309 | }
1310 | },
1311 | "node_modules/pg-pool": {
1312 | "version": "3.6.1",
1313 | "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.1.tgz",
1314 | "integrity": "sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og==",
1315 | "peerDependencies": {
1316 | "pg": ">=8.0"
1317 | }
1318 | },
1319 | "node_modules/pg-protocol": {
1320 | "version": "1.6.0",
1321 | "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.0.tgz",
1322 | "integrity": "sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q=="
1323 | },
1324 | "node_modules/pg-types": {
1325 | "version": "2.2.0",
1326 | "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz",
1327 | "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==",
1328 | "dependencies": {
1329 | "pg-int8": "1.0.1",
1330 | "postgres-array": "~2.0.0",
1331 | "postgres-bytea": "~1.0.0",
1332 | "postgres-date": "~1.0.4",
1333 | "postgres-interval": "^1.1.0"
1334 | },
1335 | "engines": {
1336 | "node": ">=4"
1337 | }
1338 | },
1339 | "node_modules/pgpass": {
1340 | "version": "1.0.5",
1341 | "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz",
1342 | "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==",
1343 | "dependencies": {
1344 | "split2": "^4.1.0"
1345 | }
1346 | },
1347 | "node_modules/picomatch": {
1348 | "version": "2.3.1",
1349 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
1350 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
1351 | "engines": {
1352 | "node": ">=8.6"
1353 | },
1354 | "funding": {
1355 | "url": "https://github.com/sponsors/jonschlinkert"
1356 | }
1357 | },
1358 | "node_modules/postgres-array": {
1359 | "version": "2.0.0",
1360 | "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
1361 | "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==",
1362 | "engines": {
1363 | "node": ">=4"
1364 | }
1365 | },
1366 | "node_modules/postgres-bytea": {
1367 | "version": "1.0.0",
1368 | "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz",
1369 | "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==",
1370 | "engines": {
1371 | "node": ">=0.10.0"
1372 | }
1373 | },
1374 | "node_modules/postgres-date": {
1375 | "version": "1.0.7",
1376 | "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz",
1377 | "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==",
1378 | "engines": {
1379 | "node": ">=0.10.0"
1380 | }
1381 | },
1382 | "node_modules/postgres-interval": {
1383 | "version": "1.2.0",
1384 | "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz",
1385 | "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==",
1386 | "dependencies": {
1387 | "xtend": "^4.0.0"
1388 | },
1389 | "engines": {
1390 | "node": ">=0.10.0"
1391 | }
1392 | },
1393 | "node_modules/proxy-addr": {
1394 | "version": "2.0.7",
1395 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
1396 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
1397 | "dependencies": {
1398 | "forwarded": "0.2.0",
1399 | "ipaddr.js": "1.9.1"
1400 | },
1401 | "engines": {
1402 | "node": ">= 0.10"
1403 | }
1404 | },
1405 | "node_modules/pstree.remy": {
1406 | "version": "1.1.8",
1407 | "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
1408 | "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w=="
1409 | },
1410 | "node_modules/qs": {
1411 | "version": "6.11.0",
1412 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
1413 | "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
1414 | "dependencies": {
1415 | "side-channel": "^1.0.4"
1416 | },
1417 | "engines": {
1418 | "node": ">=0.6"
1419 | },
1420 | "funding": {
1421 | "url": "https://github.com/sponsors/ljharb"
1422 | }
1423 | },
1424 | "node_modules/range-parser": {
1425 | "version": "1.2.1",
1426 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
1427 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
1428 | "engines": {
1429 | "node": ">= 0.6"
1430 | }
1431 | },
1432 | "node_modules/raw-body": {
1433 | "version": "2.5.1",
1434 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
1435 | "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
1436 | "dependencies": {
1437 | "bytes": "3.1.2",
1438 | "http-errors": "2.0.0",
1439 | "iconv-lite": "0.4.24",
1440 | "unpipe": "1.0.0"
1441 | },
1442 | "engines": {
1443 | "node": ">= 0.8"
1444 | }
1445 | },
1446 | "node_modules/readable-stream": {
1447 | "version": "3.6.2",
1448 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
1449 | "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
1450 | "dependencies": {
1451 | "inherits": "^2.0.3",
1452 | "string_decoder": "^1.1.1",
1453 | "util-deprecate": "^1.0.1"
1454 | },
1455 | "engines": {
1456 | "node": ">= 6"
1457 | }
1458 | },
1459 | "node_modules/readdirp": {
1460 | "version": "3.6.0",
1461 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
1462 | "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
1463 | "dependencies": {
1464 | "picomatch": "^2.2.1"
1465 | },
1466 | "engines": {
1467 | "node": ">=8.10.0"
1468 | }
1469 | },
1470 | "node_modules/rimraf": {
1471 | "version": "3.0.2",
1472 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
1473 | "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
1474 | "dependencies": {
1475 | "glob": "^7.1.3"
1476 | },
1477 | "bin": {
1478 | "rimraf": "bin.js"
1479 | },
1480 | "funding": {
1481 | "url": "https://github.com/sponsors/isaacs"
1482 | }
1483 | },
1484 | "node_modules/safe-buffer": {
1485 | "version": "5.2.1",
1486 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
1487 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
1488 | "funding": [
1489 | {
1490 | "type": "github",
1491 | "url": "https://github.com/sponsors/feross"
1492 | },
1493 | {
1494 | "type": "patreon",
1495 | "url": "https://www.patreon.com/feross"
1496 | },
1497 | {
1498 | "type": "consulting",
1499 | "url": "https://feross.org/support"
1500 | }
1501 | ]
1502 | },
1503 | "node_modules/safer-buffer": {
1504 | "version": "2.1.2",
1505 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
1506 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
1507 | },
1508 | "node_modules/semver": {
1509 | "version": "7.5.4",
1510 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
1511 | "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
1512 | "dependencies": {
1513 | "lru-cache": "^6.0.0"
1514 | },
1515 | "bin": {
1516 | "semver": "bin/semver.js"
1517 | },
1518 | "engines": {
1519 | "node": ">=10"
1520 | }
1521 | },
1522 | "node_modules/send": {
1523 | "version": "0.18.0",
1524 | "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
1525 | "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
1526 | "dependencies": {
1527 | "debug": "2.6.9",
1528 | "depd": "2.0.0",
1529 | "destroy": "1.2.0",
1530 | "encodeurl": "~1.0.2",
1531 | "escape-html": "~1.0.3",
1532 | "etag": "~1.8.1",
1533 | "fresh": "0.5.2",
1534 | "http-errors": "2.0.0",
1535 | "mime": "1.6.0",
1536 | "ms": "2.1.3",
1537 | "on-finished": "2.4.1",
1538 | "range-parser": "~1.2.1",
1539 | "statuses": "2.0.1"
1540 | },
1541 | "engines": {
1542 | "node": ">= 0.8.0"
1543 | }
1544 | },
1545 | "node_modules/send/node_modules/ms": {
1546 | "version": "2.1.3",
1547 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
1548 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
1549 | },
1550 | "node_modules/serve-static": {
1551 | "version": "1.15.0",
1552 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
1553 | "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
1554 | "dependencies": {
1555 | "encodeurl": "~1.0.2",
1556 | "escape-html": "~1.0.3",
1557 | "parseurl": "~1.3.3",
1558 | "send": "0.18.0"
1559 | },
1560 | "engines": {
1561 | "node": ">= 0.8.0"
1562 | }
1563 | },
1564 | "node_modules/set-blocking": {
1565 | "version": "2.0.0",
1566 | "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
1567 | "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="
1568 | },
1569 | "node_modules/set-function-length": {
1570 | "version": "1.1.1",
1571 | "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz",
1572 | "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==",
1573 | "dependencies": {
1574 | "define-data-property": "^1.1.1",
1575 | "get-intrinsic": "^1.2.1",
1576 | "gopd": "^1.0.1",
1577 | "has-property-descriptors": "^1.0.0"
1578 | },
1579 | "engines": {
1580 | "node": ">= 0.4"
1581 | }
1582 | },
1583 | "node_modules/setprototypeof": {
1584 | "version": "1.2.0",
1585 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
1586 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
1587 | },
1588 | "node_modules/side-channel": {
1589 | "version": "1.0.4",
1590 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
1591 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
1592 | "dependencies": {
1593 | "call-bind": "^1.0.0",
1594 | "get-intrinsic": "^1.0.2",
1595 | "object-inspect": "^1.9.0"
1596 | },
1597 | "funding": {
1598 | "url": "https://github.com/sponsors/ljharb"
1599 | }
1600 | },
1601 | "node_modules/signal-exit": {
1602 | "version": "3.0.7",
1603 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
1604 | "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
1605 | },
1606 | "node_modules/simple-update-notifier": {
1607 | "version": "2.0.0",
1608 | "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz",
1609 | "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==",
1610 | "dependencies": {
1611 | "semver": "^7.5.3"
1612 | },
1613 | "engines": {
1614 | "node": ">=10"
1615 | }
1616 | },
1617 | "node_modules/split2": {
1618 | "version": "4.2.0",
1619 | "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
1620 | "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
1621 | "engines": {
1622 | "node": ">= 10.x"
1623 | }
1624 | },
1625 | "node_modules/statuses": {
1626 | "version": "2.0.1",
1627 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
1628 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
1629 | "engines": {
1630 | "node": ">= 0.8"
1631 | }
1632 | },
1633 | "node_modules/string_decoder": {
1634 | "version": "1.3.0",
1635 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
1636 | "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
1637 | "dependencies": {
1638 | "safe-buffer": "~5.2.0"
1639 | }
1640 | },
1641 | "node_modules/string-width": {
1642 | "version": "4.2.3",
1643 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
1644 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
1645 | "dependencies": {
1646 | "emoji-regex": "^8.0.0",
1647 | "is-fullwidth-code-point": "^3.0.0",
1648 | "strip-ansi": "^6.0.1"
1649 | },
1650 | "engines": {
1651 | "node": ">=8"
1652 | }
1653 | },
1654 | "node_modules/strip-ansi": {
1655 | "version": "6.0.1",
1656 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
1657 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
1658 | "dependencies": {
1659 | "ansi-regex": "^5.0.1"
1660 | },
1661 | "engines": {
1662 | "node": ">=8"
1663 | }
1664 | },
1665 | "node_modules/supports-color": {
1666 | "version": "5.5.0",
1667 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
1668 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
1669 | "dependencies": {
1670 | "has-flag": "^3.0.0"
1671 | },
1672 | "engines": {
1673 | "node": ">=4"
1674 | }
1675 | },
1676 | "node_modules/tar": {
1677 | "version": "6.2.0",
1678 | "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz",
1679 | "integrity": "sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==",
1680 | "dependencies": {
1681 | "chownr": "^2.0.0",
1682 | "fs-minipass": "^2.0.0",
1683 | "minipass": "^5.0.0",
1684 | "minizlib": "^2.1.1",
1685 | "mkdirp": "^1.0.3",
1686 | "yallist": "^4.0.0"
1687 | },
1688 | "engines": {
1689 | "node": ">=10"
1690 | }
1691 | },
1692 | "node_modules/to-regex-range": {
1693 | "version": "5.0.1",
1694 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
1695 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
1696 | "dependencies": {
1697 | "is-number": "^7.0.0"
1698 | },
1699 | "engines": {
1700 | "node": ">=8.0"
1701 | }
1702 | },
1703 | "node_modules/toidentifier": {
1704 | "version": "1.0.1",
1705 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
1706 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
1707 | "engines": {
1708 | "node": ">=0.6"
1709 | }
1710 | },
1711 | "node_modules/touch": {
1712 | "version": "3.1.0",
1713 | "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz",
1714 | "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==",
1715 | "dependencies": {
1716 | "nopt": "~1.0.10"
1717 | },
1718 | "bin": {
1719 | "nodetouch": "bin/nodetouch.js"
1720 | }
1721 | },
1722 | "node_modules/tr46": {
1723 | "version": "0.0.3",
1724 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
1725 | "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
1726 | },
1727 | "node_modules/type-is": {
1728 | "version": "1.6.18",
1729 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
1730 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
1731 | "dependencies": {
1732 | "media-typer": "0.3.0",
1733 | "mime-types": "~2.1.24"
1734 | },
1735 | "engines": {
1736 | "node": ">= 0.6"
1737 | }
1738 | },
1739 | "node_modules/undefsafe": {
1740 | "version": "2.0.5",
1741 | "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
1742 | "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA=="
1743 | },
1744 | "node_modules/unpipe": {
1745 | "version": "1.0.0",
1746 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
1747 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
1748 | "engines": {
1749 | "node": ">= 0.8"
1750 | }
1751 | },
1752 | "node_modules/util-deprecate": {
1753 | "version": "1.0.2",
1754 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
1755 | "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
1756 | },
1757 | "node_modules/utils-merge": {
1758 | "version": "1.0.1",
1759 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
1760 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
1761 | "engines": {
1762 | "node": ">= 0.4.0"
1763 | }
1764 | },
1765 | "node_modules/vary": {
1766 | "version": "1.1.2",
1767 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
1768 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
1769 | "engines": {
1770 | "node": ">= 0.8"
1771 | }
1772 | },
1773 | "node_modules/webidl-conversions": {
1774 | "version": "3.0.1",
1775 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
1776 | "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
1777 | },
1778 | "node_modules/whatwg-url": {
1779 | "version": "5.0.0",
1780 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
1781 | "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
1782 | "dependencies": {
1783 | "tr46": "~0.0.3",
1784 | "webidl-conversions": "^3.0.0"
1785 | }
1786 | },
1787 | "node_modules/wide-align": {
1788 | "version": "1.1.5",
1789 | "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
1790 | "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
1791 | "dependencies": {
1792 | "string-width": "^1.0.2 || 2 || 3 || 4"
1793 | }
1794 | },
1795 | "node_modules/wrappy": {
1796 | "version": "1.0.2",
1797 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
1798 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
1799 | },
1800 | "node_modules/xtend": {
1801 | "version": "4.0.2",
1802 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
1803 | "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
1804 | "engines": {
1805 | "node": ">=0.4"
1806 | }
1807 | },
1808 | "node_modules/yallist": {
1809 | "version": "4.0.0",
1810 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
1811 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
1812 | }
1813 | }
1814 | }
1815 |
--------------------------------------------------------------------------------