From f32e749973a9c3be40c9a0a3328a524506a3dc5f Mon Sep 17 00:00:00 2001 From: sanketshinde3001 Date: Sun, 29 Sep 2024 23:48:05 +0530 Subject: [PATCH] GencodeX by Sanket and Vaishnavi(VS Coders) --- BuildAi/README.md | 15 + BuildAi/backend/.gitignore | 24 + BuildAi/backend/geminiService.js | 144 + BuildAi/backend/package-lock.json | 1281 ++ BuildAi/backend/package.json | 22 + BuildAi/backend/server.js | 255 + BuildAi/frontend/.gitignore | 24 + BuildAi/frontend/README.md | 70 + BuildAi/frontend/package-lock.json | 20320 +++++++++++++++++++ BuildAi/frontend/package.json | 58 + BuildAi/frontend/public/favicon.ico | Bin 0 -> 3870 bytes BuildAi/frontend/public/index.html | 43 + BuildAi/frontend/public/logo192.png | Bin 0 -> 5347 bytes BuildAi/frontend/public/logo512.png | Bin 0 -> 9664 bytes BuildAi/frontend/public/manifest.json | 25 + BuildAi/frontend/public/robots.txt | 3 + BuildAi/frontend/src/App.css | 0 BuildAi/frontend/src/App.js | 25 + BuildAi/frontend/src/App.test.js | 8 + BuildAi/frontend/src/CodeContext.js | 26 + BuildAi/frontend/src/CodeFeatures.js | 170 + BuildAi/frontend/src/CodeFeaturesJs.js | 126 + BuildAi/frontend/src/CodeFeaturesJsquiz.js | 79 + BuildAi/frontend/src/Codeoutput.js | 38 + BuildAi/frontend/src/Home.jsx | 62 + BuildAi/frontend/src/Jseditor.jsx | 366 + BuildAi/frontend/src/Jsquiz.jsx | 445 + BuildAi/frontend/src/MarkdownPreviewer.js | 266 + BuildAi/frontend/src/Voice.jsx | 205 + BuildAi/frontend/src/code.js | 58 + BuildAi/frontend/src/index.css | 3 + BuildAi/frontend/src/index.js | 17 + BuildAi/frontend/src/logo.svg | 1 + BuildAi/frontend/src/reportWebVitals.js | 13 + BuildAi/frontend/src/setupTests.js | 5 + BuildAi/frontend/src/web.jsx | 431 + BuildAi/frontend/tailwind.config.js | 8 + 37 files changed, 24636 insertions(+) create mode 100644 BuildAi/README.md create mode 100644 BuildAi/backend/.gitignore create mode 100644 BuildAi/backend/geminiService.js create mode 100644 BuildAi/backend/package-lock.json create mode 100644 BuildAi/backend/package.json create mode 100644 BuildAi/backend/server.js create mode 100644 BuildAi/frontend/.gitignore create mode 100644 BuildAi/frontend/README.md create mode 100644 BuildAi/frontend/package-lock.json create mode 100644 BuildAi/frontend/package.json create mode 100644 BuildAi/frontend/public/favicon.ico create mode 100644 BuildAi/frontend/public/index.html create mode 100644 BuildAi/frontend/public/logo192.png create mode 100644 BuildAi/frontend/public/logo512.png create mode 100644 BuildAi/frontend/public/manifest.json create mode 100644 BuildAi/frontend/public/robots.txt create mode 100644 BuildAi/frontend/src/App.css create mode 100644 BuildAi/frontend/src/App.js create mode 100644 BuildAi/frontend/src/App.test.js create mode 100644 BuildAi/frontend/src/CodeContext.js create mode 100644 BuildAi/frontend/src/CodeFeatures.js create mode 100644 BuildAi/frontend/src/CodeFeaturesJs.js create mode 100644 BuildAi/frontend/src/CodeFeaturesJsquiz.js create mode 100644 BuildAi/frontend/src/Codeoutput.js create mode 100644 BuildAi/frontend/src/Home.jsx create mode 100644 BuildAi/frontend/src/Jseditor.jsx create mode 100644 BuildAi/frontend/src/Jsquiz.jsx create mode 100644 BuildAi/frontend/src/MarkdownPreviewer.js create mode 100644 BuildAi/frontend/src/Voice.jsx create mode 100644 BuildAi/frontend/src/code.js create mode 100644 BuildAi/frontend/src/index.css create mode 100644 BuildAi/frontend/src/index.js create mode 100644 BuildAi/frontend/src/logo.svg create mode 100644 BuildAi/frontend/src/reportWebVitals.js create mode 100644 BuildAi/frontend/src/setupTests.js create mode 100644 BuildAi/frontend/src/web.jsx create mode 100644 BuildAi/frontend/tailwind.config.js diff --git a/BuildAi/README.md b/BuildAi/README.md new file mode 100644 index 0000000..0fa79d2 --- /dev/null +++ b/BuildAi/README.md @@ -0,0 +1,15 @@ +# GencodeX + +- Add your gemini api keys in backend env file. + +```bash +cd frontend +npm install +npm start +``` + +```bash +cd backend +npm install +node server.js +``` \ No newline at end of file diff --git a/BuildAi/backend/.gitignore b/BuildAi/backend/.gitignore new file mode 100644 index 0000000..2b552a6 --- /dev/null +++ b/BuildAi/backend/.gitignore @@ -0,0 +1,24 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# production +/build + +# misc +.DS_Store +.env.local +.env +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/BuildAi/backend/geminiService.js b/BuildAi/backend/geminiService.js new file mode 100644 index 0000000..1fc111b --- /dev/null +++ b/BuildAi/backend/geminiService.js @@ -0,0 +1,144 @@ +import { GoogleGenerativeAI } from "@google/generative-ai"; +import { config } from "dotenv"; + +config(); + +const GEMINI_API_KEY = process.env.GEMINI_API_KEY || null; + +if (!GEMINI_API_KEY) { + console.error("Api key not found"); +} + +const genAI = new GoogleGenerativeAI(GEMINI_API_KEY); + +// Helper function to make a request to the Gemini API +const makeGeminiRequest = async (prompt) => { + try { + const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" }); + const response = await model.generateContent(prompt); + const text = response.response.text(); + return text; + } catch (error) { + console.error( + "Error in Gemini API request:", + error.response?.data || error.message + ); + } +}; + +// Function to explain code chunkwise +const explainCodeChunkwise = async (htmlCode, cssCode, jsCode) => { + // const combinedCode = `HTML CODE\n${htmlCode}\nCSS CODE\n${cssCode}\nJS CODE\n${jsCode}`; + const prompt = `Analyze the provided HTML, CSS, and JavaScript code. Break down the explanation into blocks, explaining each section individually. Identify the purpose, logic, and important details of each code block. Use Markdown with headings, code blocks, and clear explanations. + +HTML CODE: +${htmlCode} + +CSS CODE: +${cssCode} + +JS CODE: +${jsCode} +`; + return await makeGeminiRequest(prompt); +}; +const explainCodeChunkwisejs = async (jsCode) => { + const prompt = `Analyze the provided JavaScript code. Break down the explanation into blocks, explaining each section individually. Identify the purpose, logic, and important details of each code block. Use Markdown with headings, code blocks, and clear explanations. + + JS CODE: + ${jsCode} + `; + return await makeGeminiRequest(prompt); +}; + +// Function to rewrite the code for HTML, CSS, and JS files +const rewriteCodeFiles = async (htmlCode, cssCode, jsCode) => { + const prompt = `Analyze the provided HTML, CSS, and JavaScript code and rewrite it using best practices in programming. Ensure the logic and variable names remain the same, and split the HTML, CSS, and JavaScript into three distinct blocks (one for each). The code should follow these guidelines: + +Add comments to clarify key parts of the code. +Improve readability and organization by proper indentation and structuring. +Refactor code to follow semantic conventions where applicable (e.g., using appropriate tags and structure in HTML). +Maintain variable and function names as they are, ensuring the code remains recognizable but clean. +Do not optimize the code logic or structure beyond these basic improvements. + + HTML CODE: + ${htmlCode} + + CSS CODE: + ${cssCode} + + JS CODE: + ${jsCode} + `; + + return await makeGeminiRequest(prompt); +}; + +const rewriteCodeFilesjs = async (jsCode) => { + const prompt = `Analyze the provided JavaScript code and rewrite it using best practices in programming. Ensure the logic and variable names remain the same. The code should follow these guidelines: +Add comments to clarify key parts of the code. +Improve readability and organization by proper indentation and structuring. +Refactor code to follow conventions and clean coding practices. +Maintain variable and function names as they are, ensuring the code remains recognizable but clean. + +JS CODE: ${jsCode}`; + + return await makeGeminiRequest(prompt); +}; + +// Function to optimize the code for HTML, CSS, and JS files +const optimizeCodeFiles = async (htmlCode, cssCode, jsCode) => { + const prompt = `Rewrite the provided HTML, CSS, and JavaScript code, optimizing it for both time complexity and space complexity. Consider reducing redundant logic, minimizing DOM manipulation, improving JavaScript algorithms, and streamlining CSS. + Generate three distinct blocks: one for HTML, one for CSS, and one for JavaScript. As you go through each block of code, add comments that explain the improvements you are making. In these comments, make sure to discuss how each change affects performance, scalability, or maintainability, and also mention any relevant trade-offs + Please maintain the functionality and logic of the original code. + Provided code: + HTML CODE: + ${htmlCode} + + CSS CODE: + ${cssCode} + + JS CODE: + ${jsCode} + `; + return await makeGeminiRequest(prompt); +}; +const optimizeCodeFilesjs = async (jsCode) => { + const prompt = `Rewrite the provided JavaScript code, optimizing it for both time complexity and space complexity. Consider reducing redundant logic, + improving algorithms, and minimizing memory usage. + As you go through the code, add comments that explain the improvements you're making. In these comments, discuss how each change affects performance, scalability, or maintainability, and mention any relevant trade-offs. + Please maintain the functionality and logic of the original code. + Provided code: + + JS CODE: +${jsCode}`; + return await makeGeminiRequest(prompt); +}; +const solutionCodeFilesjs = async (jsCode,output) => { + const prompt = `### Question & Code - +${jsCode} + +### Expected Output - +${output} + +### Requirements for the solution: +1. First, verify if the provided code produces the correct output for the given question. + - If the code is correct, provide both time complexity (TC) and space complexity (SC) of the code. + - Suggest a more optimized solution if applicable, explaining why it’s more efficient. + +2. If the code is incorrect: + - Return a new corrected code version. + - Point out mistakes in the user's code with short comments inside the code (explaining what went wrong). + - After fixing the code, give a more optimized solution (if possible) and explain why the new approach is better in terms of efficiency.`; + return await makeGeminiRequest(prompt); +}; + +export { + explainCodeChunkwise, + rewriteCodeFiles, + optimizeCodeFiles, + explainCodeChunkwisejs, + rewriteCodeFilesjs, + optimizeCodeFilesjs, + solutionCodeFilesjs +}; diff --git a/BuildAi/backend/package-lock.json b/BuildAi/backend/package-lock.json new file mode 100644 index 0000000..7bf8a3e --- /dev/null +++ b/BuildAi/backend/package-lock.json @@ -0,0 +1,1281 @@ +{ + "name": "backend", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "backend", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@google/generative-ai": "^0.20.0", + "axios": "^1.7.7", + "cors": "^2.8.5", + "dotenv": "^16.4.5", + "express": "^4.21.0", + "multer": "^1.4.5-lts.1", + "nodemon": "^3.1.7" + } + }, + "node_modules/@google/generative-ai": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@google/generative-ai/-/generative-ai-0.20.0.tgz", + "integrity": "sha512-uJQNDr1sihvBJ9w8B0ESpNdX9aEueAMXgwnTuhTo+LnI7DD0M1KHnOWzxb2l6cM1rRHzvkdgJNNfeybcqg7uVg==", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/append-field": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", + "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==" + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/axios": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", + "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz", + "integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.6.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.10", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==" + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/multer": { + "version": "1.4.5-lts.1", + "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.5-lts.1.tgz", + "integrity": "sha512-ywPWvcDMeH+z9gQq5qYHCCy+ethsk4goepZ45GLD63fOu0YcNecQxi64nDs3qluZB+murG3/D4dJ7+dGctcCQQ==", + "dependencies": { + "append-field": "^1.0.0", + "busboy": "^1.0.0", + "concat-stream": "^1.5.2", + "mkdirp": "^0.5.4", + "object-assign": "^4.1.1", + "type-is": "^1.6.4", + "xtend": "^4.0.0" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/nodemon": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.7.tgz", + "integrity": "sha512-hLj7fuMow6f0lbB0cD14Lz2xNjwsyruH251Pk4t/yIitCFJbmY1myuLlHm/q06aST4jg6EgAh74PIBBrRqpVAQ==", + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^4", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^7.5.3", + "simple-update-notifier": "^2.0.0", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/nodemon/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/nodemon/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", + "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==" + }, + "node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/simple-update-notifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/touch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", + "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==", + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" + }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==" + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + } + } +} diff --git a/BuildAi/backend/package.json b/BuildAi/backend/package.json new file mode 100644 index 0000000..544d353 --- /dev/null +++ b/BuildAi/backend/package.json @@ -0,0 +1,22 @@ +{ + "name": "backend", + "version": "1.0.0", + "description": "", + "main": "index.js", + "type": "module", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "@google/generative-ai": "^0.20.0", + "axios": "^1.7.7", + "cors": "^2.8.5", + "dotenv": "^16.4.5", + "express": "^4.21.0", + "multer": "^1.4.5-lts.1", + "nodemon": "^3.1.7" + } +} diff --git a/BuildAi/backend/server.js b/BuildAi/backend/server.js new file mode 100644 index 0000000..b128013 --- /dev/null +++ b/BuildAi/backend/server.js @@ -0,0 +1,255 @@ +import express from "express"; +import { + explainCodeChunkwise, + explainCodeChunkwisejs, + rewriteCodeFiles, + rewriteCodeFilesjs, + optimizeCodeFiles, + optimizeCodeFilesjs, + solutionCodeFilesjs, +} from "./geminiService.js"; +import cors from "cors"; +const app = express(); +import multer from "multer"; +import { config } from "dotenv"; +import { GoogleGenerativeAI } from "@google/generative-ai"; +const PORT = process.env.PORT || 5000; + +app.use(cors()); +app.use(express.json()); +const upload = multer({ storage: multer.memoryStorage() }); +config(); + +const GEMINI_API_KEY = process.env.GEMINI_API_KEY || null; + +if (!GEMINI_API_KEY) { + console.error("Api key not found"); +} + +const genAI = new GoogleGenerativeAI(GEMINI_API_KEY); + +// API route to explain code chunkwise +app.post("/api/code/explain", async (req, res) => { + const { htmlCode, cssCode, jsCode } = req.body; + // console.log(htmlCode,cssCode,jsCode) + try { + const explanation = await explainCodeChunkwise(htmlCode, cssCode, jsCode); + res.json({ explanation }); + } catch (error) { + console.error("Error explaining code:", error.message); + res.status(500).json({ message: "Failed to explain code" }); + } +}); +app.post("/api/code/js/explain", async (req, res) => { + const { jsCode } = req.body; + // console.log(htmlCode,cssCode,jsCode) + try { + const explanation = await explainCodeChunkwisejs(jsCode); + res.json({ explanation }); + } catch (error) { + console.error("Error explaining code:", error.message); + res.status(500).json({ message: "Failed to explain code" }); + } +}); + +// API route to rewrite the code for all three files +app.post("/api/code/rewrite", async (req, res) => { + const { htmlCode, cssCode, jsCode } = req.body; + + try { + const rewrittenCode = await rewriteCodeFiles(htmlCode, cssCode, jsCode); + res.json({ rewrittenCode }); + } catch (error) { + console.error("Error rewriting code:", error.message); + res.status(500).json({ message: "Failed to rewrite code" }); + } +}); +app.post("/api/code/js/rewrite", async (req, res) => { + const { jsCode } = req.body; + + try { + const rewrittenCode = await rewriteCodeFilesjs(jsCode); + res.json({ rewrittenCode }); + } catch (error) { + console.error("Error rewriting code:", error.message); + res.status(500).json({ message: "Failed to rewrite code" }); + } +}); + +// API route to optimize the code for all three files +app.post("/api/code/optimize", async (req, res) => { + const { htmlCode, cssCode, jsCode } = req.body; + + try { + const optimizedCode = await optimizeCodeFiles(htmlCode, cssCode, jsCode); + res.json({ optimizedCode }); + } catch (error) { + console.error("Error optimizing code:", error.message); + res.status(500).json({ message: "Failed to optimize code" }); + } +}); +app.post("/api/code/js/optimize", async (req, res) => { + const { jsCode } = req.body; + + try { + const optimizedCode = await optimizeCodeFilesjs(jsCode); + res.json({ optimizedCode }); + } catch (error) { + console.error("Error optimizing code:", error.message); + res.status(500).json({ message: "Failed to optimize code" }); + } +}); +app.post("/api/code/js/quiz/submit", async (req, res) => { + const { jsCode, output } = req.body; + + try { + const solutionCode = await solutionCodeFilesjs(jsCode, output); + res.json({ solutionCode }); + } catch (error) { + console.error("Error optimizing code:", error.message); + res.status(500).json({ message: "Failed to optimize code" }); + } +}); + +app.post( + "/api/code/cssredesign", + upload.single("screenshot"), + async (req, res) => { + try { + // Access the CSS code, image, and text from the request + const cssCode = req.body.cssCode; + const htmlCode = req.body.htmlCode; + const screenshot = req.file; // Access the uploaded screenshot as a Buffer + + // Check if the uploaded file is a PNG + if (!screenshot || screenshot.mimetype !== "image/png") { + return res.status(400).json({ message: "Please upload a PNG image." }); + } + + const prompt = `I have the following HTML code and corresponding CSS code. I would like to focus on updating the CSS only to achieve a better user interface while retaining the existing HTML structure, logic, and naming conventions. + Please make the following considerations in your redesign: + 1. Improve the overall visual aesthetics while maintaining usability. + 2. Ensure that the existing classes and IDs in the HTML remain unchanged. + 3. Optimize the CSS for better performance and maintainability without altering any HTML elements or their behaviors. + 4. Enhance responsiveness and cross-browser compatibility if applicable. + + HTML code:\n${htmlCode}\n + CSS code:\n${cssCode}`; + + // const prompt = `what you see in image` + const image = { + inlineData: { + data: screenshot.buffer.toString("base64"), + mimeType: "image/png", + }, + }; + + const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" }); + const result = await model.generateContent([prompt, image]); + const responseText = result.response.text(); // Assuming the API returns a text response + console.log(responseText); + + res.json({ + message: "Data sent to Gemini API successfully", + response: responseText, + }); + } catch (error) { + console.error("Error processing request:", error); + + // If error has field violations, print those details + if ( + error.errorDetails && + error.errorDetails[0] && + error.errorDetails[0].fieldViolations + ) { + console.error( + "Field Violations: ", + error.errorDetails[0].fieldViolations + ); + } + + res + .status(500) + .json({ message: "Internal server error", error: error.message }); + } + } +); +app.post( + "/api/code/imgtocode", + upload.single("screenshot"), + async (req, res) => { + try { + const promptuser = req.body.prompt; + const screenshot = req.file; // Access the uploaded screenshot as a Buffer + + // Check if the uploaded file is a PNG + if (!screenshot || screenshot.mimetype !== "image/png") { + return res.status(400).json({ message: "Please upload a PNG image." }); + } + + const prompt = `Convert the following image into HTML, CSS, and JavaScript code: 1. **Structure:** - Break down the visual elements of the photo into well-structured HTML elements such as "
", "
", "
", "
", " + + +
+ + + + + ); +}; + +export default CodeFeatures; \ No newline at end of file diff --git a/BuildAi/frontend/src/CodeFeaturesJs.js b/BuildAi/frontend/src/CodeFeaturesJs.js new file mode 100644 index 0000000..75e7ab7 --- /dev/null +++ b/BuildAi/frontend/src/CodeFeaturesJs.js @@ -0,0 +1,126 @@ +import React, { useContext, useState } from "react"; +import axios from "axios"; +import { CodeContext } from "./CodeContext"; +const backend_url = process.env.REACT_APP_Backend + +const CodeFeaturesJS = ({ jsCode, setJsCode }) => { + const { + explanation, + setExplanation, + rewrittenCode, + setRewrittenCode, + optimizedCode, + setOptimizedCode, + } = useContext(CodeContext); + + const handleJsChange = (newJsCode) => { + setJsCode(newJsCode); + }; + + const handleExplainCode = async () => { + try { + const response = await axios.post( + `${backend_url}/api/code/js/explain`, + { + jsCode, + }, + { + headers: { + "Content-Type": "application/json", + }, + } + ); + + console.log(response); + setExplanation(response.data.explanation); + setRewrittenCode(""); // Clear rewrittenCode + setOptimizedCode(""); + } catch (error) { + console.error("Error explaining code:", error); + } + }; + + const extractCodeSnippets = (markdown) => { + const jsMatch = markdown.match(/```javascript\s*([\s\S]*?)```/); + + const jsCode = jsMatch ? jsMatch[1].trim() : ""; + + return jsCode; + }; + + const handleRewriteCode = async () => { + try { + const response = await axios.post( + `${backend_url}/api/code/js/rewrite`, + { + jsCode, + }, + { + headers: { + "Content-Type": "application/json", + }, + } + ); + console.log("response.data"); + setRewrittenCode(response.data.rewrittenCode); + setExplanation(""); // Clear explanation + setOptimizedCode(""); + const data = extractCodeSnippets(response.data.rewrittenCode); + // console.log(data.htmlCode) + handleJsChange(data); + } catch (error) { + console.error("Error rewriting code:", error); + } + }; + + const handleOptimizeCode = async () => { + try { + const response = await axios.post( + `${backend_url}/api/code/js/optimize`, + { + jsCode, + }, + { + headers: { + "Content-Type": "application/json", + }, + } + ); + setOptimizedCode(response.data.optimizedCode); + setExplanation(""); // Clear explanation + setRewrittenCode(""); + const data = extractCodeSnippets(response.data.optimizedCode); + // console.log(data.htmlCode) + handleJsChange(data); + } catch (error) { + console.error("Error optimizing code:", error); + } + }; + + return ( +
+
+ + + +
+
+ ); +}; + +export default CodeFeaturesJS; diff --git a/BuildAi/frontend/src/CodeFeaturesJsquiz.js b/BuildAi/frontend/src/CodeFeaturesJsquiz.js new file mode 100644 index 0000000..0c06d22 --- /dev/null +++ b/BuildAi/frontend/src/CodeFeaturesJsquiz.js @@ -0,0 +1,79 @@ +import React, { useContext, useState } from "react"; +import axios from "axios"; +import { CodeContext } from "./CodeContext"; +const backend_url = process.env.REACT_APP_Backend + +const CodeFeaturesJSQuiz = ({ jsCode, setJsCode , Shufflequestion ,output + }) => { + const { + explanation, + setExplanation, + rewrittenCode, + setRewrittenCode, + optimizedCode, + setOptimizedCode, + } = useContext(CodeContext); + + const handleJsChange = (newJsCode) => { + setJsCode(newJsCode); + }; + +const extractCodeSnippets = (markdown) => { + const jsMatch = markdown.match(/```javascript\s*([\s\S]*?)```/); + + const jsCode = jsMatch ? jsMatch[1].trim() : ""; + + return jsCode; + }; + + const handleSubmitCode = async () => { + try { + console.log("here1") + const response = await axios.post( + `${backend_url}/api/code/js/quiz/submit`, + { + jsCode, + output + }, + { + headers: { + "Content-Type": "application/json", + }, + } + ); + + console.log("here1") + console.log(response.data); + setRewrittenCode(response.data.solutionCode); + setExplanation("") + setOptimizedCode("") + // const data = extractCodeSnippets(response.data.rewrittenCode); + // console.log(data.htmlCode) + // handleJsChange(data); + } catch (error) { + console.error("Error rewriting code:", error); + } + }; + + + return ( +
+
+ + +
+
+ ); +}; + +export default CodeFeaturesJSQuiz; diff --git a/BuildAi/frontend/src/Codeoutput.js b/BuildAi/frontend/src/Codeoutput.js new file mode 100644 index 0000000..f7d6af8 --- /dev/null +++ b/BuildAi/frontend/src/Codeoutput.js @@ -0,0 +1,38 @@ +import React, { useContext } from 'react'; +import { CodeContext } from './CodeContext'; +import MarkdownPreviewer from "./MarkdownPreviewer"; + +const ResultsComponent = () => { + // Consume the context to get explanation, rewrittenCode, and optimizedCode + const { explanation, rewrittenCode, optimizedCode } = useContext(CodeContext); + + return ( +
+ {/* Explanation Section */} + {explanation && ( +
+

Explanation of code

+ +
+ )} + + {/* Rewritten Code Section */} + {rewrittenCode && ( +
+

Rewritten Code:

+ +
+ )} + + {/* Optimized Code Section */} + {optimizedCode && ( +
+

Optimized Code:

+ +
+ )} +
+ ); +}; + +export default ResultsComponent; \ No newline at end of file diff --git a/BuildAi/frontend/src/Home.jsx b/BuildAi/frontend/src/Home.jsx new file mode 100644 index 0000000..87cc674 --- /dev/null +++ b/BuildAi/frontend/src/Home.jsx @@ -0,0 +1,62 @@ +import React from 'react'; +import { Link } from 'react-router-dom'; +import { FaJs, FaGlobe, FaGithub } from 'react-icons/fa'; // Importing icons + +const LandingPage = () => { + return ( +
+ {/* Header Section */} +

+ Welcome to GenCodeX +

+

+ Explore our features and learn more about JavaScript and Web Development. +

+ + {/* Main Button Section */} +
+
+ + + + + + +
+ +
+ + + +
+
+ + {/* GitHub Links Section */} +
+ + + + + + +
+ + {/* Footer Section */} +
+ © 2024 GenCodeX. All rights reserved. +
+
+ ); +}; + +export default LandingPage; \ No newline at end of file diff --git a/BuildAi/frontend/src/Jseditor.jsx b/BuildAi/frontend/src/Jseditor.jsx new file mode 100644 index 0000000..dbbded0 --- /dev/null +++ b/BuildAi/frontend/src/Jseditor.jsx @@ -0,0 +1,366 @@ +import React, { useState, useEffect } from "react"; +import html2canvas from "html2canvas"; +import axios from "axios"; +import Editor from "@monaco-editor/react"; +import { + FaPlay, + FaStop, + FaHtml5, + FaCss3Alt, + FaJs, + FaDownload, + FaRedo, +} from "react-icons/fa"; +import CodeFeatures from "./CodeFeatures"; // Import the new CodeFeatures component +import { CodeProvider } from "./CodeContext"; +import ResultsComponent from "./Codeoutput"; +import CodeFeaturesJS from "./CodeFeaturesJs"; +const backend_url = process.env.REACT_APP_Backend; + +function Jseditor() { + const runCode = () => { + try { + // Use Function constructor to run the code and capture console logs + const consoleLog = []; + const originalLog = console.log; + + console.log = (...args) => { + consoleLog.push(args.join(" ")); + }; + + // Create a new function and run the code + const run = new Function(jsCode); + run(); + setOutput(consoleLog.join("\n")); + } catch (error) { + setOutput(error.toString()); + } + }; + + const [activeTab, setActiveTab] = useState("js"); + const [output, setOutput] = useState(""); + const [livePreview, setLivePreview] = useState(false); + const [isRunning, setIsRunning] = useState(false); + const htmlDefault = ` + + + + + + Simple Webpage + + + + +
+

