├── server ├── .gitignore ├── src │ ├── models │ │ ├── allRooms.js │ │ ├── message.js │ │ ├── roomSchema.js │ │ └── userSchema.js │ ├── db │ │ └── connec.js │ ├── config.env.example │ ├── middleware │ │ └── authenticate.js │ ├── router │ │ └── auth.js │ └── index.js ├── package.json └── package-lock.json ├── client ├── public │ ├── robots.txt │ ├── favicon.ico │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── index.html ├── src │ ├── assets │ │ ├── codeimg2.jpg │ │ └── Backgrounds │ │ │ ├── warning.png │ │ │ ├── Fade-In-Background.svg │ │ │ └── rooms.svg │ ├── setupTests.js │ ├── App.test.js │ ├── components │ │ ├── SignUp │ │ │ ├── signup.css │ │ │ └── SignUp.jsx │ │ ├── ChatFeature │ │ │ ├── Messages │ │ │ │ ├── Messages.css │ │ │ │ ├── Messages.jsx │ │ │ │ └── Message │ │ │ │ │ ├── Message.jsx │ │ │ │ │ └── Message.css │ │ │ └── Input │ │ │ │ ├── Input.css │ │ │ │ └── Input.jsx │ │ ├── Room │ │ │ ├── Rooms.css │ │ │ └── Rooms.jsx │ │ ├── EditorBox │ │ │ ├── Box.jsx │ │ │ └── InputBox.jsx │ │ ├── Error │ │ │ └── Errorpage.jsx │ │ ├── Home │ │ │ ├── Home.css │ │ │ └── Home.jsx │ │ ├── Editor │ │ │ ├── editor.css │ │ │ └── myEditor.jsx │ │ ├── InsideRoom │ │ │ └── Room.jsx │ │ └── Login │ │ │ └── Login.jsx │ ├── reportWebVitals.js │ ├── pages │ │ ├── LoginPage.jsx │ │ ├── CreateAccount.jsx │ │ └── Logout.jsx │ ├── index.css │ ├── index.js │ ├── App.css │ ├── App.js │ └── logo.svg ├── .gitignore ├── package.json └── README.md └── Tutorial for new users.mp4 /server/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /src/config.env 3 | -------------------------------------------------------------------------------- /client/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /client/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pranawr/SynCode_Project_CSN_254/HEAD/client/public/favicon.ico -------------------------------------------------------------------------------- /client/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pranawr/SynCode_Project_CSN_254/HEAD/client/public/logo192.png -------------------------------------------------------------------------------- /client/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pranawr/SynCode_Project_CSN_254/HEAD/client/public/logo512.png -------------------------------------------------------------------------------- /Tutorial for new users.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pranawr/SynCode_Project_CSN_254/HEAD/Tutorial for new users.mp4 -------------------------------------------------------------------------------- /client/src/assets/codeimg2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pranawr/SynCode_Project_CSN_254/HEAD/client/src/assets/codeimg2.jpg -------------------------------------------------------------------------------- /client/src/assets/Backgrounds/warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pranawr/SynCode_Project_CSN_254/HEAD/client/src/assets/Backgrounds/warning.png -------------------------------------------------------------------------------- /client/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /client/src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /server/src/models/allRooms.js: -------------------------------------------------------------------------------- 1 | var mongoose= require("mongoose"); 2 | 3 | var AllRooms= new mongoose.Schema({ 4 | allrooms: [ 5 | { 6 | type: mongoose.Schema.Types.ObjectId, 7 | ref: "ROOM" 8 | } 9 | ] 10 | }); 11 | 12 | //setup svhema to a model 13 | module.exports=mongoose.model('ALLROOMS', AllRooms); -------------------------------------------------------------------------------- /server/src/db/connec.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | 3 | const DB = process.env.DATABASE; 4 | 5 | mongoose.connect(DB, { 6 | useNewUrlParser: true, 7 | useCreateIndex: true, 8 | useUnifiedTopology: true, 9 | useFindAndModify: false 10 | }).then(()=>{ 11 | console.log('Connection Successful'); 12 | }).catch((err)=>console.log(err)); 13 | -------------------------------------------------------------------------------- /server/src/config.env.example: -------------------------------------------------------------------------------- 1 | DATABASE="paste your mongodb atlas link here (without quotes)" 2 | PORT=5000 3 | SECRET_KEY="paste your secret key here (without quotes)" 4 | JDOODLE_CLIENT_ID="paste your jdoodle client id here (without quotes)" 5 | JDOODLE_CLIENT_SECRET="paste your jdoodle client secret here (without quotes)" 6 | JDOODLE_URL="paste jdoodle api url here (without quotes)" -------------------------------------------------------------------------------- /client/src/components/SignUp/signup.css: -------------------------------------------------------------------------------- 1 | /* html{ 2 | background-image: url("./../../assets/Backgrounds/Fade-In-Background.svg"); 3 | background-position: 'center'; 4 | background-size: 'cover'; 5 | background-repeat: 'no-repeat'; 6 | width: '100vw'; 7 | height: '100vh'; 8 | height: 100%; 9 | } 10 | 11 | body{ 12 | background:unset !important; 13 | } */ -------------------------------------------------------------------------------- /client/src/components/ChatFeature/Messages/Messages.css: -------------------------------------------------------------------------------- 1 | .messages { 2 | padding: 5% 0; 3 | overflow: auto; 4 | flex: auto; 5 | } 6 | 7 | ::-webkit-scrollbar{ 8 | width: 8.5px; 9 | } 10 | ::-webkit-scrollbar-track{ 11 | background-color: #f4f4f4; 12 | } 13 | 14 | ::-webkit-scrollbar-thumb{ 15 | border-radius: 25px; 16 | background-color: #909090; 17 | } -------------------------------------------------------------------------------- /client/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | ./config.env 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /client/src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /client/src/pages/LoginPage.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Login from '../components/Login/Login' 3 | import background from "./../assets/Backgrounds/Fade-In-Background.svg" 4 | 5 | const LoginPage = props => { 6 | return ( 7 |
8 | 9 |
10 | ) 11 | } 12 | 13 | export default LoginPage 14 | -------------------------------------------------------------------------------- /client/src/components/ChatFeature/Messages/Messages.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import ScrollToBottom from 'react-scroll-to-bottom'; 4 | 5 | import Message from './Message/Message'; 6 | 7 | import './Messages.css'; 8 | 9 | const Messages = ({ messages, nameOfUser }) => ( 10 | 11 | {messages.map((message, i) =>
)} 12 |
13 | ); 14 | 15 | export default Messages; -------------------------------------------------------------------------------- /client/src/pages/CreateAccount.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import SignUp from '../components/SignUp/SignUp' 3 | import background from "./../assets/Backgrounds/Fade-In-Background.svg" 4 | 5 | const CreateAccount = props => { 6 | return ( 7 |
8 | 9 |
10 | ) 11 | } 12 | 13 | 14 | 15 | export default CreateAccount 16 | -------------------------------------------------------------------------------- /client/src/components/Room/Rooms.css: -------------------------------------------------------------------------------- 1 | .roomsLink:hover{ 2 | color: #ffffff !important; 3 | } 4 | 5 | .roomsLink{ 6 | text-decoration: none; 7 | display: inline-block; 8 | } 9 | 10 | .roomsLink::after{ 11 | content: ""; 12 | display: block; 13 | width: 0; 14 | height: 2px; 15 | background: #3498db; 16 | transition: width 1s; 17 | } 18 | .banner-text h2{ 19 | font-family: 'Poppins', sans-serif; 20 | color: #fff; 21 | } 22 | .roomsLink:hover::after{ 23 | width: 100%; 24 | transition: width 1s; 25 | } -------------------------------------------------------------------------------- /server/src/models/message.js: -------------------------------------------------------------------------------- 1 | var mongoose= require("mongoose"); 2 | 3 | var messageSchema= mongoose.Schema({ 4 | text:{ 5 | type: String, 6 | required: true 7 | }, 8 | 9 | time1:{ 10 | type:String, 11 | default:new Date().toISOString().slice(0,10) 12 | }, 13 | author:{ 14 | id:{ 15 | type:mongoose.Schema.Types.ObjectId, 16 | ref:"USER" 17 | }, 18 | userName:String 19 | }, 20 | 21 | }); 22 | 23 | module.exports =mongoose.model("MESSAGE",messageSchema); -------------------------------------------------------------------------------- /server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "server", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "axios": "^0.21.1", 14 | "bcrypt": "^5.0.1", 15 | "bcryptjs": "^2.4.3", 16 | "cookie-parser": "^1.4.5", 17 | "dotenv": "^8.2.0", 18 | "express": "^4.17.1", 19 | "jsonwebtoken": "^8.5.1", 20 | "mongoose": "^5.12.3", 21 | "socket.io": "^4.0.1" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /client/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "SynCode", 3 | "name": "SynCode", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /client/src/index.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Mulish:wght@500&display=swap'); 2 | * { 3 | margin: 0; 4 | padding: 0; 5 | box-sizing: border-box; 6 | } 7 | 8 | body { 9 | margin: 0; 10 | padding: 0; 11 | height: 100%; 12 | font-family: 'Mulish', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 13 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 14 | sans-serif; 15 | -webkit-font-smoothing: antialiased; 16 | -moz-osx-font-smoothing: grayscale; 17 | } 18 | 19 | html{ 20 | position: relative; 21 | height: 100%; 22 | } 23 | 24 | html body{ 25 | overflow: auto; 26 | } 27 | -------------------------------------------------------------------------------- /client/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import reportWebVitals from './reportWebVitals'; 6 | import { BrowserRouter } from "react-router-dom"; 7 | 8 | ReactDOM.render( 9 | 10 | 11 | 12 | 13 | , 14 | document.getElementById('root') 15 | ); 16 | 17 | // If you want to start measuring performance in your app, pass a function 18 | // to log results (for example: reportWebVitals(console.log)) 19 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 20 | reportWebVitals(); 21 | -------------------------------------------------------------------------------- /client/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | .App-header { 17 | background-color: #282c34; 18 | min-height: 100vh; 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | justify-content: center; 23 | font-size: calc(10px + 2vmin); 24 | color: white; 25 | } 26 | 27 | .App-link { 28 | color: #61dafb; 29 | } 30 | 31 | @keyframes App-logo-spin { 32 | from { 33 | transform: rotate(0deg); 34 | } 35 | to { 36 | transform: rotate(360deg); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /client/src/components/ChatFeature/Input/Input.css: -------------------------------------------------------------------------------- 1 | .form { 2 | display: flex; 3 | border-top: 2px solid #D3D3D3; 4 | border-left: 2px solid #D3D3D3; 5 | border-right: 2px solid #D3D3D3; 6 | margin-bottom: 0px; 7 | border-radius: 20px; 8 | } 9 | 10 | .input { 11 | border: none; 12 | border-radius: 20px; 13 | padding: 1%; 14 | padding-left: 5%; 15 | width: 90%; 16 | font-size: 1.2em; 17 | } 18 | 19 | input:focus, textarea:focus, select:focus{ 20 | outline: none; 21 | } 22 | 23 | .sendButton { 24 | color: #fff !important; 25 | text-transform: uppercase; 26 | text-decoration: none; 27 | background: #2979FF; 28 | padding: 20px; 29 | display: inline-block; 30 | border: none; 31 | width: 10%; 32 | } -------------------------------------------------------------------------------- /client/src/components/EditorBox/Box.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Editor from "@monaco-editor/react" 3 | 4 | const Box = (props) => { 5 | 6 | return ( 7 | <> 8 |
9 | {props.feature} 10 |
11 |
12 | 20 |
21 | 22 | ) 23 | } 24 | 25 | export default Box 26 | -------------------------------------------------------------------------------- /server/src/models/roomSchema.js: -------------------------------------------------------------------------------- 1 | var mongoose= require("mongoose"); 2 | 3 | var roomSchema= new mongoose.Schema({ 4 | language: { 5 | type: String, 6 | required: true 7 | }, 8 | code: { 9 | type: String, 10 | required: true 11 | }, 12 | admin:{ 13 | id:{ 14 | type:mongoose.Schema.Types.ObjectId, 15 | ref:"USER" 16 | }, 17 | userName:String, 18 | 19 | }, 20 | time1:{ 21 | type:String, 22 | default:new Date().toISOString().slice(0,10) 23 | }, 24 | messages: [ 25 | { 26 | type: mongoose.Schema.Types.ObjectId, 27 | ref: "MESSAGE" 28 | } 29 | ] 30 | }); 31 | 32 | //setupsvhema to a model 33 | module.exports=mongoose.model('ROOM', roomSchema); -------------------------------------------------------------------------------- /server/src/middleware/authenticate.js: -------------------------------------------------------------------------------- 1 | const jwt = require('jsonwebtoken'); 2 | const User = require('../models/userSchema') 3 | 4 | const authenticate = async (req, res, next) => { 5 | try { 6 | console.log(req.cookies); 7 | const token = req.cookies.jwtToken; 8 | const verificationResult = await jwt.verify(token, process.env.SECRET_KEY); 9 | 10 | const rootUser = await User.findOne({_id: verificationResult._id, "tokens.token": token}); 11 | 12 | if (!rootUser) { 13 | throw new Error("Could not find User"); 14 | } 15 | 16 | req.token = token; 17 | req.rootUser = rootUser; 18 | req.userID = rootUser._id; 19 | 20 | next(); 21 | 22 | } catch (error) { 23 | res.status(401).send({error: "No token provided"}); 24 | console.log(error); 25 | } 26 | } 27 | 28 | module.exports = authenticate; -------------------------------------------------------------------------------- /client/src/components/ChatFeature/Input/Input.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import SendRoundedIcon from '@material-ui/icons/SendRounded'; 3 | import IconButton from '@material-ui/core/IconButton'; 4 | 5 | import './Input.css'; 6 | 7 | const Input = ({ setMessage, sendMessage, message }) => ( 8 |
9 | setMessage(value)} 15 | onKeyPress={event => event.key === 'Enter' ? sendMessage(event) : null} 16 | /> 17 | sendMessage(e)} title="Send"> 18 | 19 | 20 | {/* */} 21 |
22 | ) 23 | 24 | export default Input; -------------------------------------------------------------------------------- /client/src/components/EditorBox/InputBox.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Editor from "@monaco-editor/react" 3 | 4 | const InputBox = (props) => { 5 | 6 | const handleEditorChange = (value, event) => { 7 | console.log("here is the current model value:", value); 8 | props.setProperty(value); 9 | } 10 | return ( 11 | <> 12 |
13 | {props.feature} 14 |
15 |
16 | 24 |
25 | 26 | ) 27 | } 28 | 29 | export default InputBox 30 | -------------------------------------------------------------------------------- /client/src/pages/Logout.jsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from 'react' 2 | import { useHistory } from 'react-router'; 3 | 4 | const Logout = (props) => { 5 | 6 | 7 | const history = useHistory(); 8 | useEffect(()=>{ 9 | fetch('/logout', { 10 | method: "GET", 11 | headers: { 12 | Accept: 'application/json', 13 | "Content-Type": "application/json" 14 | }, 15 | credentials: "include" 16 | }).then((res)=>{ 17 | props.setIsLogout("1"); 18 | history.push('/'); 19 | if (res.status !== 200) { 20 | const err = new Error(res.error); 21 | throw err; 22 | } 23 | }).catch((err)=>{ 24 | console.log(err) 25 | }) 26 | }); 27 | 28 | return ( 29 |
30 |

31 | Logout 32 |

33 |
34 | ) 35 | } 36 | 37 | export default Logout 38 | -------------------------------------------------------------------------------- /client/src/components/ChatFeature/Messages/Message/Message.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import './Message.css'; 4 | 5 | import ReactEmoji from 'react-emoji'; 6 | 7 | const Message = ({ message: { text, sender }, nameOfUser }) => { 8 | let isSentByCurrentUser = false; 9 | 10 | 11 | 12 | if(sender === nameOfUser) { 13 | isSentByCurrentUser = true; 14 | } 15 | 16 | return ( 17 | isSentByCurrentUser 18 | ? ( 19 |
20 |

{nameOfUser}

21 |
22 |

{ReactEmoji.emojify(text)}

23 |
24 |
25 | ) 26 | : ( 27 |
28 |
29 |

{ReactEmoji.emojify(text)}

30 |
31 |

{sender}

32 |
33 | ) 34 | ); 35 | } 36 | 37 | export default Message; -------------------------------------------------------------------------------- /client/src/components/Error/Errorpage.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { NavLink } from 'react-router-dom'; 3 | import errorbackground from './../../assets/Backgrounds/Fade-In-Background.svg' 4 | import warning from './../../assets/Backgrounds/warning.png' 5 | const Errorpage = () => { 6 | return ( 7 |
8 |
9 |
10 |
11 | 12 |

ERROR 404

13 |

PAGE NOT FOUND

14 |

15 | Go back to Home 16 |

17 |
18 |
19 |
20 | 21 | 22 | 23 |
24 | ) 25 | } 26 | 27 | export default Errorpage 28 | -------------------------------------------------------------------------------- /client/src/components/ChatFeature/Messages/Message/Message.css: -------------------------------------------------------------------------------- 1 | .messageBox { 2 | background: #F3F3F3; 3 | border-radius: 20px; 4 | padding: 5px 20px; 5 | color: white; 6 | display: inline-block; 7 | max-width: 80%; 8 | } 9 | 10 | .messageText { 11 | width: 100%; 12 | letter-spacing: 0; 13 | margin-bottom: 0; 14 | float: left; 15 | font-size: 1.1em; 16 | word-wrap: break-word; 17 | } 18 | 19 | .messageText img { 20 | vertical-align: middle; 21 | } 22 | 23 | .messageContainer { 24 | display: flex; 25 | justify-content: flex-end; 26 | padding: 0 5%; 27 | margin-top: 3px; 28 | } 29 | 30 | .sentText { 31 | display: flex; 32 | align-items: center; 33 | font-family: Helvetica; 34 | color: #828282; 35 | letter-spacing: 0.3px; 36 | } 37 | 38 | .pl-10 { 39 | padding-left: 10px; 40 | } 41 | 42 | .pr-10 { 43 | padding-right: 10px; 44 | } 45 | 46 | .justifyStart { 47 | justify-content: flex-start; 48 | } 49 | 50 | .justifyEnd { 51 | justify-content: flex-end; 52 | } 53 | 54 | .colorWhite { 55 | color: white; 56 | } 57 | 58 | .colorDark { 59 | color: #353535; 60 | } 61 | 62 | .backgroundBlue { 63 | background: #2979FF; 64 | } 65 | 66 | .backgroundLight { 67 | background: #F3F3F3; 68 | } -------------------------------------------------------------------------------- /server/src/models/userSchema.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | const bcrypt = require('bcryptjs'); 3 | const jwt = require('jsonwebtoken'); 4 | const room = require('./roomSchema') 5 | 6 | const userSchema = new mongoose.Schema({ 7 | userName: { 8 | type: String, 9 | required: true 10 | }, 11 | email: { 12 | type: String, 13 | required: true 14 | }, 15 | password: { 16 | type: String, 17 | required: true 18 | }, 19 | roomsJoinedByMe:[ 20 | { 21 | type: mongoose.Schema.Types.ObjectId, 22 | ref: "ROOM" 23 | } 24 | ], 25 | roomsCreatedByMe:[ 26 | { 27 | type: mongoose.Schema.Types.ObjectId, 28 | ref: "ROOM" 29 | }, 30 | ], 31 | tokens: [ 32 | { 33 | token:{ 34 | type: String, 35 | required: true 36 | } 37 | } 38 | ] 39 | }); 40 | 41 | userSchema.pre('save', async function (next) { 42 | console.log('outside'); 43 | if (this.isModified('password')) { 44 | console.log('inside'); 45 | 46 | this.password = await bcrypt.hash(this.password, 12); 47 | console.log(this.password); 48 | } 49 | next(); 50 | }); 51 | 52 | userSchema.methods.generateAuthToken = async function(){ 53 | try { 54 | let currToken = jwt.sign({ _id: this._id}, process.env.SECRET_KEY); 55 | this.tokens = this.tokens.concat({ token: currToken }); 56 | await this.save(); 57 | return currToken; 58 | } catch (error) { 59 | console.log(error); 60 | } 61 | } 62 | 63 | const User = mongoose.model('USER', userSchema); 64 | 65 | module.exports = User; -------------------------------------------------------------------------------- /client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "client", 3 | "version": "0.1.0", 4 | "private": true, 5 | "proxy": "http://localhost:5000/", 6 | "dependencies": { 7 | "@material-ui/core": "^4.11.4", 8 | "@material-ui/icons": "^4.11.2", 9 | "@material-ui/lab": "^4.0.0-alpha.58", 10 | "@monaco-editor/react": "^4.1.3", 11 | "@popperjs/core": "^2.9.2", 12 | "@testing-library/jest-dom": "^5.11.10", 13 | "@testing-library/react": "^11.2.5", 14 | "@testing-library/user-event": "^12.8.3", 15 | "axios": "^0.21.1", 16 | "bootstrap": "^4.6.0", 17 | "dotenv": "^9.0.0", 18 | "jquery": "^3.6.0", 19 | "js-file-download": "^0.4.12", 20 | "notistack": "^1.0.6", 21 | "react": "^17.0.2", 22 | "react-device-detect": "^1.17.0", 23 | "react-dom": "^17.0.2", 24 | "react-emoji": "^0.5.0", 25 | "react-icons": "^4.2.0", 26 | "react-reflex": "^4.0.0", 27 | "react-router-dom": "^5.2.0", 28 | "react-scripts": "4.0.3", 29 | "react-scroll-to-bottom": "^4.1.0", 30 | "socket.io-client": "^4.0.1", 31 | "typewriter-effect": "^2.17.0", 32 | "uuid": "^8.3.2", 33 | "web-vitals": "^1.1.1" 34 | }, 35 | "scripts": { 36 | "start": "react-scripts start", 37 | "build": "react-scripts build", 38 | "test": "react-scripts test", 39 | "eject": "react-scripts eject" 40 | }, 41 | "eslintConfig": { 42 | "extends": [ 43 | "react-app", 44 | "react-app/jest" 45 | ] 46 | }, 47 | "browserslist": { 48 | "production": [ 49 | ">0.2%", 50 | "not dead", 51 | "not op_mini all" 52 | ], 53 | "development": [ 54 | "last 1 chrome version", 55 | "last 1 firefox version", 56 | "last 1 safari version" 57 | ] 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /client/src/App.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react' 2 | import { Route, Switch } from 'react-router-dom' 3 | import "./../node_modules/bootstrap/dist/css/bootstrap.min.css"; 4 | import "./../node_modules/bootstrap/dist/js/bootstrap.bundle"; 5 | import Errorpage from './components/Error/Errorpage'; 6 | import Home from './components/Home/Home'; 7 | import Rooms from './components/Room/Rooms'; 8 | import Room from './components/InsideRoom/Room'; 9 | import { io } from "socket.io-client" 10 | import { SnackbarProvider } from "notistack"; 11 | import CreateAccount from './pages/CreateAccount'; 12 | import LoginPage from './pages/LoginPage'; 13 | import Logout from './pages/Logout'; 14 | 15 | 16 | const App = () => { 17 | 18 | const [socket, setSocket] = useState() 19 | const [nameOfUser, setNameOfUser] = useState("") 20 | // const socket = io("http://localhost:5000"); 21 | const [isLogout, setIsLogout] = useState('0'); 22 | useEffect(() => { 23 | const s = io("http://localhost:5000"); 24 | console.log(s); 25 | setSocket(s); 26 | 27 | return () => { 28 | s.disconnect(); 29 | } 30 | }, []); 31 | 32 | const [isDisconnected, setIsDisconnected] = useState(false); 33 | 34 | useEffect(() => { 35 | 36 | if (isDisconnected===true) { 37 | const s = io("http://localhost:5000"); 38 | console.log(s); 39 | setSocket(s); 40 | console.log("USEEFFECT") 41 | window.location.reload(); 42 | setIsDisconnected(false); 43 | 44 | return () => { 45 | s.disconnect(); 46 | } 47 | } 48 | 49 | }, [isDisconnected]); 50 | 51 | return ( 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | ) 86 | } 87 | 88 | export default App -------------------------------------------------------------------------------- /client/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | SynCode 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
37 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /client/src/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/README.md: -------------------------------------------------------------------------------- 1 | # Getting Started with Create React App 2 | 3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 4 | 5 | ## Available Scripts 6 | 7 | In the project directory, you can run: 8 | 9 | ### `npm start` 10 | 11 | Runs the app in the development mode.\ 12 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 13 | 14 | The page will reload if you make edits.\ 15 | You will also see any lint errors in the console. 16 | 17 | ### `npm test` 18 | 19 | Launches the test runner in the interactive watch mode.\ 20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 21 | 22 | ### `npm run build` 23 | 24 | Builds the app for production to the `build` folder.\ 25 | It correctly bundles React in production mode and optimizes the build for the best performance. 26 | 27 | The build is minified and the filenames include the hashes.\ 28 | Your app is ready to be deployed! 29 | 30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 31 | 32 | ### `npm run eject` 33 | 34 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!** 35 | 36 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 37 | 38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. 39 | 40 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. 41 | 42 | ## Learn More 43 | 44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 45 | 46 | To learn React, check out the [React documentation](https://reactjs.org/). 47 | 48 | ### Code Splitting 49 | 50 | This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting) 51 | 52 | ### Analyzing the Bundle Size 53 | 54 | This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size) 55 | 56 | ### Making a Progressive Web App 57 | 58 | This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app) 59 | 60 | ### Advanced Configuration 61 | 62 | This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration) 63 | 64 | ### Deployment 65 | 66 | This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment) 67 | 68 | ### `npm run build` fails to minify 69 | 70 | This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify) 71 | -------------------------------------------------------------------------------- /client/src/components/Home/Home.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@200&display=swap'); 2 | @import url('https://fonts.googleapis.com/css2?family=Mulish:wght@400;500&display=swap'); 3 | .headerClass{ 4 | background-image: linear-gradient(rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)),url(./../../assets/codeimg2.jpg); 5 | height: 100vh; 6 | -webkit-background-size: cover; 7 | background-size: cover; 8 | background-position:center center; 9 | 10 | } 11 | 12 | .banner-text{ 13 | position: absolute; 14 | top: 50%; 15 | left: 50%; 16 | transform: translate(-50%, -50%); 17 | text-align: center; 18 | } 19 | 20 | .navbar-brand{ 21 | font-family: 'Mulish', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; 22 | font-size: 1.4rem !important; 23 | } 24 | 25 | .nav-link{ 26 | font-family: 'Mulish', 'Poppins', sans-serif; 27 | text-transform: uppercase; 28 | font-size: 1.1rem; 29 | } 30 | 31 | .my-link:hover{ 32 | color: #3498db !important; 33 | } 34 | 35 | .my-link{ 36 | text-decoration: none; 37 | display: inline-block; 38 | } 39 | 40 | .my-link::after{ 41 | content: ""; 42 | display: block; 43 | width: 0; 44 | height: 2px; 45 | background: #1d4762; 46 | transition: width 1s; 47 | } 48 | 49 | .my-link:hover::after{ 50 | width: 100%; 51 | transition: width 1s; 52 | } 53 | 54 | .banner-text p{ 55 | font-family: 'Poppins', sans-serif; 56 | color: #fff; 57 | } 58 | 59 | .banner-btn a{ 60 | border: 1px solid #fff; 61 | border-radius: 50px; 62 | text-transform: uppercase; 63 | text-decoration: none; 64 | padding: 10px 50px; 65 | display: inline-block; 66 | margin-top: 15px; 67 | color: #fff; 68 | 69 | } 70 | 71 | .banner-btn a:hover{ 72 | background:#fed136; 73 | border-color: #fed136; 74 | color: #000; 75 | 76 | } 77 | 78 | /* text-animation */ 79 | 80 | .text-area{ 81 | font-size: 70px; 82 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; 83 | text-transform: uppercase; 84 | font-weight: bold; 85 | } 86 | 87 | .text-area span{ 88 | color: #fed136; 89 | opacity: 0; 90 | transform: translate(0, -100px) rotate(360deg) scale(0); 91 | animation: animate 5s forwards; 92 | 93 | } 94 | 95 | .text-area span{ 96 | display: inline-block; 97 | } 98 | 99 | .text-area span:nth-of-type(2){ 100 | animation-delay: .1s; 101 | } 102 | .text-area span:nth-of-type(3){ 103 | animation-delay: .2s; 104 | } 105 | .text-area span:nth-of-type(4){ 106 | animation-delay: .3s; 107 | } 108 | .text-area span:nth-of-type(5){ 109 | animation-delay: .4s; 110 | } 111 | .text-area span:nth-of-type(6){ 112 | animation-delay: .5s; 113 | } 114 | .text-area span:nth-of-type(7){ 115 | animation-delay: .6s; 116 | } 117 | .text-area span:nth-of-type(8){ 118 | animation-delay: .7s; 119 | } 120 | .text-area span:nth-of-type(9){ 121 | animation-delay: .8s; 122 | } 123 | .text-area span:nth-of-type(10){ 124 | animation-delay: .9s; 125 | } 126 | .text-area span:nth-of-type(11){ 127 | animation-delay: .10s; 128 | } 129 | .text-area span:nth-of-type(12){ 130 | animation-delay: .11s; 131 | } 132 | 133 | @keyframes animate { 134 | 30%{ 135 | transform: translate(0, -50px) rotate(180deg) scale(1); 136 | } 137 | 30%{ 138 | transform: translate(0, 20px) rotate(0deg) scale(0.8); 139 | } 140 | 100%{ 141 | transform: translate(0) rotate(0deg) scale(1); 142 | opacity: 1; 143 | } 144 | } -------------------------------------------------------------------------------- /server/src/router/auth.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | 3 | const router = express.Router(); 4 | const bcrypt = require('bcryptjs'); 5 | const jwt = require('jsonwebtoken'); 6 | 7 | const authenticate = require('../middleware/authenticate'); 8 | 9 | require('../db/connec'); 10 | const User = require('../models/userSchema'); 11 | 12 | 13 | router.post('/register', async (req, res) => { 14 | console.log('Hello'); 15 | console.log(req.body); 16 | const { userName, email, password } = req.body; 17 | 18 | if (!userName || !email || !password) { 19 | console.log('Please enter'); 20 | return res.status(422).json({ error:"Please fill all required fields" }); 21 | } 22 | 23 | try { 24 | const userExists = await User.findOne({ email: email }); 25 | 26 | if(userExists) { 27 | return res.status(422).json({ error:"User with same email already exists" }); 28 | } 29 | const user = new User({ userName, email, password }); 30 | 31 | const userRegistered = await user.save(); 32 | 33 | if(userRegistered) { 34 | res.status(201).json({message:"User registered successfully"}); 35 | } 36 | } catch (error) { 37 | console.log(error); 38 | } 39 | }); 40 | 41 | router.post('/login', async (req, res) => { 42 | const { userName, password } = req.body; 43 | 44 | if (!userName || !password) { 45 | return res.status(422).json({ error:"Please fill all required fields" }); 46 | } 47 | 48 | try { 49 | const userExists = await User.findOne({ userName: userName }); 50 | 51 | if (userExists){ 52 | isMatch = await bcrypt.compare(password, userExists.password); 53 | 54 | const token = await userExists.generateAuthToken(); 55 | console.log(token); 56 | 57 | res.cookie("jwtToken", token, { 58 | expires:new Date(Date.now(), 25892000000), 59 | httpOnly:true 60 | }); 61 | 62 | if (!isMatch) { 63 | res.status(400).json({error: "Invalid credentials"}); 64 | } else { 65 | res.json({message: "Logged In successfully"}); 66 | } 67 | } 68 | else{ 69 | res.status(400).json({error: "Invalid credentials"}); 70 | } 71 | 72 | 73 | } catch (error) { 74 | console.log(error); 75 | } 76 | }); 77 | 78 | router.get('/roomsforuser', authenticate, (req, res) => { 79 | console.log("Hello From Room"); 80 | res.send(req.rootUser); 81 | }); 82 | 83 | router.get('/logout', (req, res) => { 84 | console.log("Loggin out"); 85 | res.clearCookie('jwtToken', {path:'/'}) 86 | res.status(200).send("Logged out successfully"); 87 | }); 88 | 89 | router.get('/inaroom', authenticate, (req, res) => { 90 | console.log("Hello From inside Room"); 91 | res.send(req.rootUser); 92 | }) 93 | 94 | router.get('/checkforUser', (req, res)=>{ 95 | console.log("checking for Token-->"); 96 | try { 97 | console.log("checking userA-->") 98 | console.log(req.cookies) 99 | console.log(Object.keys(req.cookies).length+"length"); 100 | console.log(req.cookies.jwtToken+"-->jwttok"); 101 | if (req.cookies.jwtToken===undefined) { 102 | res.status(200).json({isuser: "0"}); 103 | } 104 | else{ 105 | res.status(200).json({isuser: "1"}); 106 | } 107 | 108 | } catch (error) { 109 | res.status(200).json({message: "Some error occured"}); 110 | } 111 | }) 112 | module.exports = router; -------------------------------------------------------------------------------- /client/src/components/Editor/editor.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Poppins&display=swap'); 2 | body { 3 | margin: 0; 4 | font-family: 'Poppins', sans-serif; 5 | } 6 | 7 | .listButton-dark { 8 | margin: 0; 9 | background-color: #202124; 10 | position: relative; 11 | } 12 | 13 | .listButton-light { 14 | margin: 0; 15 | background-color: #FFFFFE; 16 | position: relative; 17 | } 18 | 19 | .language-name-dark { 20 | padding-left: 1.5%; 21 | color: white; 22 | } 23 | 24 | .language-name-light { 25 | padding-left: 1.5%; 26 | color: dark; 27 | } 28 | 29 | @media only screen and (max-width: 780px) { 30 | .title-doc { 31 | visibility: hidden; 32 | } 33 | .language-name-dark { 34 | padding-left: 2.5%; 35 | color: white; 36 | } 37 | .language-name-light { 38 | padding-left: 2.5%; 39 | color: dark; 40 | } 41 | } 42 | 43 | .select-dark { 44 | -webkit-appearance: none; 45 | -moz-appearance: none; 46 | -ms-appearance: none; 47 | appearance: none; 48 | outline: 0; 49 | box-shadow: none; 50 | border: 0!important; 51 | background: #5c6664; 52 | background-image: none; 53 | padding: 0 .5em; 54 | margin-left: 1.5%; 55 | color: #fff; 56 | cursor: pointer; 57 | font-size: 1em; 58 | } 59 | 60 | .select-light { 61 | -webkit-appearance: none; 62 | -moz-appearance: none; 63 | -ms-appearance: none; 64 | appearance: none; 65 | outline: 0; 66 | box-shadow: none; 67 | border: 0!important; 68 | background: #f5e9e9; 69 | background-image: none; 70 | padding: 0 .5em; 71 | margin-left: 1.5%; 72 | color: black; 73 | cursor: pointer; 74 | font-size: 1em; 75 | } 76 | 77 | .select::-ms-expand { 78 | display: none; 79 | } 80 | 81 | .title-doc { 82 | display: inline; 83 | position: absolute; 84 | left: 45%; 85 | padding-top: 0.25%; 86 | } 87 | 88 | .input-dark { 89 | margin-right: auto; 90 | margin-left: auto; 91 | -webkit-appearance: none; 92 | -moz-appearance: none; 93 | -ms-appearance: none; 94 | appearance: none; 95 | outline: 0; 96 | box-shadow: none; 97 | border: 0!important; 98 | background: #202124; 99 | background-image: none; 100 | padding: 0 .5em; 101 | margin-left: 0.5%; 102 | color: #fff; 103 | cursor: pointer; 104 | font-size: 1em; 105 | } 106 | 107 | .input-light { 108 | -webkit-appearance: none; 109 | -moz-appearance: none; 110 | -ms-appearance: none; 111 | appearance: none; 112 | outline: 0; 113 | box-shadow: none; 114 | border: 0!important; 115 | background: white; 116 | background-image: none; 117 | padding: 0 .5em; 118 | margin-left: 0.5%; 119 | color: black; 120 | cursor: pointer; 121 | font-size: 1em; 122 | } 123 | 124 | .sunIcon { 125 | color: white; 126 | transform: scale(1.25); 127 | margin-top: 0.25%; 128 | margin-left: 1.5%; 129 | cursor: pointer; 130 | } 131 | 132 | .bulbIcon { 133 | transform: scale(1.25); 134 | margin-left: 1.5%; 135 | margin-top: 0.25%; 136 | cursor: pointer; 137 | } 138 | 139 | .checkIcon { 140 | transform: scale(1); 141 | color: white; 142 | position: absolute; 143 | left: 43.5%; 144 | cursor: pointer; 145 | margin-top: 0.35%; 146 | } 147 | 148 | .logoEditor { 149 | font-size: 1.25em; 150 | margin-left: 1.5%; 151 | } 152 | 153 | .mobile-notValid { 154 | display: flex; 155 | justify-content: center; 156 | align-items: center; 157 | flex-direction: column; 158 | text-align: center; 159 | font-family: 'Poppins', sans-serif; 160 | flex-wrap: wrap; 161 | height: 95vh; 162 | } -------------------------------------------------------------------------------- /client/src/components/InsideRoom/Room.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import MyEditor from './../Editor/myEditor'; 3 | import Box from './../EditorBox/Box'; 4 | import axios from "axios"; 5 | import InputBox from './../EditorBox/InputBox'; 6 | import { useSnackbar } from 'notistack'; 7 | 8 | import 'react-reflex/styles.css' 9 | 10 | const Room = (props) => { 11 | 12 | const socket = props.socket; 13 | 14 | 15 | const getLanguageVersion = { 16 | cpp17: "0", // g++ 17 GCC 9.10 17 | java: "3", // JDK 11.0.4 18 | python3: "3", // 3.7.4 19 | go: "3", // 1.13.1 20 | nodejs: "3", // 12.11.1 21 | }; 22 | const getLanguage = { 23 | cpp: "cpp17", 24 | java: "java", 25 | python: "python3", 26 | go: "go", 27 | javascript: "nodejs", 28 | }; 29 | 30 | const [input, setInput] = useState(""); 31 | const [languageInRoom, setlanguageInRoom] = useState("cpp"); 32 | const [output, setoutput] = useState(""); 33 | const [codeInRoom, setcodeInRoom] = useState(""); 34 | const [stats, setstats] = useState(""); 35 | const [RoomFontSize, setRoomFontSize] = useState(""); 36 | const [RoomTheme, setRoomTheme] = useState("vs-dark"); 37 | const [isError, setisError] = useState(false) 38 | const { enqueueSnackbar, closeSnackbar } = useSnackbar(); 39 | 40 | const runCode = async () => { 41 | const script = codeInRoom; 42 | console.log("script:" + script); 43 | console.log("language in room-->" + languageInRoom); 44 | const language = getLanguage[languageInRoom]; 45 | const versionIndex = getLanguageVersion[language] 46 | const stdin = input; 47 | console.log("languageinRunCode" + language); 48 | console.log("versionIndexinRunCode" + versionIndex); 49 | console.log("stdininRunCode" + stdin); 50 | // console.log("URL-->"+`${process.env.REACT_APP_JDOODLE_URL}`); 51 | // console.log("CID-->"+`${process.env.REACT_APP_JDOODLE_CLIENT_ID}`); 52 | // console.log("CSec-->"+`${process.env.REACT_APP_JDOODLE_CLIENT_SECRET}`); 53 | 54 | 55 | const response = await axios({ 56 | method: "POST", 57 | url: `http://localhost:5000/execute`, 58 | data: { 59 | script: script, 60 | language: language, 61 | stdin: stdin, 62 | versionIndex: versionIndex 63 | }, 64 | responseType: "json", 65 | }); 66 | 67 | if (response.status === 200) { 68 | console.log(response); 69 | console.log(response.data); 70 | const data = response.data; 71 | if (data.memory === null || data.cpu === null) { 72 | console.log("in true"); 73 | setisError(true); 74 | enqueueSnackbar('Compilation Error', { 75 | variant: "warning" 76 | }) 77 | setoutput(data.output.substr(1)) 78 | } else { 79 | console.log("in false"); 80 | setisError(false); 81 | enqueueSnackbar('Code executed successfully', { 82 | variant: "success" 83 | }) 84 | setoutput(data.output); 85 | } 86 | const statement1 = `Memory used: ${data.memory} kilobyte(s).\n` 87 | const statement2 = `CPU time: ${data.cpuTime} sec(s).` 88 | var sta = statement1.concat(statement2); 89 | console.log(isError+"--") 90 | setstats(sta); 91 | 92 | } 93 | else { 94 | enqueueSnackbar('Some Error occurred', { 95 | variant: "error" 96 | }) 97 | } 98 | } 99 | 100 | return ( 101 |
102 |
103 | 113 | 114 |
115 | 116 |
117 |
118 | 119 |
120 |
121 | 122 |
123 |
124 | 125 |
126 | 127 |
128 |
129 | ) 130 | } 131 | 132 | export default Room 133 | -------------------------------------------------------------------------------- /client/src/components/Login/Login.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import Avatar from '@material-ui/core/Avatar'; 3 | import Button from '@material-ui/core/Button'; 4 | import CssBaseline from '@material-ui/core/CssBaseline'; 5 | import TextField from '@material-ui/core/TextField'; 6 | import FormControlLabel from '@material-ui/core/FormControlLabel'; 7 | import Checkbox from '@material-ui/core/Checkbox'; 8 | import Link from '@material-ui/core/Link'; 9 | import Grid from '@material-ui/core/Grid'; 10 | import Box from '@material-ui/core/Box'; 11 | import LockOutlinedIcon from '@material-ui/icons/LockOutlined'; 12 | import Typography from '@material-ui/core/Typography'; 13 | import { makeStyles } from '@material-ui/core/styles'; 14 | import Container from '@material-ui/core/Container'; 15 | import {useHistory} from 'react-router-dom' 16 | import { useSnackbar } from 'notistack'; 17 | 18 | function Copyright() { 19 | return ( 20 | 21 | {'Copyright © '} 22 | 23 | SynCode 24 | {' '} 25 | {new Date().getFullYear()} 26 | {'.'} 27 | 28 | ); 29 | } 30 | 31 | const useStyles = makeStyles((theme) => ({ 32 | myclass:{ 33 | paddingTop: theme.spacing(8), 34 | paddingLeft:"0", 35 | paddingRight:"0" 36 | }, 37 | paper: { 38 | marginTop: theme.spacing(0), 39 | display: 'flex', 40 | flexDirection: 'column', 41 | alignItems: 'center', 42 | }, 43 | avatar: { 44 | margin: theme.spacing(1), 45 | backgroundColor: theme.palette.secondary.main, 46 | }, 47 | form: { 48 | width: '100%', // Fix IE 11 issue. 49 | marginTop: theme.spacing(3), 50 | }, 51 | submit: { 52 | margin: theme.spacing(3, 0, 2), 53 | }, 54 | })); 55 | 56 | export default function Login() { 57 | const classes = useStyles(); 58 | 59 | const { enqueueSnackbar, closeSnackbar } = useSnackbar(); 60 | 61 | const [passwordShown, setPasswordShown] = useState(false); 62 | 63 | const showPassword = () => { 64 | setPasswordShown(passwordShown ? false : true); 65 | }; 66 | 67 | const [user, setUser] = useState({ 68 | userName: "", 69 | password: "" 70 | }); 71 | 72 | let name, value; 73 | const handleInputs = (e) => { 74 | name = e.target.name; 75 | value = e.target.value; 76 | 77 | setUser({...user, [name]: value}); 78 | } 79 | 80 | const history = useHistory(); 81 | 82 | const postDataLogin = async (e) => { 83 | e.preventDefault(); 84 | 85 | const { userName, password } = user; 86 | console.log(user); 87 | console.log(userName); 88 | const res = await fetch("/login", { 89 | method: "POST", 90 | headers: { 91 | "Content-Type": "application/json" 92 | }, 93 | body: JSON.stringify({ 94 | userName, password 95 | }) 96 | }) 97 | 98 | console.log("Hello") 99 | 100 | const data = await res.json(); 101 | console.log(res); 102 | console.log(data); 103 | if (res.status===422 || res.status===400 || !data) { 104 | enqueueSnackbar('Invalid Credentials', { 105 | variant: "error" 106 | }) 107 | console.log("Invalid Credentials"); 108 | } 109 | else { 110 | enqueueSnackbar('Logged in successfully', { 111 | variant: "success" 112 | }) 113 | console.log("Logged In Successfull"); 114 | 115 | history.push("/"); 116 | } 117 | } 118 | 119 | 120 | return ( 121 | 122 |
123 |
124 | 125 |
126 | 127 | 128 | 129 | 130 | Sign in 131 | 132 |
133 | 134 | 135 | 146 | 147 | 148 | 159 | 160 | 161 | } 163 | label="Show Password" 164 | /> 165 | 166 | 167 | 177 | 178 | 179 | 180 | Don't have an account? Sign Up 181 | 182 | 183 | 184 |
185 |
186 | 187 | 188 | 189 |
190 |
191 |
192 | )}; -------------------------------------------------------------------------------- /client/src/components/SignUp/SignUp.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import Avatar from '@material-ui/core/Avatar'; 3 | import Button from '@material-ui/core/Button'; 4 | import CssBaseline from '@material-ui/core/CssBaseline'; 5 | import TextField from '@material-ui/core/TextField'; 6 | import FormControlLabel from '@material-ui/core/FormControlLabel'; 7 | import Checkbox from '@material-ui/core/Checkbox'; 8 | import Link from '@material-ui/core/Link'; 9 | import Grid from '@material-ui/core/Grid'; 10 | import Box from '@material-ui/core/Box'; 11 | import LockOutlinedIcon from '@material-ui/icons/LockOutlined'; 12 | import Typography from '@material-ui/core/Typography'; 13 | import { makeStyles } from '@material-ui/core/styles'; 14 | import Container from '@material-ui/core/Container'; 15 | import {useHistory} from 'react-router-dom' 16 | import './signup.css' 17 | 18 | function Copyright() { 19 | return ( 20 | 21 | {'Copyright © '} 22 | 23 | SynCode 24 | {' '} 25 | {new Date().getFullYear()} 26 | {'.'} 27 | 28 | ); 29 | } 30 | 31 | const useStyles = makeStyles((theme) => ({ 32 | myclass:{ 33 | paddingTop: theme.spacing(8), 34 | paddingLeft:"0", 35 | paddingRight:"0" 36 | }, 37 | paper: { 38 | marginTop: theme.spacing(0), 39 | display: 'flex', 40 | flexDirection: 'column', 41 | alignItems: 'center', 42 | }, 43 | avatar: { 44 | margin: theme.spacing(1), 45 | backgroundColor: theme.palette.secondary.main, 46 | }, 47 | form: { 48 | width: '100%', // Fix IE 11 issue. 49 | marginTop: theme.spacing(3), 50 | }, 51 | submit: { 52 | margin: theme.spacing(3, 0, 2), 53 | }, 54 | })); 55 | 56 | export default function SignUp() { 57 | const classes = useStyles(); 58 | 59 | 60 | const [passwordShown, setPasswordShown] = useState(false); 61 | 62 | const showPassword = () => { 63 | setPasswordShown(passwordShown ? false : true); 64 | }; 65 | 66 | const [user, setUser] = useState({ 67 | userName: "", 68 | email: "", 69 | password: "" 70 | }); 71 | 72 | let name, value; 73 | const handleInputs = (e) => { 74 | name = e.target.name; 75 | value = e.target.value; 76 | 77 | setUser({...user, [name]: value}); 78 | } 79 | 80 | const history = useHistory(); 81 | 82 | const postData = async (e) => { 83 | e.preventDefault(); 84 | const { userName, email, password } = user; 85 | console.log(user); 86 | console.log(userName); 87 | console.log(email); 88 | const res = await fetch("/register", { 89 | method: "POST", 90 | headers: { 91 | "Content-Type": "application/json" 92 | }, 93 | body: JSON.stringify({ 94 | userName, email, password 95 | }) 96 | }) 97 | 98 | const data = await res.json(); 99 | console.log(data); 100 | console.log(res); 101 | if (res.status===422 || !data) { 102 | window.alert("Invalid registration request"); 103 | console.log("Invalid registration request"); 104 | } 105 | else { 106 | window.alert("Registration Successfull"); 107 | console.log("Registration Successfull"); 108 | 109 | history.push("/login"); 110 | } 111 | } 112 | 113 | 114 | return ( 115 | 116 |
117 |
118 | 119 |
120 | 121 | 122 | 123 | 124 | Sign up 125 | 126 |
127 | 128 | 129 | 140 | 141 | 142 | 143 | 153 | 154 | 155 | 166 | 167 | 168 | } 170 | label="Show Password" 171 | /> 172 | 173 | 174 | 184 | 185 | 186 | 187 | Already have an account? Sign in 188 | 189 | 190 | 191 |
192 |
193 | 194 | 195 | 196 |
197 |
198 |
199 | )}; -------------------------------------------------------------------------------- /server/src/index.js: -------------------------------------------------------------------------------- 1 | const dotenv = require('dotenv'); 2 | const cors = require('cors'); 3 | const mongoose = require('mongoose'); 4 | const http = require('http'); 5 | const express = require('express'); 6 | const cookieParser = require('cookie-parser'); 7 | const app = express(); 8 | const httpServer = new http.Server(app); 9 | const axios = require("axios"); 10 | 11 | const CLIENT_URL = "http://localhost:3000"; 12 | 13 | app.use( 14 | cors({ 15 | origin: CLIENT_URL, 16 | methods: "GET,HEAD,PUT,PATCH,POST,DELETE", 17 | credentials: true, // allow session cookies from browser to pass throught 18 | }) 19 | ); 20 | 21 | app.use(cookieParser()); 22 | 23 | dotenv.config({path:'./config.env'}); 24 | 25 | app.use(express.json()); 26 | 27 | require('./db/connec'); 28 | 29 | app.use(require('./router/auth')); 30 | 31 | const User = require('./models/userSchema'); 32 | 33 | const PORT = process.env.PORT; 34 | 35 | var rooms = [] 36 | var removeRooms = [] 37 | 38 | const io = require("socket.io")(httpServer, { 39 | cors: { 40 | origin: "http://localhost:3000", 41 | methods: ["GET", "POST"], 42 | }, 43 | }) 44 | 45 | function removingRooms() { 46 | 47 | console.log("ROOMS: " + rooms) 48 | if (removeRooms.length != 0) { 49 | for (let i = 0; i < removeRooms.length; i++) { 50 | if (io.sockets.adapter.rooms[removeRooms[i]] === undefined) { 51 | rooms = rooms.filter(function (item) { 52 | return item !== removeRooms[i] 53 | }) 54 | } 55 | } 56 | } 57 | removeRooms.splice(0,removeRooms.length) 58 | 59 | setTimeout(removingRooms, 60 * 60 * 1000); 60 | } 61 | 62 | function getLastValue(set){ 63 | let value; 64 | for(value of set); 65 | return value; 66 | } 67 | 68 | io.on("connection", socket => { 69 | console.log("COMMECTED SUCCESSFULLY"); 70 | const { id } = socket.client 71 | console.log(`User connected ${id}`) 72 | 73 | // Check if room exists 74 | socket.on('room-id', msg => { 75 | let exists = rooms.includes(msg) 76 | socket.emit('room-check', exists) 77 | 78 | }) 79 | 80 | // If code changes, broadcast to sockets 81 | socket.on('code-change', msg => { 82 | socket.broadcast.to(socket.room).emit('code-update', msg) 83 | 84 | }) 85 | 86 | // Send initial data to last person who joined 87 | socket.on('user-join', msg => { 88 | let room = io.sockets.adapter.rooms.get(socket.room); 89 | let lastPerson = getLastValue(room); 90 | console.log("lastPerson-->" + lastPerson); 91 | io.to(lastPerson).emit('accept-info', msg); 92 | }) 93 | 94 | // Add room to socket 95 | socket.on('join-room', msg => { 96 | console.log("JOINING " + msg.id) 97 | socket.room = msg.id 98 | socket.join(msg.id); 99 | console.log(io.sockets.adapter.rooms); 100 | console.log(io.sockets.adapter.rooms.get(msg.id)); 101 | 102 | let room = io.sockets.adapter.rooms.get(socket.room); 103 | console.log(room); 104 | if (room.size > 1) { 105 | var it = room.values(); 106 | 107 | var first = it.next(); 108 | let user = first.value; 109 | console.log("first-->" + user); 110 | // let user = Object.keys(room.sockets)[0] 111 | io.to(user).emit('request-info', ""); 112 | } 113 | console.log("-----> "+ Object.values(msg)); 114 | socket.emit('receive-message', { sender: 'admin', text: `${msg.nameOfUser}, welcome to room.`}); 115 | socket.broadcast.to(socket.room).emit('receive-message', { sender: 'admin', text: `${msg.nameOfUser} has joined!` }); 116 | io.sockets.in(socket.room).emit('joined-users', room.size) 117 | }) 118 | 119 | socket.on('created-room', msg => { 120 | console.log("CREATED-ROOM " + msg) 121 | rooms.push(msg) 122 | console.log(rooms); 123 | }) 124 | 125 | 126 | // If language changes, broadcast to sockets 127 | socket.on('language-change', msg => { 128 | io.sockets.in(socket.room).emit('language-update', msg) 129 | }) 130 | 131 | // If title changes, broadcast to sockets 132 | socket.on('title-change', msg => { 133 | io.sockets.in(socket.room).emit('title-update', msg) 134 | }) 135 | 136 | socket.on('sendMessage', ({message, sender}) => { 137 | io.to(socket.room).emit('receive-message', { sender: sender, text: message }); 138 | }); 139 | 140 | // If connection is lost 141 | socket.on('disconnect', () => { 142 | console.log(`User ${id} disconnected`) 143 | }) 144 | 145 | socket.on('leaving', (msg)=>{ 146 | try { 147 | let room = io.sockets.adapter.rooms.get(socket.room) 148 | io.sockets.in(socket.room).emit('joined-users', room.size - 1) 149 | socket.broadcast.to(socket.room).emit('receive-message', { sender: 'admin', text: `${msg.nameOfUser} has left!` }); 150 | if (room.size === 1) { 151 | console.log("Leaving Room " + socket.room) 152 | socket.leave(socket.room) 153 | removeRooms.push(socket.room) 154 | } 155 | } 156 | catch (error) { 157 | console.log("Leaving error") 158 | } 159 | }) 160 | 161 | // Check if there is no one in the room, remove the room if true 162 | socket.on('disconnecting', () => { 163 | try { 164 | let room = io.sockets.adapter.rooms.get(socket.room) 165 | io.sockets.in(socket.room).emit('joined-users', room.size - 1) 166 | if (room.size === 1) { 167 | console.log("Leaving Room " + socket.room) 168 | socket.leave(socket.room) 169 | removeRooms.push(socket.room) 170 | } 171 | } 172 | catch (error) { 173 | console.log("Disconnect error") 174 | } 175 | }) 176 | }) 177 | 178 | app.get('/', (req, res) => { 179 | res.send(`Welcome`); 180 | }); 181 | 182 | app.post('/execute', async (req, res)=>{ 183 | console.log(req.body); 184 | const { script, language, stdin, versionIndex } = req.body; 185 | 186 | const response = await axios({ 187 | method: "POST", 188 | url: process.env.JDOODLE_URL, 189 | data: { 190 | script: script, 191 | stdin: stdin, 192 | language: language, 193 | versionIndex: versionIndex, 194 | clientId: process.env.JDOODLE_CLIENT_ID, 195 | clientSecret: process.env.JDOODLE_CLIENT_SECRET 196 | }, 197 | responseType: "json", 198 | }); 199 | 200 | console.log("RESPONSE from jdoodle--->" + response.data); 201 | res.json(response.data); 202 | }) 203 | 204 | console.log('Hello world from server IndexJS'); 205 | removingRooms(); 206 | httpServer.listen(PORT, () => { 207 | console.log(`port ${PORT}`); 208 | }); 209 | -------------------------------------------------------------------------------- /client/src/components/Room/Rooms.jsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react'; 2 | import { NavLink } from 'react-router-dom'; 3 | import { useHistory } from 'react-router-dom'; 4 | import {v4 as uuidV4} from "uuid"; 5 | import roombackground from './../../assets/Backgrounds/rooms.svg' 6 | import Button from '@material-ui/core/Button'; 7 | import './Rooms.css'; 8 | import Typewriter from 'typewriter-effect'; 9 | 10 | const Rooms = (props) => { 11 | 12 | const history = useHistory(); 13 | const [userData, setUserData] = useState({}); 14 | 15 | const checkForAuthentication = async () => { 16 | try { 17 | const res = await fetch('/roomsforuser', { 18 | method: "GET", 19 | headers: { 20 | Accept: 'application/json', 21 | "Content-Type": "application/json" 22 | }, 23 | credentials: "include" 24 | }); 25 | 26 | const data = await res.json(); 27 | setUserData(data); 28 | props.setNameOfUser(data.userName); 29 | 30 | if (!(res.status === 200)) { 31 | throw new Error(res.error); 32 | } 33 | } catch (error) { 34 | console.log("NO LOGIN"); 35 | console.log(error); 36 | history.push("/login"); 37 | } 38 | } 39 | 40 | const [roomCode, setroomCode] = useState(""); 41 | 42 | const generateRoomCode = () => { 43 | let text = uuidV4(); 44 | setroomCode(text) 45 | } 46 | 47 | useEffect(() => { 48 | checkForAuthentication(); 49 | 50 | }, []); 51 | 52 | const socket = props.socket; 53 | 54 | useEffect(() => { 55 | if (roomCode !== "") { 56 | socket.emit('created-room', roomCode) 57 | console.log('CREATED-ROOM') 58 | history.push(`/room/${roomCode}`) 59 | } 60 | 61 | }, [roomCode]); 62 | 63 | const [joinRoom, setJoinRoom] = useState(""); 64 | const [roomLink, setRoomLink] = useState(""); 65 | 66 | const generateJoinRoomCode = () => { 67 | if (joinRoom!=="") { 68 | setRoomLink(joinRoom); 69 | } 70 | 71 | } 72 | 73 | useEffect(() => { 74 | if (roomLink !== "") { 75 | socket.emit('create-room', roomLink); 76 | console.log('JOINED-ROOM'); 77 | history.push(`/room/${roomLink}`); 78 | } 79 | 80 | }, [roomLink]); 81 | 82 | 83 | return ( 84 |
85 | 86 | 103 | 104 |
105 |
106 |
107 |

Hey!! {userData.userName} 108 | { 110 | typewriter 111 | .typeString("Create a new room") 112 | .pauseFor(1000) 113 | .deleteAll() 114 | .typeString("Join your friend's room") 115 | .pauseFor(1000) 116 | .deleteAll() 117 | .start(); 118 | }} 119 | 120 | options={{autoStart: true, loop:true}} 121 | /> 122 |

123 | 124 |

125 | 128 | 131 |

132 |
133 |
134 |
135 |
136 | 137 | 170 |
171 |
172 | ); 173 | } 174 | 175 | export default Rooms; 176 | -------------------------------------------------------------------------------- /client/src/components/Home/Home.jsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react' 2 | import { Link } from 'react-router-dom'; 3 | import './Home.css'; 4 | import { NavLink } from 'react-router-dom'; 5 | import { 6 | BrowserView, 7 | MobileView 8 | } from "react-device-detect"; 9 | 10 | const Home = (props) => { 11 | 12 | const [Isuser, setIsuser] = useState("0") 13 | 14 | const checkForUser= async () => { 15 | try { 16 | const res = await fetch('/checkforUser', { 17 | method: "GET", 18 | headers: { 19 | Accept: 'application/json', 20 | "Content-Type": "application/json" 21 | }, 22 | credentials: "include" 23 | }); 24 | 25 | const data = await res.json(); 26 | // console.log(data.isuser); 27 | setIsuser(data.isuser); 28 | if (!(res.status === 200)) { 29 | throw new Error(res.error); 30 | } 31 | } catch (error) { 32 | console.log(error); 33 | } 34 | } 35 | 36 | useEffect(()=>{ 37 | checkForUser(); 38 | }, []) 39 | 40 | useEffect(() => { 41 | if (props.isLogout==="1") { 42 | // props.setIsLogout("0") 43 | window.location.reload(); 44 | } 45 | }, [props.isLogout]) 46 | 47 | return ( 48 | <> 49 | 50 |
51 | 52 | 113 | 114 |
115 |
116 |
117 |
118 | C 119 | O 120 | D 121 | E  122 | &  123 | D 124 | I 125 | S 126 | C 127 | U 128 | S 129 | S 130 | 131 |
132 | 133 |

134 | Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, 135 | when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap 136 |

137 | 138 |

139 | {Isuser==='0' 140 | ? 141 | Login 142 | : 143 | Login 144 | 145 | } 146 | {/* Login */} 147 | {Isuser==='0' 148 | ? 149 | Room 150 | : 151 | Room 152 | 153 | } 154 | {/* Room */} 155 |

156 |
157 |
158 |
159 | {/* 160 |

Login

161 |

Sign up

162 |

Room

163 | */} 164 |
165 |
166 | 167 |
168 |

Dear user, unfortunately this app is not supported in MobileView.

169 |

Kindly use on a Desktop.

170 |
171 |
172 | 173 | ) 174 | } 175 | 176 | export default Home 177 | -------------------------------------------------------------------------------- /client/src/assets/Backgrounds/Fade-In-Background.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | -------------------------------------------------------------------------------- /client/src/components/Editor/myEditor.jsx: -------------------------------------------------------------------------------- 1 | import React, { useRef, useState, useEffect } from 'react'; 2 | import { NavLink} from "react-router-dom"; 3 | import { useParams } from "react-router-dom"; 4 | import Editor from "@monaco-editor/react" 5 | import { IconContext } from "react-icons"; 6 | import { 7 | BrowserView, 8 | MobileView 9 | } from "react-device-detect"; 10 | import { useHistory } from 'react-router-dom'; 11 | import { useSnackbar } from 'notistack'; 12 | import IconButton from '@material-ui/core/IconButton'; 13 | import Brightness7RoundedIcon from '@material-ui/icons/Brightness7Rounded'; 14 | import Brightness4RoundedIcon from '@material-ui/icons/Brightness4Rounded'; 15 | import { RiCheckFill } from 'react-icons/ri'; 16 | import ShareRoundedIcon from '@material-ui/icons/ShareRounded'; 17 | import Messages from '../ChatFeature/Messages/Messages'; 18 | import Input from '../ChatFeature/Input/Input'; 19 | import GetAppRoundedIcon from '@material-ui/icons/GetAppRounded'; 20 | import PublishRoundedIcon from '@material-ui/icons/PublishRounded'; 21 | import ExitToAppRoundedIcon from '@material-ui/icons/ExitToAppRounded'; 22 | import fileDownload from 'js-file-download' 23 | import PlayArrowRoundedIcon from '@material-ui/icons/PlayArrowRounded'; 24 | 25 | const MyEditor = (props) => { 26 | 27 | const socket = props.socket; 28 | const history = useHistory(); 29 | 30 | const [theme, setTheme] = useState("vs-dark"); 31 | 32 | const [language, setLanguage] = useState("cpp") 33 | // Check if editor is ready 34 | const [isEditorReady, setIsEditorReady] = useState(false) 35 | // Send chunks of code on change 36 | const [editorCode, seteditorCode] = useState("") 37 | // Set value of editor 38 | const [value, setValue] = useState('') 39 | const [valid, setValid] = useState(false) 40 | const [sendInitialData, setSendInitialData] = useState(false) 41 | const [users, setUsers] = useState(0) 42 | const [title, setTitle] = useState("Untitled") 43 | const [titleInfo, setTitleInfo] = useState("Untitled") 44 | const [titleChange, setTitleChange] = useState(false) 45 | const [fileExtensionValue, setfileExtensionValue] = useState(0) 46 | 47 | const [currentUsers, setcurrentUsers] = useState(''); 48 | const [message, setMessage] = useState(''); 49 | const [messages, setMessages] = useState([]); 50 | const [fontsize, setFontsize] = useState("16px") 51 | 52 | const { enqueueSnackbar, closeSnackbar } = useSnackbar(); 53 | 54 | let { id } = useParams(); 55 | 56 | // Check if room exists 57 | 58 | useEffect(() => { 59 | if (socket===undefined) { 60 | props.setIsDisconnected(true); 61 | history.push("/"); 62 | } else { 63 | socket.emit('room-id', id) 64 | setValid(true) 65 | } 66 | return ()=>{ 67 | 68 | } 69 | }, []) 70 | 71 | // Ref for editor 72 | const editorRef = useRef() 73 | 74 | // Called on initialization, adds ref 75 | const handleEditorDidMount = (_, editor) => { 76 | setIsEditorReady(true); 77 | editorRef.current = editor 78 | } 79 | 80 | // Called whenever there is a change in the editor 81 | const handleEditorChange = (value, event) => { 82 | seteditorCode(value) 83 | props.setcodeInRoom(value) 84 | }; 85 | 86 | // For theme of code editor 87 | const toggleTheme = () => { 88 | if (theme==="light") { 89 | enqueueSnackbar('Changed to Dark mode',{ 90 | variant:"success" 91 | }); 92 | } 93 | else{ 94 | enqueueSnackbar('Changed to Light mode',{ 95 | variant:"success" 96 | }); 97 | } 98 | setTheme(theme === "light" ? "vs-dark" : "light") 99 | props.setRoomTheme(theme === "light" ? "vs-dark" : "light") 100 | } 101 | 102 | //for copying room code 103 | const copyRoomCode = () => { 104 | navigator.clipboard.writeText(id); 105 | enqueueSnackbar(`Room-code copied! Share this code with your friends and Code with them!🤩`, { 106 | variant:"success" 107 | }); 108 | } 109 | 110 | // If language changes on one socket, emit to all other 111 | useEffect(() => { 112 | if (socket===undefined) { 113 | props.setIsDisconnected(true); 114 | history.push("/"); 115 | } else { 116 | socket.emit('language-change', language) 117 | } 118 | 119 | }, [language]) 120 | 121 | 122 | // If there is a code change on a socket, emit to all other 123 | useEffect(() => { 124 | if (socket===undefined) { 125 | history.push("/"); 126 | } else { 127 | socket.emit('code-change', editorCode) 128 | } 129 | 130 | }, [editorCode]) 131 | 132 | // If there is a title change on a socket, emit to all other 133 | useEffect(() => { 134 | if (socket===undefined) { 135 | props.setIsDisconnected(true); 136 | history.push("/"); 137 | } else { 138 | socket.emit('title-change', title) 139 | } 140 | 141 | }, [title]) 142 | 143 | 144 | // Recieve code, title and language changes 145 | useEffect(() => { 146 | if (socket===undefined) { 147 | props.setIsDisconnected(true); 148 | history.push("/"); 149 | } 150 | else{ 151 | socket.on('code-update', (data) => { 152 | setValue(data) 153 | props.setcodeInRoom(data.code) 154 | }) 155 | socket.on('language-update', (data) => { 156 | setLanguage(data) 157 | props.setlanguageInRoom(data) 158 | }) 159 | 160 | socket.on('title-update', (data) => { 161 | setTitleInfo(data) 162 | }) 163 | 164 | socket.on('receive-message', message => { 165 | setMessages(messages => [...messages, message]); 166 | }); 167 | 168 | socket.on('room-check', (data) => { 169 | if (data === false) { 170 | setValid(false) 171 | } else { 172 | socket.emit('join-room', { id, nameOfUser: props.nameOfUser }) 173 | } 174 | 175 | }) 176 | 177 | socket.on('request-info', (data) => { 178 | setSendInitialData(true) 179 | }) 180 | 181 | // Triggered if new user joins 182 | socket.on('accept-info', (data) => { 183 | setTitleInfo(data.title) 184 | setLanguage(data.language) 185 | props.setlanguageInRoom(data.language) 186 | setValue(data.code) 187 | props.setcodeInRoom(data.code) 188 | }) 189 | 190 | // Update participants 191 | socket.on('joined-users', (data) => { 192 | setUsers(data) 193 | }) 194 | } 195 | 196 | }, []) 197 | 198 | 199 | // If a new user join, send him current language and title used by other sockets. 200 | useEffect(() => { 201 | if (socket===undefined) { 202 | props.setIsDisconnected(true); 203 | history.push("/") 204 | } else { 205 | if (sendInitialData === true) { 206 | socket.emit('user-join', { code: editorCode, title: title, language: language }) 207 | setSendInitialData(false) 208 | } 209 | } 210 | 211 | }, [sendInitialData]) 212 | 213 | const languages = ["cpp", "python", "javascript", "c", "java", "go"] 214 | const languageExtension = ["cpp", "py", "js", "c", "java", "go"] 215 | const fontSizes = ["10px", "12px", "14px", "16px", "18px", "20px", "22px", "24px", "26px", "28px", "30px"] 216 | 217 | const changeLanguage = (e) => { 218 | setLanguage(languages[e.target.value]) 219 | props.setlanguageInRoom(languages[e.target.value]) 220 | setfileExtensionValue(e.target.value) 221 | } 222 | 223 | const changeFontSize = (e) => { 224 | setFontsize(fontSizes[e.target.value]) 225 | props.setRoomFontSize(fontSizes[e.target.value]) 226 | } 227 | 228 | const titleUpdating = (e) => { 229 | setTitleInfo(e.target.value) 230 | setTitleChange(true) 231 | } 232 | 233 | const leaveRoom = (e) =>{ 234 | if (socket===undefined) { 235 | props.setIsDisconnected(true); 236 | history.push("/"); 237 | } else { 238 | socket.emit('leaving', {nameOfUser: props.nameOfUser}); 239 | socket.disconnect(); 240 | props.setIsDisconnected(true); 241 | history.push("/"); 242 | } 243 | } 244 | 245 | const sendMessage = (event) => { 246 | event.preventDefault(); 247 | 248 | if (message) { 249 | socket.emit('sendMessage', { message, sender: props.nameOfUser }); 250 | setMessage(""); 251 | } 252 | } 253 | 254 | const titleUpdated = (e) => { 255 | setTitle(titleInfo) 256 | setTitleChange(false) 257 | } 258 | 259 | const downloadCode = (e) =>{ 260 | e.preventDefault(); 261 | fileDownload(editorCode, `${title}.${languageExtension[fileExtensionValue]}`) 262 | } 263 | 264 | const showFile = async (e) => { 265 | e.preventDefault() 266 | const reader = new FileReader() 267 | reader.onload = async (e) => { 268 | const text = (e.target.result) 269 | setValue(text) 270 | props.setcodeInRoom(text) 271 | seteditorCode(text) 272 | // alert(text) 273 | }; 274 | reader.readAsText(e.target.files[0]) 275 | } 276 | 277 | const hiddenFileInput = React.useRef(null); 278 | 279 | const handleUpload = event => { 280 | hiddenFileInput.current.click(); 281 | }; 282 | 283 | 284 | return ( 285 | <> 286 | 287 | 288 | 393 | 394 |
395 |
396 | 407 |
408 |
409 |
410 | 411 | 412 | 413 |
414 |
415 | 416 | 417 |
418 |
419 | 420 |
421 |

Dear user, unfortunately this app is not supported in MobileView.

422 |

Kindly use on a Desktop.

423 |
424 |
425 | 426 | ); 427 | 428 | } 429 | 430 | export default MyEditor; -------------------------------------------------------------------------------- /client/src/assets/Backgrounds/rooms.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /server/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "server", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@mapbox/node-pre-gyp": { 8 | "version": "1.0.3", 9 | "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.3.tgz", 10 | "integrity": "sha512-9dTIfQW8HVCxLku5QrJ/ysS/b2MdYngs9+/oPrOTLvp3TrggdANYVW2h8FGJGDf0J7MYfp44W+c90cVJx+ASuA==", 11 | "requires": { 12 | "detect-libc": "^1.0.3", 13 | "https-proxy-agent": "^5.0.0", 14 | "make-dir": "^3.1.0", 15 | "node-fetch": "^2.6.1", 16 | "nopt": "^5.0.0", 17 | "npmlog": "^4.1.2", 18 | "rimraf": "^3.0.2", 19 | "semver": "^7.3.4", 20 | "tar": "^6.1.0" 21 | }, 22 | "dependencies": { 23 | "semver": { 24 | "version": "7.3.5", 25 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", 26 | "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", 27 | "requires": { 28 | "lru-cache": "^6.0.0" 29 | } 30 | } 31 | } 32 | }, 33 | "@types/bson": { 34 | "version": "4.0.3", 35 | "resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.0.3.tgz", 36 | "integrity": "sha512-mVRvYnTOZJz3ccpxhr3wgxVmSeiYinW+zlzQz3SXWaJmD1DuL05Jeq7nKw3SnbKmbleW5qrLG5vdyWe/A9sXhw==", 37 | "requires": { 38 | "@types/node": "*" 39 | } 40 | }, 41 | "@types/component-emitter": { 42 | "version": "1.2.10", 43 | "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.10.tgz", 44 | "integrity": "sha512-bsjleuRKWmGqajMerkzox19aGbscQX5rmmvvXl3wlIp5gMG1HgkiwPxsN5p070fBDKTNSPgojVbuY1+HWMbFhg==" 45 | }, 46 | "@types/cookie": { 47 | "version": "0.4.0", 48 | "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.0.tgz", 49 | "integrity": "sha512-y7mImlc/rNkvCRmg8gC3/lj87S7pTUIJ6QGjwHR9WQJcFs+ZMTOaoPrkdFA/YdbuqVEmEbb5RdhVxMkAcgOnpg==" 50 | }, 51 | "@types/cors": { 52 | "version": "2.8.10", 53 | "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.10.tgz", 54 | "integrity": "sha512-C7srjHiVG3Ey1nR6d511dtDkCEjxuN9W1HWAEjGq8kpcwmNM6JJkpC0xvabM7BXTG2wDq8Eu33iH9aQKa7IvLQ==" 55 | }, 56 | "@types/mongodb": { 57 | "version": "3.6.12", 58 | "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.12.tgz", 59 | "integrity": "sha512-49aEzQD5VdHPxyd5dRyQdqEveAg9LanwrH8RQipnMuulwzKmODXIZRp0umtxi1eBUfEusRkoy8AVOMr+kVuFog==", 60 | "requires": { 61 | "@types/bson": "*", 62 | "@types/node": "*" 63 | } 64 | }, 65 | "@types/node": { 66 | "version": "14.14.37", 67 | "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.37.tgz", 68 | "integrity": "sha512-XYmBiy+ohOR4Lh5jE379fV2IU+6Jn4g5qASinhitfyO71b/sCo6MKsMLF5tc7Zf2CE8hViVQyYSobJNke8OvUw==" 69 | }, 70 | "abbrev": { 71 | "version": "1.1.1", 72 | "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", 73 | "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" 74 | }, 75 | "accepts": { 76 | "version": "1.3.7", 77 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", 78 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", 79 | "requires": { 80 | "mime-types": "~2.1.24", 81 | "negotiator": "0.6.2" 82 | } 83 | }, 84 | "agent-base": { 85 | "version": "6.0.2", 86 | "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", 87 | "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", 88 | "requires": { 89 | "debug": "4" 90 | }, 91 | "dependencies": { 92 | "debug": { 93 | "version": "4.3.1", 94 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", 95 | "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", 96 | "requires": { 97 | "ms": "2.1.2" 98 | } 99 | }, 100 | "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 | } 106 | }, 107 | "ansi-regex": { 108 | "version": "2.1.1", 109 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", 110 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" 111 | }, 112 | "aproba": { 113 | "version": "1.2.0", 114 | "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", 115 | "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" 116 | }, 117 | "are-we-there-yet": { 118 | "version": "1.1.5", 119 | "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", 120 | "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", 121 | "requires": { 122 | "delegates": "^1.0.0", 123 | "readable-stream": "^2.0.6" 124 | } 125 | }, 126 | "array-flatten": { 127 | "version": "1.1.1", 128 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 129 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" 130 | }, 131 | "axios": { 132 | "version": "0.21.1", 133 | "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", 134 | "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", 135 | "requires": { 136 | "follow-redirects": "^1.10.0" 137 | } 138 | }, 139 | "balanced-match": { 140 | "version": "1.0.2", 141 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 142 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" 143 | }, 144 | "base64-arraybuffer": { 145 | "version": "0.1.4", 146 | "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz", 147 | "integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI=" 148 | }, 149 | "base64id": { 150 | "version": "2.0.0", 151 | "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", 152 | "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==" 153 | }, 154 | "bcrypt": { 155 | "version": "5.0.1", 156 | "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.0.1.tgz", 157 | "integrity": "sha512-9BTgmrhZM2t1bNuDtrtIMVSmmxZBrJ71n8Wg+YgdjHuIWYF7SjjmCPZFB+/5i/o/PIeRpwVJR3P+NrpIItUjqw==", 158 | "requires": { 159 | "@mapbox/node-pre-gyp": "^1.0.0", 160 | "node-addon-api": "^3.1.0" 161 | } 162 | }, 163 | "bcryptjs": { 164 | "version": "2.4.3", 165 | "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", 166 | "integrity": "sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=" 167 | }, 168 | "bl": { 169 | "version": "2.2.1", 170 | "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", 171 | "integrity": "sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==", 172 | "requires": { 173 | "readable-stream": "^2.3.5", 174 | "safe-buffer": "^5.1.1" 175 | } 176 | }, 177 | "bluebird": { 178 | "version": "3.5.1", 179 | "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", 180 | "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" 181 | }, 182 | "body-parser": { 183 | "version": "1.19.0", 184 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", 185 | "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", 186 | "requires": { 187 | "bytes": "3.1.0", 188 | "content-type": "~1.0.4", 189 | "debug": "2.6.9", 190 | "depd": "~1.1.2", 191 | "http-errors": "1.7.2", 192 | "iconv-lite": "0.4.24", 193 | "on-finished": "~2.3.0", 194 | "qs": "6.7.0", 195 | "raw-body": "2.4.0", 196 | "type-is": "~1.6.17" 197 | } 198 | }, 199 | "brace-expansion": { 200 | "version": "1.1.11", 201 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 202 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 203 | "requires": { 204 | "balanced-match": "^1.0.0", 205 | "concat-map": "0.0.1" 206 | } 207 | }, 208 | "bson": { 209 | "version": "1.1.6", 210 | "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.6.tgz", 211 | "integrity": "sha512-EvVNVeGo4tHxwi8L6bPj3y3itEvStdwvvlojVxxbyYfoaxJ6keLgrTuKdyfEAszFK+H3olzBuafE0yoh0D1gdg==" 212 | }, 213 | "buffer-equal-constant-time": { 214 | "version": "1.0.1", 215 | "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", 216 | "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" 217 | }, 218 | "bytes": { 219 | "version": "3.1.0", 220 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", 221 | "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" 222 | }, 223 | "chownr": { 224 | "version": "2.0.0", 225 | "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", 226 | "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" 227 | }, 228 | "code-point-at": { 229 | "version": "1.1.0", 230 | "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", 231 | "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" 232 | }, 233 | "component-emitter": { 234 | "version": "1.3.0", 235 | "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", 236 | "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" 237 | }, 238 | "concat-map": { 239 | "version": "0.0.1", 240 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 241 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" 242 | }, 243 | "console-control-strings": { 244 | "version": "1.1.0", 245 | "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", 246 | "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" 247 | }, 248 | "content-disposition": { 249 | "version": "0.5.3", 250 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", 251 | "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", 252 | "requires": { 253 | "safe-buffer": "5.1.2" 254 | } 255 | }, 256 | "content-type": { 257 | "version": "1.0.4", 258 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 259 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" 260 | }, 261 | "cookie": { 262 | "version": "0.4.0", 263 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", 264 | "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" 265 | }, 266 | "cookie-parser": { 267 | "version": "1.4.5", 268 | "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.5.tgz", 269 | "integrity": "sha512-f13bPUj/gG/5mDr+xLmSxxDsB9DQiTIfhJS/sqjrmfAWiAN+x2O4i/XguTL9yDZ+/IFDanJ+5x7hC4CXT9Tdzw==", 270 | "requires": { 271 | "cookie": "0.4.0", 272 | "cookie-signature": "1.0.6" 273 | } 274 | }, 275 | "cookie-signature": { 276 | "version": "1.0.6", 277 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 278 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" 279 | }, 280 | "core-util-is": { 281 | "version": "1.0.2", 282 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 283 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 284 | }, 285 | "cors": { 286 | "version": "2.8.5", 287 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", 288 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", 289 | "requires": { 290 | "object-assign": "^4", 291 | "vary": "^1" 292 | } 293 | }, 294 | "debug": { 295 | "version": "2.6.9", 296 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 297 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 298 | "requires": { 299 | "ms": "2.0.0" 300 | } 301 | }, 302 | "delegates": { 303 | "version": "1.0.0", 304 | "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", 305 | "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" 306 | }, 307 | "denque": { 308 | "version": "1.5.0", 309 | "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.0.tgz", 310 | "integrity": "sha512-CYiCSgIF1p6EUByQPlGkKnP1M9g0ZV3qMIrqMqZqdwazygIA/YP2vrbcyl1h/WppKJTdl1F85cXIle+394iDAQ==" 311 | }, 312 | "depd": { 313 | "version": "1.1.2", 314 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 315 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" 316 | }, 317 | "destroy": { 318 | "version": "1.0.4", 319 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 320 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" 321 | }, 322 | "detect-libc": { 323 | "version": "1.0.3", 324 | "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", 325 | "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" 326 | }, 327 | "dotenv": { 328 | "version": "8.2.0", 329 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", 330 | "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==" 331 | }, 332 | "ecdsa-sig-formatter": { 333 | "version": "1.0.11", 334 | "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", 335 | "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", 336 | "requires": { 337 | "safe-buffer": "^5.0.1" 338 | } 339 | }, 340 | "ee-first": { 341 | "version": "1.1.1", 342 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 343 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 344 | }, 345 | "encodeurl": { 346 | "version": "1.0.2", 347 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 348 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" 349 | }, 350 | "engine.io": { 351 | "version": "5.0.0", 352 | "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-5.0.0.tgz", 353 | "integrity": "sha512-BATIdDV3H1SrE9/u2BAotvsmjJg0t1P4+vGedImSs1lkFAtQdvk4Ev1y4LDiPF7BPWgXWEG+NDY+nLvW3UrMWw==", 354 | "requires": { 355 | "accepts": "~1.3.4", 356 | "base64id": "2.0.0", 357 | "cookie": "~0.4.1", 358 | "cors": "~2.8.5", 359 | "debug": "~4.3.1", 360 | "engine.io-parser": "~4.0.0", 361 | "ws": "~7.4.2" 362 | }, 363 | "dependencies": { 364 | "cookie": { 365 | "version": "0.4.1", 366 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", 367 | "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" 368 | }, 369 | "debug": { 370 | "version": "4.3.1", 371 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", 372 | "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", 373 | "requires": { 374 | "ms": "2.1.2" 375 | } 376 | }, 377 | "ms": { 378 | "version": "2.1.2", 379 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 380 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 381 | } 382 | } 383 | }, 384 | "engine.io-parser": { 385 | "version": "4.0.2", 386 | "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.2.tgz", 387 | "integrity": "sha512-sHfEQv6nmtJrq6TKuIz5kyEKH/qSdK56H/A+7DnAuUPWosnIZAS2NHNcPLmyjtY3cGS/MqJdZbUjW97JU72iYg==", 388 | "requires": { 389 | "base64-arraybuffer": "0.1.4" 390 | } 391 | }, 392 | "escape-html": { 393 | "version": "1.0.3", 394 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 395 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" 396 | }, 397 | "etag": { 398 | "version": "1.8.1", 399 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 400 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" 401 | }, 402 | "express": { 403 | "version": "4.17.1", 404 | "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", 405 | "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", 406 | "requires": { 407 | "accepts": "~1.3.7", 408 | "array-flatten": "1.1.1", 409 | "body-parser": "1.19.0", 410 | "content-disposition": "0.5.3", 411 | "content-type": "~1.0.4", 412 | "cookie": "0.4.0", 413 | "cookie-signature": "1.0.6", 414 | "debug": "2.6.9", 415 | "depd": "~1.1.2", 416 | "encodeurl": "~1.0.2", 417 | "escape-html": "~1.0.3", 418 | "etag": "~1.8.1", 419 | "finalhandler": "~1.1.2", 420 | "fresh": "0.5.2", 421 | "merge-descriptors": "1.0.1", 422 | "methods": "~1.1.2", 423 | "on-finished": "~2.3.0", 424 | "parseurl": "~1.3.3", 425 | "path-to-regexp": "0.1.7", 426 | "proxy-addr": "~2.0.5", 427 | "qs": "6.7.0", 428 | "range-parser": "~1.2.1", 429 | "safe-buffer": "5.1.2", 430 | "send": "0.17.1", 431 | "serve-static": "1.14.1", 432 | "setprototypeof": "1.1.1", 433 | "statuses": "~1.5.0", 434 | "type-is": "~1.6.18", 435 | "utils-merge": "1.0.1", 436 | "vary": "~1.1.2" 437 | } 438 | }, 439 | "finalhandler": { 440 | "version": "1.1.2", 441 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", 442 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", 443 | "requires": { 444 | "debug": "2.6.9", 445 | "encodeurl": "~1.0.2", 446 | "escape-html": "~1.0.3", 447 | "on-finished": "~2.3.0", 448 | "parseurl": "~1.3.3", 449 | "statuses": "~1.5.0", 450 | "unpipe": "~1.0.0" 451 | } 452 | }, 453 | "follow-redirects": { 454 | "version": "1.14.0", 455 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.0.tgz", 456 | "integrity": "sha512-0vRwd7RKQBTt+mgu87mtYeofLFZpTas2S9zY+jIeuLJMNvudIgF52nr19q40HOwH5RrhWIPuj9puybzSJiRrVg==" 457 | }, 458 | "forwarded": { 459 | "version": "0.1.2", 460 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", 461 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" 462 | }, 463 | "fresh": { 464 | "version": "0.5.2", 465 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 466 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" 467 | }, 468 | "fs-minipass": { 469 | "version": "2.1.0", 470 | "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", 471 | "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", 472 | "requires": { 473 | "minipass": "^3.0.0" 474 | } 475 | }, 476 | "fs.realpath": { 477 | "version": "1.0.0", 478 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 479 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" 480 | }, 481 | "gauge": { 482 | "version": "2.7.4", 483 | "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", 484 | "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", 485 | "requires": { 486 | "aproba": "^1.0.3", 487 | "console-control-strings": "^1.0.0", 488 | "has-unicode": "^2.0.0", 489 | "object-assign": "^4.1.0", 490 | "signal-exit": "^3.0.0", 491 | "string-width": "^1.0.1", 492 | "strip-ansi": "^3.0.1", 493 | "wide-align": "^1.1.0" 494 | } 495 | }, 496 | "glob": { 497 | "version": "7.1.6", 498 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 499 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 500 | "requires": { 501 | "fs.realpath": "^1.0.0", 502 | "inflight": "^1.0.4", 503 | "inherits": "2", 504 | "minimatch": "^3.0.4", 505 | "once": "^1.3.0", 506 | "path-is-absolute": "^1.0.0" 507 | } 508 | }, 509 | "has-unicode": { 510 | "version": "2.0.1", 511 | "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", 512 | "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" 513 | }, 514 | "http-errors": { 515 | "version": "1.7.2", 516 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", 517 | "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", 518 | "requires": { 519 | "depd": "~1.1.2", 520 | "inherits": "2.0.3", 521 | "setprototypeof": "1.1.1", 522 | "statuses": ">= 1.5.0 < 2", 523 | "toidentifier": "1.0.0" 524 | } 525 | }, 526 | "https-proxy-agent": { 527 | "version": "5.0.0", 528 | "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", 529 | "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", 530 | "requires": { 531 | "agent-base": "6", 532 | "debug": "4" 533 | }, 534 | "dependencies": { 535 | "debug": { 536 | "version": "4.3.1", 537 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", 538 | "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", 539 | "requires": { 540 | "ms": "2.1.2" 541 | } 542 | }, 543 | "ms": { 544 | "version": "2.1.2", 545 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 546 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 547 | } 548 | } 549 | }, 550 | "iconv-lite": { 551 | "version": "0.4.24", 552 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 553 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 554 | "requires": { 555 | "safer-buffer": ">= 2.1.2 < 3" 556 | } 557 | }, 558 | "inflight": { 559 | "version": "1.0.6", 560 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 561 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 562 | "requires": { 563 | "once": "^1.3.0", 564 | "wrappy": "1" 565 | } 566 | }, 567 | "inherits": { 568 | "version": "2.0.3", 569 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 570 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 571 | }, 572 | "ipaddr.js": { 573 | "version": "1.9.1", 574 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 575 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" 576 | }, 577 | "is-fullwidth-code-point": { 578 | "version": "1.0.0", 579 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", 580 | "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", 581 | "requires": { 582 | "number-is-nan": "^1.0.0" 583 | } 584 | }, 585 | "isarray": { 586 | "version": "1.0.0", 587 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 588 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 589 | }, 590 | "jsonwebtoken": { 591 | "version": "8.5.1", 592 | "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", 593 | "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", 594 | "requires": { 595 | "jws": "^3.2.2", 596 | "lodash.includes": "^4.3.0", 597 | "lodash.isboolean": "^3.0.3", 598 | "lodash.isinteger": "^4.0.4", 599 | "lodash.isnumber": "^3.0.3", 600 | "lodash.isplainobject": "^4.0.6", 601 | "lodash.isstring": "^4.0.1", 602 | "lodash.once": "^4.0.0", 603 | "ms": "^2.1.1", 604 | "semver": "^5.6.0" 605 | }, 606 | "dependencies": { 607 | "ms": { 608 | "version": "2.1.3", 609 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 610 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 611 | } 612 | } 613 | }, 614 | "jwa": { 615 | "version": "1.4.1", 616 | "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", 617 | "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", 618 | "requires": { 619 | "buffer-equal-constant-time": "1.0.1", 620 | "ecdsa-sig-formatter": "1.0.11", 621 | "safe-buffer": "^5.0.1" 622 | } 623 | }, 624 | "jws": { 625 | "version": "3.2.2", 626 | "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", 627 | "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", 628 | "requires": { 629 | "jwa": "^1.4.1", 630 | "safe-buffer": "^5.0.1" 631 | } 632 | }, 633 | "kareem": { 634 | "version": "2.3.2", 635 | "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.2.tgz", 636 | "integrity": "sha512-STHz9P7X2L4Kwn72fA4rGyqyXdmrMSdxqHx9IXon/FXluXieaFA6KJ2upcHAHxQPQ0LeM/OjLrhFxifHewOALQ==" 637 | }, 638 | "lodash.includes": { 639 | "version": "4.3.0", 640 | "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", 641 | "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=" 642 | }, 643 | "lodash.isboolean": { 644 | "version": "3.0.3", 645 | "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", 646 | "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=" 647 | }, 648 | "lodash.isinteger": { 649 | "version": "4.0.4", 650 | "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", 651 | "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=" 652 | }, 653 | "lodash.isnumber": { 654 | "version": "3.0.3", 655 | "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", 656 | "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=" 657 | }, 658 | "lodash.isplainobject": { 659 | "version": "4.0.6", 660 | "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", 661 | "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" 662 | }, 663 | "lodash.isstring": { 664 | "version": "4.0.1", 665 | "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", 666 | "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" 667 | }, 668 | "lodash.once": { 669 | "version": "4.1.1", 670 | "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", 671 | "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" 672 | }, 673 | "lru-cache": { 674 | "version": "6.0.0", 675 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", 676 | "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", 677 | "requires": { 678 | "yallist": "^4.0.0" 679 | } 680 | }, 681 | "make-dir": { 682 | "version": "3.1.0", 683 | "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", 684 | "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", 685 | "requires": { 686 | "semver": "^6.0.0" 687 | }, 688 | "dependencies": { 689 | "semver": { 690 | "version": "6.3.0", 691 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", 692 | "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" 693 | } 694 | } 695 | }, 696 | "media-typer": { 697 | "version": "0.3.0", 698 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 699 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" 700 | }, 701 | "memory-pager": { 702 | "version": "1.5.0", 703 | "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", 704 | "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", 705 | "optional": true 706 | }, 707 | "merge-descriptors": { 708 | "version": "1.0.1", 709 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 710 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" 711 | }, 712 | "methods": { 713 | "version": "1.1.2", 714 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 715 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" 716 | }, 717 | "mime": { 718 | "version": "1.6.0", 719 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 720 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" 721 | }, 722 | "mime-db": { 723 | "version": "1.46.0", 724 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.46.0.tgz", 725 | "integrity": "sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ==" 726 | }, 727 | "mime-types": { 728 | "version": "2.1.29", 729 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.29.tgz", 730 | "integrity": "sha512-Y/jMt/S5sR9OaqteJtslsFZKWOIIqMACsJSiHghlCAyhf7jfVYjKBmLiX8OgpWeW+fjJ2b+Az69aPFPkUOY6xQ==", 731 | "requires": { 732 | "mime-db": "1.46.0" 733 | } 734 | }, 735 | "minimatch": { 736 | "version": "3.0.4", 737 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 738 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 739 | "requires": { 740 | "brace-expansion": "^1.1.7" 741 | } 742 | }, 743 | "minipass": { 744 | "version": "3.1.3", 745 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", 746 | "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", 747 | "requires": { 748 | "yallist": "^4.0.0" 749 | } 750 | }, 751 | "minizlib": { 752 | "version": "2.1.2", 753 | "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", 754 | "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", 755 | "requires": { 756 | "minipass": "^3.0.0", 757 | "yallist": "^4.0.0" 758 | } 759 | }, 760 | "mkdirp": { 761 | "version": "1.0.4", 762 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", 763 | "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" 764 | }, 765 | "mongodb": { 766 | "version": "3.6.5", 767 | "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.5.tgz", 768 | "integrity": "sha512-mQlYKw1iGbvJJejcPuyTaytq0xxlYbIoVDm2FODR+OHxyEiMR021vc32bTvamgBjCswsD54XIRwhg3yBaWqJjg==", 769 | "requires": { 770 | "bl": "^2.2.1", 771 | "bson": "^1.1.4", 772 | "denque": "^1.4.1", 773 | "require_optional": "^1.0.1", 774 | "safe-buffer": "^5.1.2", 775 | "saslprep": "^1.0.0" 776 | } 777 | }, 778 | "mongoose": { 779 | "version": "5.12.3", 780 | "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.12.3.tgz", 781 | "integrity": "sha512-frsSR9yeldaRpSUeTegXCSB0Tu5UGq8sHuHBuEV31Jk3COyxlKFQPL7UsdMhxPUCmk74FpOYSmNwxhWBEqgzQg==", 782 | "requires": { 783 | "@types/mongodb": "^3.5.27", 784 | "bson": "^1.1.4", 785 | "kareem": "2.3.2", 786 | "mongodb": "3.6.5", 787 | "mongoose-legacy-pluralize": "1.0.2", 788 | "mpath": "0.8.3", 789 | "mquery": "3.2.5", 790 | "ms": "2.1.2", 791 | "regexp-clone": "1.0.0", 792 | "safe-buffer": "5.2.1", 793 | "sift": "7.0.1", 794 | "sliced": "1.0.1" 795 | }, 796 | "dependencies": { 797 | "ms": { 798 | "version": "2.1.2", 799 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 800 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 801 | }, 802 | "safe-buffer": { 803 | "version": "5.2.1", 804 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 805 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" 806 | } 807 | } 808 | }, 809 | "mongoose-legacy-pluralize": { 810 | "version": "1.0.2", 811 | "resolved": "https://registry.npmjs.org/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz", 812 | "integrity": "sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ==" 813 | }, 814 | "mpath": { 815 | "version": "0.8.3", 816 | "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.8.3.tgz", 817 | "integrity": "sha512-eb9rRvhDltXVNL6Fxd2zM9D4vKBxjVVQNLNijlj7uoXUy19zNDsIif5zR+pWmPCWNKwAtqyo4JveQm4nfD5+eA==" 818 | }, 819 | "mquery": { 820 | "version": "3.2.5", 821 | "resolved": "https://registry.npmjs.org/mquery/-/mquery-3.2.5.tgz", 822 | "integrity": "sha512-VjOKHHgU84wij7IUoZzFRU07IAxd5kWJaDmyUzQlbjHjyoeK5TNeeo8ZsFDtTYnSgpW6n/nMNIHvE3u8Lbrf4A==", 823 | "requires": { 824 | "bluebird": "3.5.1", 825 | "debug": "3.1.0", 826 | "regexp-clone": "^1.0.0", 827 | "safe-buffer": "5.1.2", 828 | "sliced": "1.0.1" 829 | }, 830 | "dependencies": { 831 | "debug": { 832 | "version": "3.1.0", 833 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 834 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", 835 | "requires": { 836 | "ms": "2.0.0" 837 | } 838 | } 839 | } 840 | }, 841 | "ms": { 842 | "version": "2.0.0", 843 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 844 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 845 | }, 846 | "negotiator": { 847 | "version": "0.6.2", 848 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", 849 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" 850 | }, 851 | "node-addon-api": { 852 | "version": "3.1.0", 853 | "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.1.0.tgz", 854 | "integrity": "sha512-flmrDNB06LIl5lywUz7YlNGZH/5p0M7W28k8hzd9Lshtdh1wshD2Y+U4h9LD6KObOy1f+fEVdgprPrEymjM5uw==" 855 | }, 856 | "node-fetch": { 857 | "version": "2.6.1", 858 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", 859 | "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" 860 | }, 861 | "nopt": { 862 | "version": "5.0.0", 863 | "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", 864 | "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", 865 | "requires": { 866 | "abbrev": "1" 867 | } 868 | }, 869 | "npmlog": { 870 | "version": "4.1.2", 871 | "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", 872 | "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", 873 | "requires": { 874 | "are-we-there-yet": "~1.1.2", 875 | "console-control-strings": "~1.1.0", 876 | "gauge": "~2.7.3", 877 | "set-blocking": "~2.0.0" 878 | } 879 | }, 880 | "number-is-nan": { 881 | "version": "1.0.1", 882 | "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", 883 | "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" 884 | }, 885 | "object-assign": { 886 | "version": "4.1.1", 887 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 888 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" 889 | }, 890 | "on-finished": { 891 | "version": "2.3.0", 892 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 893 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 894 | "requires": { 895 | "ee-first": "1.1.1" 896 | } 897 | }, 898 | "once": { 899 | "version": "1.4.0", 900 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 901 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 902 | "requires": { 903 | "wrappy": "1" 904 | } 905 | }, 906 | "parseurl": { 907 | "version": "1.3.3", 908 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 909 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" 910 | }, 911 | "path-is-absolute": { 912 | "version": "1.0.1", 913 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 914 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" 915 | }, 916 | "path-to-regexp": { 917 | "version": "0.1.7", 918 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 919 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" 920 | }, 921 | "process-nextick-args": { 922 | "version": "2.0.1", 923 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", 924 | "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" 925 | }, 926 | "proxy-addr": { 927 | "version": "2.0.6", 928 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", 929 | "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", 930 | "requires": { 931 | "forwarded": "~0.1.2", 932 | "ipaddr.js": "1.9.1" 933 | } 934 | }, 935 | "qs": { 936 | "version": "6.7.0", 937 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", 938 | "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" 939 | }, 940 | "range-parser": { 941 | "version": "1.2.1", 942 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 943 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" 944 | }, 945 | "raw-body": { 946 | "version": "2.4.0", 947 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", 948 | "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", 949 | "requires": { 950 | "bytes": "3.1.0", 951 | "http-errors": "1.7.2", 952 | "iconv-lite": "0.4.24", 953 | "unpipe": "1.0.0" 954 | } 955 | }, 956 | "readable-stream": { 957 | "version": "2.3.7", 958 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", 959 | "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", 960 | "requires": { 961 | "core-util-is": "~1.0.0", 962 | "inherits": "~2.0.3", 963 | "isarray": "~1.0.0", 964 | "process-nextick-args": "~2.0.0", 965 | "safe-buffer": "~5.1.1", 966 | "string_decoder": "~1.1.1", 967 | "util-deprecate": "~1.0.1" 968 | } 969 | }, 970 | "regexp-clone": { 971 | "version": "1.0.0", 972 | "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-1.0.0.tgz", 973 | "integrity": "sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw==" 974 | }, 975 | "require_optional": { 976 | "version": "1.0.1", 977 | "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", 978 | "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==", 979 | "requires": { 980 | "resolve-from": "^2.0.0", 981 | "semver": "^5.1.0" 982 | } 983 | }, 984 | "resolve-from": { 985 | "version": "2.0.0", 986 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", 987 | "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" 988 | }, 989 | "rimraf": { 990 | "version": "3.0.2", 991 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", 992 | "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", 993 | "requires": { 994 | "glob": "^7.1.3" 995 | } 996 | }, 997 | "safe-buffer": { 998 | "version": "5.1.2", 999 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 1000 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 1001 | }, 1002 | "safer-buffer": { 1003 | "version": "2.1.2", 1004 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 1005 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 1006 | }, 1007 | "saslprep": { 1008 | "version": "1.0.3", 1009 | "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", 1010 | "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", 1011 | "optional": true, 1012 | "requires": { 1013 | "sparse-bitfield": "^3.0.3" 1014 | } 1015 | }, 1016 | "semver": { 1017 | "version": "5.7.1", 1018 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 1019 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" 1020 | }, 1021 | "send": { 1022 | "version": "0.17.1", 1023 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", 1024 | "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", 1025 | "requires": { 1026 | "debug": "2.6.9", 1027 | "depd": "~1.1.2", 1028 | "destroy": "~1.0.4", 1029 | "encodeurl": "~1.0.2", 1030 | "escape-html": "~1.0.3", 1031 | "etag": "~1.8.1", 1032 | "fresh": "0.5.2", 1033 | "http-errors": "~1.7.2", 1034 | "mime": "1.6.0", 1035 | "ms": "2.1.1", 1036 | "on-finished": "~2.3.0", 1037 | "range-parser": "~1.2.1", 1038 | "statuses": "~1.5.0" 1039 | }, 1040 | "dependencies": { 1041 | "ms": { 1042 | "version": "2.1.1", 1043 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", 1044 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" 1045 | } 1046 | } 1047 | }, 1048 | "serve-static": { 1049 | "version": "1.14.1", 1050 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", 1051 | "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", 1052 | "requires": { 1053 | "encodeurl": "~1.0.2", 1054 | "escape-html": "~1.0.3", 1055 | "parseurl": "~1.3.3", 1056 | "send": "0.17.1" 1057 | } 1058 | }, 1059 | "set-blocking": { 1060 | "version": "2.0.0", 1061 | "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", 1062 | "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" 1063 | }, 1064 | "setprototypeof": { 1065 | "version": "1.1.1", 1066 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", 1067 | "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" 1068 | }, 1069 | "sift": { 1070 | "version": "7.0.1", 1071 | "resolved": "https://registry.npmjs.org/sift/-/sift-7.0.1.tgz", 1072 | "integrity": "sha512-oqD7PMJ+uO6jV9EQCl0LrRw1OwsiPsiFQR5AR30heR+4Dl7jBBbDLnNvWiak20tzZlSE1H7RB30SX/1j/YYT7g==" 1073 | }, 1074 | "signal-exit": { 1075 | "version": "3.0.3", 1076 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", 1077 | "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" 1078 | }, 1079 | "sliced": { 1080 | "version": "1.0.1", 1081 | "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", 1082 | "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=" 1083 | }, 1084 | "socket.io": { 1085 | "version": "4.0.1", 1086 | "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.0.1.tgz", 1087 | "integrity": "sha512-g8eZB9lV0f4X4gndG0k7YZAywOg1VxYgCUspS4V+sDqsgI/duqd0AW84pKkbGj/wQwxrqrEq+VZrspRfTbHTAQ==", 1088 | "requires": { 1089 | "@types/cookie": "^0.4.0", 1090 | "@types/cors": "^2.8.8", 1091 | "@types/node": ">=10.0.0", 1092 | "accepts": "~1.3.4", 1093 | "base64id": "~2.0.0", 1094 | "debug": "~4.3.1", 1095 | "engine.io": "~5.0.0", 1096 | "socket.io-adapter": "~2.2.0", 1097 | "socket.io-parser": "~4.0.3" 1098 | }, 1099 | "dependencies": { 1100 | "debug": { 1101 | "version": "4.3.1", 1102 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", 1103 | "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", 1104 | "requires": { 1105 | "ms": "2.1.2" 1106 | } 1107 | }, 1108 | "ms": { 1109 | "version": "2.1.2", 1110 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 1111 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 1112 | } 1113 | } 1114 | }, 1115 | "socket.io-adapter": { 1116 | "version": "2.2.0", 1117 | "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.2.0.tgz", 1118 | "integrity": "sha512-rG49L+FwaVEwuAdeBRq49M97YI3ElVabJPzvHT9S6a2CWhDKnjSFasvwAwSYPRhQzfn4NtDIbCaGYgOCOU/rlg==" 1119 | }, 1120 | "socket.io-parser": { 1121 | "version": "4.0.4", 1122 | "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.4.tgz", 1123 | "integrity": "sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g==", 1124 | "requires": { 1125 | "@types/component-emitter": "^1.2.10", 1126 | "component-emitter": "~1.3.0", 1127 | "debug": "~4.3.1" 1128 | }, 1129 | "dependencies": { 1130 | "debug": { 1131 | "version": "4.3.1", 1132 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", 1133 | "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", 1134 | "requires": { 1135 | "ms": "2.1.2" 1136 | } 1137 | }, 1138 | "ms": { 1139 | "version": "2.1.2", 1140 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 1141 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 1142 | } 1143 | } 1144 | }, 1145 | "sparse-bitfield": { 1146 | "version": "3.0.3", 1147 | "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", 1148 | "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=", 1149 | "optional": true, 1150 | "requires": { 1151 | "memory-pager": "^1.0.2" 1152 | } 1153 | }, 1154 | "statuses": { 1155 | "version": "1.5.0", 1156 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", 1157 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" 1158 | }, 1159 | "string-width": { 1160 | "version": "1.0.2", 1161 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", 1162 | "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", 1163 | "requires": { 1164 | "code-point-at": "^1.0.0", 1165 | "is-fullwidth-code-point": "^1.0.0", 1166 | "strip-ansi": "^3.0.0" 1167 | } 1168 | }, 1169 | "string_decoder": { 1170 | "version": "1.1.1", 1171 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 1172 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 1173 | "requires": { 1174 | "safe-buffer": "~5.1.0" 1175 | } 1176 | }, 1177 | "strip-ansi": { 1178 | "version": "3.0.1", 1179 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", 1180 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", 1181 | "requires": { 1182 | "ansi-regex": "^2.0.0" 1183 | } 1184 | }, 1185 | "tar": { 1186 | "version": "6.1.0", 1187 | "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", 1188 | "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", 1189 | "requires": { 1190 | "chownr": "^2.0.0", 1191 | "fs-minipass": "^2.0.0", 1192 | "minipass": "^3.0.0", 1193 | "minizlib": "^2.1.1", 1194 | "mkdirp": "^1.0.3", 1195 | "yallist": "^4.0.0" 1196 | } 1197 | }, 1198 | "toidentifier": { 1199 | "version": "1.0.0", 1200 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", 1201 | "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" 1202 | }, 1203 | "type-is": { 1204 | "version": "1.6.18", 1205 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 1206 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 1207 | "requires": { 1208 | "media-typer": "0.3.0", 1209 | "mime-types": "~2.1.24" 1210 | } 1211 | }, 1212 | "unpipe": { 1213 | "version": "1.0.0", 1214 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 1215 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" 1216 | }, 1217 | "util-deprecate": { 1218 | "version": "1.0.2", 1219 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 1220 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 1221 | }, 1222 | "utils-merge": { 1223 | "version": "1.0.1", 1224 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 1225 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" 1226 | }, 1227 | "vary": { 1228 | "version": "1.1.2", 1229 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 1230 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" 1231 | }, 1232 | "wide-align": { 1233 | "version": "1.1.3", 1234 | "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", 1235 | "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", 1236 | "requires": { 1237 | "string-width": "^1.0.2 || 2" 1238 | } 1239 | }, 1240 | "wrappy": { 1241 | "version": "1.0.2", 1242 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1243 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 1244 | }, 1245 | "ws": { 1246 | "version": "7.4.5", 1247 | "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz", 1248 | "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==" 1249 | }, 1250 | "yallist": { 1251 | "version": "4.0.0", 1252 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", 1253 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" 1254 | } 1255 | } 1256 | } 1257 | --------------------------------------------------------------------------------