Hello, World!

+ +

Click the button to change this text.

+
+ + + +`; + + const cssDefault = `* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: Arial, sans-serif; + background-color: #f0f0f0; + display: flex; + justify-content: center; + align-items: center; + height: 100vh; +} + +.container { + background-color: #fff; + padding: 20px; + border-radius: 8px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); + text-align: center; +} + +h1 { + color: #333; +} + +button { + padding: 10px 20px; + margin-top: 20px; + margin-bottom: 20px; + background-color: #007BFF; + color: #fff; + border: none; + border-radius: 4px; + cursor: pointer; + transition: background-color 0.3s ease; +} + +button:hover { + background-color: #0056b3; +}`; + + const jsDefault = `function fibonacci(n) { + const sequence = [0, 1]; + + for (let i = 2; i < n; i++) { + sequence.push(sequence[i - 1] + sequence[i - 2]); + } + + return sequence.slice(0, n); +} + +const n = 10; +const result = fibonacci(n); +console.log("Series - "+result); +`; + + const [htmlCode, setHtmlCode] = useState(htmlDefault); + const [cssCode, setCssCode] = useState(cssDefault); + const [jsCode, setJsCode] = useState(jsDefault); + + const extractcssSnippets = (markdown) => { + const cssMatch = markdown.match(/```css\s*([\s\S]*?)```/); + + // Store the extracted code in variables + const cssCode = cssMatch ? cssMatch[1].trim() : ""; + + return cssCode; + }; + + const handleExtraButtonClick = async () => { + const extractedCssCode = cssCode; + const extractedHtmlCode = htmlCode; + const extractedJsCode = jsCode; + + const iframe = document.createElement("iframe"); + iframe.style.position = "absolute"; + iframe.style.top = "-9999px"; // Hide it off-screen + iframe.style.width = "800px"; // Set width + iframe.style.height = "600px"; // Set height + document.body.appendChild(iframe); + + const iframeDocument = + iframe.contentDocument || iframe.contentWindow.document; + + iframeDocument.open(); + iframeDocument.write(` + + + + + + + ${extractedHtmlCode} + + + + `); + iframeDocument.close(); + + // Wait for the iframe to load its content + iframe.onload = async () => { + try { + const canvas = await html2canvas(iframeDocument.body); + canvas.toBlob(async (blob) => { + if (blob) { + const formData = new FormData(); + formData.append("cssCode", extractedCssCode); + formData.append("htmlCode", extractedHtmlCode); + formData.append("screenshot", blob, "screenshot.png"); + + try { + const response = await axios.post( + `${backend_url}/api/code/cssredesign`, + formData, + { + headers: { + "Content-Type": "multipart/form-data", + }, + } + ); + console.log("Response from backend: ", response.response); + const datafromback = response.data.response; + console.log(datafromback); + const finaldata = extractcssSnippets(datafromback); + console.log(finaldata); + + setCssCode(finaldata); + } catch (error) { + console.error("Error uploading data: ", error); + } + } + }, "image/png"); + } catch (error) { + console.error("Error capturing screenshot or sending data:", error); + } finally { + document.body.removeChild(iframe); // Remove the iframe after capturing the screenshot + } + }; + }; + + useEffect(() => { + function hideError(e) { + if ( + e.message === + "ResizeObserver loop completed with undelivered notifications." + ) { + const resizeObserverErrDiv = document.getElementById( + "webpack-dev-server-client-overlay-div" + ); + const resizeObserverErr = document.getElementById( + "webpack-dev-server-client-overlay" + ); + if (resizeObserverErr) { + resizeObserverErr.setAttribute("style", "display: none"); + } + if (resizeObserverErrDiv) { + resizeObserverErrDiv.setAttribute("style", "display: none"); + } + } + } + + window.addEventListener("error", hideError); + return () => { + window.addEventListener("error", hideError); + }; + }, []); + + useEffect(() => { + if (isRunning) { + runCode(); + } else { + console.log("Conditions not met for running code"); + } + }, [jsCode, isRunning]); + + const updateOutput = () => { + runCode(); + }; + + const resetEditor = () => { + setJsCode(""); + if (isRunning) { + updateOutput(); + } + }; + + const downloadCode = () => { + const code = jsCode; + + const blob = new Blob([code], { type: "text/js" }); + const a = document.createElement("a"); + a.href = URL.createObjectURL(blob); + a.download = "code.js"; + a.click(); + }; + + const handleEditorChangejs = (value) => { + // Ensure value exists and is not undefined + if (value !== undefined) { + setJsCode(value); // Update state with the new HTML code + } + }; + + const handleRunButtonClick = () => { + if (isRunning) { + setIsRunning(false); + } else { + setIsRunning(true); + runCode(); + } + }; + + return ( + +
+
+
+ +
+ +
+ +
+ +
+
+ + +
+
+
+ +
+
+ {activeTab === "js" && ( +
+ +
+ )} +
+ +
+ {output} +
+
+ +
+ +
+
+ ); +} + +export default Jseditor; \ No newline at end of file diff --git a/BuildAi/frontend/src/Jsquiz.jsx b/BuildAi/frontend/src/Jsquiz.jsx new file mode 100644 index 0000000..1362060 --- /dev/null +++ b/BuildAi/frontend/src/Jsquiz.jsx @@ -0,0 +1,445 @@ +import React, { useState, useEffect } from "react"; +import html2canvas from "html2canvas"; +import axios from "axios"; +import Editor from "@monaco-editor/react"; +import { FaPlay, FaStop, FaJs, FaDownload, FaRedo } from "react-icons/fa"; +import CodeFeatures from "./CodeFeatures"; // Import the new CodeFeatures component +import { CodeProvider } from "./CodeContext"; +import ResultsComponent from "./Codeoutput"; +import CodeFeaturesJS from "./CodeFeaturesJs"; +import CodeFeaturesJSQuiz from "./CodeFeaturesJsquiz"; +const backend_url = process.env.REACT_APP_Backend; + +function Jsquiz() { + const runCode = () => { + try { + // Use Function constructor to run the code and capture console logs + const consoleLog = []; + const originalLog = console.log; + + console.log = (...args) => { + consoleLog.push(args.join(" ")); + }; + + // Create a new function and run the code + const run = new Function(jsCode); + run(); + setOutput(consoleLog.join("\n")); + } catch (error) { + setOutput(error.toString()); + } + }; + + const [activeTab, setActiveTab] = useState("js"); + const [output, setOutput] = useState(""); + const [isRunning, setIsRunning] = useState(false); + const [jsCode, setJsCode] = useState("loading"); + const [difficulty, setDifficulty] = useState(""); + const [remainingTime, setRemainingTime] = useState(0); + const [isTimerRunning, setIsTimerRunning] = useState(false); + const questions = [ + // Easy Questions + { + question: "// Write a function to find the factorial of a number.", + difficulty: "easy", + }, + { + question: + "// Write a function to generate the Fibonacci sequence up to a given number.", + difficulty: "easy", + }, + { + question: "// Write a function to check if a number is prime.", + difficulty: "easy", + }, + { + question: "// Write a function to check if a string is a palindrome.", + difficulty: "easy", + }, + { + question: "// Write a function to reverse a string.", + difficulty: "easy", + }, + { + question: "// Write a function to find the largest number in an array.", + difficulty: "easy", + }, + { + question: "// Write a function to count the vowels in a string.", + difficulty: "easy", + }, + { + question: "// Write a function to remove duplicates from an array.", + difficulty: "easy", + }, + { + question: "// Write a function to convert Celsius to Fahrenheit.", + difficulty: "easy", + }, + { + question: "// Write a function to sum all numbers in an array.", + difficulty: "easy", + }, + // Medium Questions + { + question: "// Write a function to sort an array using quicksort.", + difficulty: "medium", + }, + { + question: "// Write a function to check if a string is a palindrome.", + difficulty: "medium", + }, + { + question: + "// Write a function to find the first non-repeating character in a string.", + difficulty: "medium", + }, + { + question: + "// Write a function to merge two sorted arrays into one sorted array.", + difficulty: "medium", + }, + { + question: + "// Write a function to implement a simple calculator (add, subtract, multiply, divide).", + difficulty: "medium", + }, + { + question: + "// Write a function to determine if two strings are anagrams of each other.", + difficulty: "medium", + }, + { + question: "// Write a function to rotate an array by k positions.", + difficulty: "medium", + }, + { + question: "// Write a function to find the intersection of two arrays.", + difficulty: "medium", + }, + { + question: "// Write a function to generate all permutations of a string.", + difficulty: "medium", + }, + { + question: "// Write a function to validate a Sudoku board.", + difficulty: "medium", + }, + // Hard Questions + { + question: + "// Write a function to find the longest common subsequence between two strings.", + difficulty: "hard", + }, + { + question: "// Write a function to solve the Tower of Hanoi problem.", + difficulty: "hard", + }, + { + question: "// Write a function to find the shortest path in a maze.", + difficulty: "hard", + }, + { + question: + "// Write a function to implement Dijkstra’s algorithm for finding the shortest path in a graph.", + difficulty: "hard", + }, + { + question: "// Write a function to solve the N-Queens problem.", + difficulty: "hard", + }, + ]; + + useEffect(() => { + function hideError(e) { + if ( + e.message === + "ResizeObserver loop completed with undelivered notifications." + ) { + const resizeObserverErrDiv = document.getElementById( + "webpack-dev-server-client-overlay-div" + ); + const resizeObserverErr = document.getElementById( + "webpack-dev-server-client-overlay" + ); + if (resizeObserverErr) { + resizeObserverErr.setAttribute("style", "display: none"); + } + if (resizeObserverErrDiv) { + resizeObserverErrDiv.setAttribute("style", "display: none"); + } + } + } + + window.addEventListener("error", hideError); + return () => { + window.addEventListener("error", hideError); + }; + }, []); + + const getRandomQuestion = () => { + const randomIndex = Math.floor(Math.random() * questions.length); + console.log(questions[randomIndex]); + return questions[randomIndex]; + }; + // UseEffect to set the random question when the component loads + useEffect(() => { + const selectedQuestion = getRandomQuestion(); + setJsCode(selectedQuestion.question); + setDifficulty(selectedQuestion.difficulty); + + // Set time based on difficulty + let timeInSeconds; + if (selectedQuestion.difficulty === "easy") { + timeInSeconds = 5 * 60; // 5 minutes for easy + } else if (selectedQuestion.difficulty === "medium") { + timeInSeconds = 10 * 60; // 10 minutes for medium + } else if (selectedQuestion.difficulty === "hard") { + timeInSeconds = 20 * 60; // 20 minutes for hard + } + setRemainingTime(timeInSeconds); + }, []); + + const startTimer = () => { + setIsTimerRunning(true); + const timerInterval = setInterval(() => { + setRemainingTime((prevTime) => { + if (prevTime <= 1) { + clearInterval(timerInterval); + setIsTimerRunning(false); + alert("Time's up!"); + return 0; + } + return prevTime - 1; + }); + }, 1000); + }; + + const formatTime = (timeInSeconds) => { + const minutes = Math.floor(timeInSeconds / 60); + const seconds = timeInSeconds % 60; + return `${minutes}:${seconds < 10 ? `0${seconds}` : seconds}`; + }; + + const Shufflequestion = () => { + const selectedQuestion = getRandomQuestion(); + setJsCode(selectedQuestion.question); + setDifficulty(selectedQuestion.difficulty); + + let timeInSeconds; + if (selectedQuestion.difficulty === "easy") { + timeInSeconds = 5 * 60; // 5 minutes for easy + } else if (selectedQuestion.difficulty === "medium") { + timeInSeconds = 10 * 60; // 10 minutes for medium + } else if (selectedQuestion.difficulty === "hard") { + timeInSeconds = 20 * 60; // 20 minutes for hard + } + setRemainingTime(timeInSeconds); + setIsTimerRunning(false); // Reset the timer state + }; + + useEffect(() => { + if (isRunning) { + runCode(); + } else { + console.log("Conditions not met for running code"); + } + }, [jsCode, isRunning]); + + const updateOutput = () => { + runCode(); + }; + + const resetEditor = () => { + setJsCode(""); + if (isRunning) { + updateOutput(); + } + }; + + const downloadCode = () => { + const code = jsCode; + + const blob = new Blob([code], { type: "text/js" }); + const a = document.createElement("a"); + a.href = URL.createObjectURL(blob); + a.download = "code.js"; + a.click(); + }; + + const handleEditorChangejs = (value) => { + if (value !== undefined) { + setJsCode(value); // Update state with the new HTML code + } + }; + + const handleRunButtonClick = () => { + if (isRunning) { + setIsRunning(false); + } else { + setIsRunning(true); + runCode(); + } + }; + + return ( + +
+ {/*
+
+ +

Difficulty: {difficulty}

+

Remaining Time: {formatTime(remainingTime)}

+ + +
+ +
+ +
+ +
+
+ + +
+
+
*/} + +
+
+ +
+

+ Level : {difficulty} +

+

+ Time Left : {formatTime(remainingTime)} +

+
+ + {/* */} +
+ +
+ +
+ +
+ + +
+
+ +
+
+ {activeTab === "js" && ( +
+ +
+ )} +
+ +
+ {output} +
+
+ +
+ +
+
+ ); +} + +export default Jsquiz; \ No newline at end of file diff --git a/BuildAi/frontend/src/MarkdownPreviewer.js b/BuildAi/frontend/src/MarkdownPreviewer.js new file mode 100644 index 0000000..fb5243f --- /dev/null +++ b/BuildAi/frontend/src/MarkdownPreviewer.js @@ -0,0 +1,266 @@ +// import React, { useState } from "react"; +// import { marked } from "marked"; +// import DOMPurify from "dompurify"; +// import { FiCopy,FiCheckCircle } from "react-icons/fi"; + +// const MarkdownPreviewer = ({ markdown }) => { +// // State to manage copy status +// const [copyStatus, setCopyStatus] = useState({ code: "", copied: false }); + +// // Get sanitized HTML from markdown +// const getMarkdownText = () => { +// const rawMarkup = marked(markdown, { breaks: true, gfm: true }); +// return DOMPurify.sanitize(rawMarkup); +// }; + +// // Copy Code Handler +// const copyToClipboard = (code) => { +// navigator.clipboard.writeText(code); +// setCopyStatus({ code, copied: true }); + +// // Reset copy status after 2 seconds +// setTimeout(() => { +// setCopyStatus({ code: "", copied: false }); +// }, 2000); +// }; + +// // Function to render the markdown with code blocks handled separately +// const renderMarkdownWithCodeBlocks = () => { +// const blocks = markdown.split(/(```\w*\n[\s\S]*?```)/g); // Split by code blocks +// return blocks.map((block, index) => { +// // Check if the block is a code block +// const isCodeBlock = block.startsWith("```"); + +// if (isCodeBlock) { +// const codeContent = block +// .replace(/```.*\n/, "") // Remove the language specifier +// .replace(/```$/, ""); // Remove the closing ``` + +// // Extract the file type from the language specifier (if available) +// const language = block.match(/```(\w+)/); +// const fileType = language ? language[1] : "text"; // Default to 'text' if no match + +// return ( +//
+// +//
+//               {codeContent.trim()}
+//             
+//
+// ); +// } + +// return ( +//
+// ); +// }); +// }; + +// return ( +//
+//
+// {renderMarkdownWithCodeBlocks()} +//
+// +//
+// ); +// }; + +// export default MarkdownPreviewer; + + + + + +import React, { useState } from "react"; +import { marked } from "marked"; +import DOMPurify from "dompurify"; +import { FiCopy, FiCheckCircle } from "react-icons/fi"; + +const MarkdownPreviewer = ({ markdown }) => { + // State to manage copy status + const [copyStatus, setCopyStatus] = useState({ code: "", copied: false }); + + // Get sanitized HTML from markdown + const getMarkdownText = () => { + const rawMarkup = marked(markdown, { breaks: true, gfm: true }); + return DOMPurify.sanitize(rawMarkup); + }; + + // Copy Code Handler + const copyToClipboard = (code) => { + navigator.clipboard.writeText(code); + setCopyStatus({ code, copied: true }); + + // Reset copy status after 2 seconds + setTimeout(() => { + setCopyStatus({ code: "", copied: false }); + }, 2000); + }; + + // Function to render the markdown with code blocks handled separately + const renderMarkdownWithCodeBlocks = () => { + const blocks = markdown.split(/(```\w*\n[\s\S]*?```)/g); // Split by code blocks + return blocks.map((block, index) => { + // Check if the block is a code block + const isCodeBlock = block.startsWith("```"); + + if (isCodeBlock) { + const codeContent = block + .replace(/```.*\n/, "") // Remove the language specifier + .replace(/```$/, ""); // Remove the closing ``` + + // Extract the file type from the language specifier (if available) + const language = block.match(/```(\w+)/); + const fileType = language ? language[1] : "text"; // Default to 'text' if no match + + return ( +
+ +
+              {codeContent.trim()}
+            
+
+ ); + } + + return ( +
+ ); + }); + }; + + return ( +
+
+ {renderMarkdownWithCodeBlocks()} +
+ +
+ ); +}; + +export default MarkdownPreviewer; \ No newline at end of file diff --git a/BuildAi/frontend/src/Voice.jsx b/BuildAi/frontend/src/Voice.jsx new file mode 100644 index 0000000..c1c02e9 --- /dev/null +++ b/BuildAi/frontend/src/Voice.jsx @@ -0,0 +1,205 @@ +import React, { useState } from "react"; +import SpeechRecognition, { + useSpeechRecognition, +} from "react-speech-recognition"; +import { AiFillAudio } from "react-icons/ai"; +import { MdCancel } from "react-icons/md"; +import { FaFileUpload } from "react-icons/fa"; // New icon for image upload +import { BsSend } from "react-icons/bs"; // Send button icon + +import axios from "axios"; +const backend_url = process.env.REACT_APP_Backend + +const SpeechToText = ({ + htmlCode, + cssCode, + jsCode, + setHtmlCode, + setCssCode, + setJsCode +}) => { + const { + transcript, + listening, + resetTranscript, + browserSupportsSpeechRecognition, + } = useSpeechRecognition(); + + const [inputText, setInputText] = useState(""); + const [imageText, setImageText] = useState(""); + const [uploadedImage, setUploadedImage] = useState(null); + const [uploadedImageurl, setUploadedImageurl] = useState(null); + const [savedTranscript, setSavedTranscript] = useState(""); // New state to save the transcript + + if (!browserSupportsSpeechRecognition) { + return Browser doesn't support speech recognition.; + } + + const handleInputChange = (e) => { + setInputText(e.target.value); + }; + + + const handleImageUpload = (e) => { + const file = e.target.files[0]; + if (file) { + setUploadedImage(file); // Set the file (not URL) to use in the API call + setUploadedImageurl(URL.createObjectURL(file)); + } + }; + + const extractCodeSnippets = (markdown) => { + const htmlMatch = markdown.match(/```html\s*([\s\S]*?)```/); + const cssMatch = markdown.match(/```css\s*([\s\S]*?)```/); + const jsMatch = markdown.match(/```javascript\s*([\s\S]*?)```/); + + // Store the extracted code in variables + const htmlCode = htmlMatch ? htmlMatch[1].trim() : ""; + const cssCode = cssMatch ? cssMatch[1].trim() : ""; + const jsCode = jsMatch ? jsMatch[1].trim() : ""; + + return { htmlCode, cssCode, jsCode }; + }; + + const sendImageToApi = async () => { + try { + if (!uploadedImage) { + console.log("No image to upload"); + return; + } + + const formData = new FormData(); + + // Append the necessary fields to formData + formData.append("prompt", inputText); + formData.append("screenshot", uploadedImage, uploadedImage.name || "screenshot.png"); // Ensure 'uploadedImage' is a valid File + + // Make the API request + const response = await axios.post( + `${backend_url}/api/code/imgtocode`, + formData, + { + headers: { + "Content-Type": "multipart/form-data", + }, + } + ); + const datafromback = response.data.response; + const data = extractCodeSnippets(datafromback); + setHtmlCode(data.htmlCode) + setCssCode(data.cssCode) + setJsCode(data.jsCode) + // Handle the response + if (response.status === 200) { + console.log("Image and code successfully sent to the API:", response.data); + + } else { + console.log("Failed to send image and code:", response.status); + } + } catch (error) { + console.error("Error uploading the image:", error); + } + }; + + + const handleStartListening = () => { + setSavedTranscript((prev) => prev + " " + transcript); + resetTranscript(); + SpeechRecognition.startListening(); + }; + + const handleRemoveImage = () => { + setUploadedImage(null); // Remove the uploaded image + setImageText(""); // Clear the extracted text + }; + + const handleSendData = () => { + // This is where you'd handle sending the text and image to further processing + const finalText = inputText || savedTranscript + " " + transcript + " " + imageText; + const finalImage = uploadedImage; + + console.log("Sending data for further processing:", { finalText, finalImage }); + + // Clear the textarea and transcript after sending the data + setInputText(""); + setSavedTranscript(""); + resetTranscript(); // Reset SpeechRecognition transcript + setImageText(""); + setUploadedImage(null); + }; + + return ( +
+ {/* Microphone and Status */} +
+ +
+ + {/* Text Area and Uploaded Image */} +
+