diff --git a/.env.example b/.env.example index cc6383c..2098f53 100644 --- a/.env.example +++ b/.env.example @@ -1,3 +1,3 @@ -PRISMA_URL="url comes here" +PRISMA_URL="Url comes here" NEXTAUTH_SECRET=secretishere \ No newline at end of file diff --git a/constants.js b/constants.js index c65b245..2323294 100644 --- a/constants.js +++ b/constants.js @@ -1 +1,3 @@ -export const urlLocal = "http://localhost:3000" +export const urlLocal = process.env.NEXT_PUBLIC_SITE_URL || "http//localhost:3000/" || ""; +console.log("--- PUBLIC URL ==> ", urlLocal); +// export const urlLocal = ""; diff --git a/package-lock.json b/package-lock.json index 7b85d7c..75168bb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,10 +9,14 @@ "version": "0.1.0", "dependencies": { "@prisma/client": "^5.5.2", + "@tensorflow-models/coco-ssd": "^2.2.3", + "@tensorflow/tfjs": "^4.12.0", + "@tensorflow/tfjs-core": "^4.12.0", "next": "14.0.1", "next-auth": "^4.24.4", "react": "^18", "react-dom": "^18", + "react-webcam": "^7.2.0", "socket.io": "^4.7.2", "socket.io-client": "^4.7.2" }, @@ -317,6 +321,125 @@ "tslib": "^2.4.0" } }, + "node_modules/@tensorflow-models/coco-ssd": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@tensorflow-models/coco-ssd/-/coco-ssd-2.2.3.tgz", + "integrity": "sha512-iCLGktG/XhHbP6h2FWxqCKMp/Px0lCp6MZU1fjNhjDHeaWEC9G7S7cZrnPXsfH+NewCM53YShlrHnknxU3SQig==", + "peerDependencies": { + "@tensorflow/tfjs-converter": "^4.10.0", + "@tensorflow/tfjs-core": "^4.10.0" + } + }, + "node_modules/@tensorflow/tfjs": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@tensorflow/tfjs/-/tfjs-4.12.0.tgz", + "integrity": "sha512-POVhMqP1cHRznRzf34mY7fiZEcxOX+4dJBhXxgSOA0Zu1Ttk8WcrGZsXwUMmEnrYwWSfHY56LNQZmWDPfUEBJQ==", + "dependencies": { + "@tensorflow/tfjs-backend-cpu": "4.12.0", + "@tensorflow/tfjs-backend-webgl": "4.12.0", + "@tensorflow/tfjs-converter": "4.12.0", + "@tensorflow/tfjs-core": "4.12.0", + "@tensorflow/tfjs-data": "4.12.0", + "@tensorflow/tfjs-layers": "4.12.0", + "argparse": "^1.0.10", + "chalk": "^4.1.0", + "core-js": "3.29.1", + "regenerator-runtime": "^0.13.5", + "yargs": "^16.0.3" + }, + "bin": { + "tfjs-custom-module": "dist/tools/custom_module/cli.js" + } + }, + "node_modules/@tensorflow/tfjs-backend-cpu": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-cpu/-/tfjs-backend-cpu-4.12.0.tgz", + "integrity": "sha512-xm4/eABnNDjZ9pHbvUxebMt7yy6n2IGNgj8PQjp58MnPgarZdIROqKEbz9fW2BG5318TCkbgf6vK30AJqqukSw==", + "dependencies": { + "@types/seedrandom": "^2.4.28", + "seedrandom": "^3.0.5" + }, + "engines": { + "yarn": ">= 1.3.2" + }, + "peerDependencies": { + "@tensorflow/tfjs-core": "4.12.0" + } + }, + "node_modules/@tensorflow/tfjs-backend-webgl": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-webgl/-/tfjs-backend-webgl-4.12.0.tgz", + "integrity": "sha512-LVBMFg+Qck1CW/NWqR3WOWzIerk0/GdS3HKi3guIZdERJqJLW46TRVBCqllY7a4fpkKsmrIR3yzUeXSBx5DqLA==", + "dependencies": { + "@tensorflow/tfjs-backend-cpu": "4.12.0", + "@types/offscreencanvas": "~2019.3.0", + "@types/seedrandom": "^2.4.28", + "seedrandom": "^3.0.5" + }, + "engines": { + "yarn": ">= 1.3.2" + }, + "peerDependencies": { + "@tensorflow/tfjs-core": "4.12.0" + } + }, + "node_modules/@tensorflow/tfjs-converter": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-converter/-/tfjs-converter-4.12.0.tgz", + "integrity": "sha512-+UDwSO4PhobfmdqZTQQ41vvtEPMuFwZKEEcuS7zhydLK3L7Ro9+ak+rIrlWAHHrTS8knepincW1EpyDDjIkmNw==", + "peerDependencies": { + "@tensorflow/tfjs-core": "4.12.0" + } + }, + "node_modules/@tensorflow/tfjs-core": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-core/-/tfjs-core-4.12.0.tgz", + "integrity": "sha512-5pyJnDQOWOGsjPCgKf7w/7v+RLVUdbsZKjfDIMFbVPPLeHXpuUfOl4rZsZHofKZGtkQgz+oV2//ByanlYBuFLA==", + "dependencies": { + "@types/long": "^4.0.1", + "@types/offscreencanvas": "~2019.7.0", + "@types/seedrandom": "^2.4.28", + "@webgpu/types": "0.1.30", + "long": "4.0.0", + "node-fetch": "~2.6.1", + "seedrandom": "^3.0.5" + }, + "engines": { + "yarn": ">= 1.3.2" + } + }, + "node_modules/@tensorflow/tfjs-core/node_modules/@types/offscreencanvas": { + "version": "2019.7.2", + "resolved": "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.7.2.tgz", + "integrity": "sha512-ujCjOxeA07IbEBQYAkoOI+XFw5sT3nhWJ/xZfPR6reJppDG7iPQPZacQiLTtWH1b3a2NYXWlxvYqa40y/LAixQ==" + }, + "node_modules/@tensorflow/tfjs-data": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-data/-/tfjs-data-4.12.0.tgz", + "integrity": "sha512-ppwkj7XMUPX2EIwAlLmNgyyHNgiJMPyRSNTvNGD0kXlwjkF8lms2mggqTcVHFK6zBtDzMZm/i1Z56d5FUs2otA==", + "dependencies": { + "@types/node-fetch": "^2.1.2", + "node-fetch": "~2.6.1", + "string_decoder": "^1.3.0" + }, + "peerDependencies": { + "@tensorflow/tfjs-core": "4.12.0", + "seedrandom": "^3.0.5" + } + }, + "node_modules/@tensorflow/tfjs-layers": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-layers/-/tfjs-layers-4.12.0.tgz", + "integrity": "sha512-LWK8IOfZjS9nr+lpEDcR7qzQL1l4bcRhjOSembZqwfsc6gYgvkGTxqVFqk21FcvJVM/K5XxYn0ucJqC9pjw1Kg==", + "peerDependencies": { + "@tensorflow/tfjs-core": "4.12.0" + } + }, + "node_modules/@tensorflow/tfjs/node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + }, "node_modules/@types/cookie": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", @@ -330,6 +453,11 @@ "@types/node": "*" } }, + "node_modules/@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" + }, "node_modules/@types/node": { "version": "20.8.10", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.10.tgz", @@ -338,6 +466,20 @@ "undici-types": "~5.26.4" } }, + "node_modules/@types/node-fetch": { + "version": "2.6.8", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.8.tgz", + "integrity": "sha512-nnH5lV9QCMPsbEVdTb5Y+F3GQxLSw1xQgIydrb2gSfEavRPs50FnMr+KUaa+LoPSqibm2N+ZZxH7lavZlAT4GA==", + "dependencies": { + "@types/node": "*", + "form-data": "^4.0.0" + } + }, + "node_modules/@types/offscreencanvas": { + "version": "2019.3.0", + "resolved": "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.3.0.tgz", + "integrity": "sha512-esIJx9bQg+QYF0ra8GnvfianIY8qWB0GBx54PK5Eps6m+xTj86KLavHv6qDhzKcu5UUOgNfJ2pWaIIV7TRUd9Q==" + }, "node_modules/@types/prop-types": { "version": "15.7.9", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.9.tgz", @@ -361,6 +503,16 @@ "integrity": "sha512-s/FPdYRmZR8SjLWGMCuax7r3qCWQw9QKHzXVukAuuIJkXkDRwp+Pu5LMIVFi0Fxbav35WURicYr8u1QsoybnQw==", "dev": true }, + "node_modules/@types/seedrandom": { + "version": "2.4.32", + "resolved": "https://registry.npmjs.org/@types/seedrandom/-/seedrandom-2.4.32.tgz", + "integrity": "sha512-pGzjoMhPpuIxBOMMQMiZ5xMMFQMnXgJAi0SkljX/q6KOFkaSW7yNIXZT8jTpMtEsz72WXE+whu/4fGCn16cjaQ==" + }, + "node_modules/@webgpu/types": { + "version": "0.1.30", + "resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.30.tgz", + "integrity": "sha512-9AXJSmL3MzY8ZL//JjudA//q+2kBRGhLBFpkdGksWIuxrMy81nFrCzj2Am+mbh8WoU6rXmv7cY5E3rdlyru2Qg==" + }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -373,6 +525,28 @@ "node": ">= 0.6" } }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/any-promise": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", @@ -398,6 +572,19 @@ "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", "dev": true }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, "node_modules/autoprefixer": { "version": "10.4.16", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.16.tgz", @@ -551,6 +738,21 @@ } ] }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "node_modules/chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -595,6 +797,43 @@ "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/commander": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", @@ -618,6 +857,16 @@ "node": ">= 0.6" } }, + "node_modules/core-js": { + "version": "3.29.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.29.1.tgz", + "integrity": "sha512-+jwgnhg6cQxKYIIjGtAHq2nwUOolo9eoFZ4sHfUH09BLXBgxnH4gA0zEd+t+BO2cNB8idaBtZFcFTRjQJRJmAw==", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, "node_modules/cors": { "version": "2.8.5", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", @@ -664,6 +913,14 @@ } } }, + "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/didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", @@ -682,6 +939,11 @@ "integrity": "sha512-bg1m8L0n02xRzx4LsTTMbBPiUd9yIR+74iPtS/Ao65CuXvhVZHP0ym1kSdDG3yHFDXqHQQBKujlN1AQ8qZnyFg==", "dev": true }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, "node_modules/engine.io": { "version": "6.5.3", "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.3.tgz", @@ -734,7 +996,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, "engines": { "node": ">=6" } @@ -788,6 +1049,19 @@ "node": ">=8" } }, + "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/fraction.js": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", @@ -830,6 +1104,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, "node_modules/glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", @@ -872,6 +1154,14 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, "node_modules/hasown": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", @@ -933,6 +1223,14 @@ "node": ">=0.10.0" } }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -991,6 +1289,11 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, + "node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -1179,6 +1482,25 @@ } } }, + "node_modules/node-fetch": { + "version": "2.6.13", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.13.tgz", + "integrity": "sha512-StxNAxh15zr77QvvkmveSQ8uCQ4+v5FkvNTj0OESmiHu+VRi/gXArXtkWMElOsOUNLtUEvI4yS+rdtOHZTwlQA==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/node-releases": { "version": "2.0.13", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", @@ -1503,6 +1825,15 @@ "react": "^18.2.0" } }, + "node_modules/react-webcam": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/react-webcam/-/react-webcam-7.2.0.tgz", + "integrity": "sha512-xkrzYPqa1ag2DP+2Q/kLKBmCIfEx49bVdgCCCcZf88oF+0NPEbkwYk3/s/C7Zy0mhM8k+hpdNkBLzxg8H0aWcg==", + "peerDependencies": { + "react": ">=16.2.0", + "react-dom": ">=16.2.0" + } + }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -1529,6 +1860,14 @@ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -1579,6 +1918,25 @@ "queue-microtask": "^1.2.2" } }, + "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/scheduler": { "version": "0.23.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", @@ -1587,6 +1945,11 @@ "loose-envify": "^1.1.0" } }, + "node_modules/seedrandom": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", + "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==" + }, "node_modules/socket.io": { "version": "4.7.2", "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.2.tgz", @@ -1646,6 +2009,11 @@ "node": ">=0.10.0" } }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + }, "node_modules/streamsearch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", @@ -1654,6 +2022,38 @@ "node": ">=10.0.0" } }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/styled-jsx": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", @@ -1698,6 +2098,17 @@ "node": ">=8" } }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", @@ -1789,6 +2200,11 @@ "node": ">=8.0" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, "node_modules/ts-interface-checker": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", @@ -1882,6 +2298,36 @@ "node": ">=10.13.0" } }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -1916,6 +2362,14 @@ "node": ">=0.4.0" } }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "engines": { + "node": ">=10" + } + }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", @@ -1929,6 +2383,31 @@ "engines": { "node": ">= 14" } + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "engines": { + "node": ">=10" + } } } } diff --git a/package.json b/package.json index 565fdce..920a611 100644 --- a/package.json +++ b/package.json @@ -10,10 +10,14 @@ }, "dependencies": { "@prisma/client": "^5.5.2", + "@tensorflow-models/coco-ssd": "^2.2.3", + "@tensorflow/tfjs": "^4.12.0", + "@tensorflow/tfjs-core": "^4.12.0", "next": "14.0.1", "next-auth": "^4.24.4", "react": "^18", "react-dom": "^18", + "react-webcam": "^7.2.0", "socket.io": "^4.7.2", "socket.io-client": "^4.7.2" }, diff --git a/public/ghost.jpg b/public/ghost.jpg new file mode 100644 index 0000000..0eed81d Binary files /dev/null and b/public/ghost.jpg differ diff --git a/public/scream.mp3 b/public/scream.mp3 new file mode 100644 index 0000000..3dd1934 Binary files /dev/null and b/public/scream.mp3 differ diff --git a/src/app/api/auth/[...nextauth]/route.js b/src/app/api/auth/[...nextauth]/route.js index 68be201..9f64f9a 100644 --- a/src/app/api/auth/[...nextauth]/route.js +++ b/src/app/api/auth/[...nextauth]/route.js @@ -1,5 +1,6 @@ import NextAuth from "next-auth"; import CredentialsProvider from "next-auth/providers/credentials"; +import { urlLocal } from "../../../../../constants"; export const authOptions = { providers: [ CredentialsProvider({ @@ -13,7 +14,7 @@ export const authOptions = { // If no error and we have user data, return it const { username, password, type } = credentials; const user = await fetch( - `http://localhost:3000/api/db/getUsers/${username?.trim()}` + urlLocal + `/api/db/getUsers/${username?.trim()}` ) .then((res) => { return res.json(); @@ -26,13 +27,10 @@ export const authOptions = { console.log("-- register failed --"); throw new Error("user already exists"); } - const newUser = await fetch( - `http://localhost:3000/api/db/createUser`, - { - method: "POST", - body: JSON.stringify({ username, password }), - } - ) + const newUser = await fetch(urlLocal + `/api/db/createUser`, { + method: "POST", + body: JSON.stringify({ username, password }), + }) .then((res) => { alert("User registered successfully 👍! Please login"); return res.json(); diff --git a/src/app/question/[examId]/page.js b/src/app/question/[examId]/page.js index bb6dbe0..ff2c7c1 100644 --- a/src/app/question/[examId]/page.js +++ b/src/app/question/[examId]/page.js @@ -1,5 +1,6 @@ import { urlLocal } from "../../../../constants"; import Questions from "../../../components/Questions"; +import ObjectDetect from "../../../components/ObjectDetect"; const getQuestions = async (examId) => { if (!examId) return; const data = await fetch(urlLocal + `/api/db/getQuestions/${examId}`, { @@ -18,6 +19,7 @@ export default async function page({ params }) { return ( <> + ); } diff --git a/src/components/AddQues.js b/src/components/AddQues.js index 5a1d69d..a62cd0d 100644 --- a/src/components/AddQues.js +++ b/src/components/AddQues.js @@ -1,8 +1,9 @@ -"use client" -import { useState } from 'react'; +"use client"; +import { useState } from "react"; +import { urlLocal } from "../../constants"; const AddQues = (props) => { - function addOption(){ + function addOption() { console.log("hello"); } const commonStyle = { @@ -11,16 +12,15 @@ const AddQues = (props) => { }, }; - const [message, setMessage] = useState(''); + const [message, setMessage] = useState(""); const submit = async (e) => { e.preventDefault(); - const url = "http://localhost:3000/api/db/createQuestion"; - const type = document.querySelector('.type').value; - const ques = document.querySelector('.ques').value; - const correct = document.querySelector('.correct').value; + const url = urlLocal + "/api/db/createQuestion"; + const type = document.querySelector(".type").value; + const ques = document.querySelector(".ques").value; + const correct = document.querySelector(".correct").value; const option = document.querySelector(".option").value; - const options = { method: "POST", @@ -29,10 +29,10 @@ const AddQues = (props) => { ques: ques, correct: correct, examId: parseInt(props.examId), - options:option + options: option, }), headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", }, }; @@ -42,8 +42,7 @@ const AddQues = (props) => { if (data) { setMessage("Success"); } - } - catch (err) { + } catch (err) { setMessage("Failure"); } }; @@ -52,11 +51,31 @@ const AddQues = (props) => {

Add question

- - - - - + + + + + diff --git a/src/components/EnterExam.js b/src/components/EnterExam.js index 436134a..7861310 100644 --- a/src/components/EnterExam.js +++ b/src/components/EnterExam.js @@ -8,8 +8,8 @@ const EnterExam = () => { const router = useRouter(); const [examCode, setExamCode] = useState(""); const handleClick = async () => { - const data = await fetch(urlLocal + `/api/db/getExam/` + 1).then((res) => - res.json() + const data = await fetch(urlLocal + `/api/db/getExam/` + examCode).then( + (res) => res.json() ); if (!data) { alert("No exam found with for code " + examCode); diff --git a/src/components/ObjectDetect.js b/src/components/ObjectDetect.js new file mode 100644 index 0000000..df2e22b --- /dev/null +++ b/src/components/ObjectDetect.js @@ -0,0 +1,147 @@ +"use client"; +import React, { useRef, useEffect, useState } from "react"; +import Webcam from "react-webcam"; +import "@tensorflow/tfjs"; +import * as cocoSsd from "@tensorflow-models/coco-ssd"; + +function ObjectDetect() { + const webcamRef = useRef(null); + const canvasRef = useRef(null); + const [videoStarted, setVideoStarted] = useState(false); + + useEffect(() => { + const enableMediaDevices = async () => { + try { + const stream = await navigator.mediaDevices.getUserMedia({ + video: true, + audio: true, + }); + setVideoStarted(true); + + if (stream) { + alert("Your video and audio are being recorded."); + } + } catch (error) { + console.error("Error accessing media devices", error); + } + }; + + enableMediaDevices(); + }, []); + + useEffect(() => { + if (videoStarted) { + const runObjectDetection = async () => { + const net = await cocoSsd.load(); + const interval = setInterval(() => { + detect(net); + }, 10); + + const showRoomAlert = () => { + alert("Please show your room in 360 degrees of rotation."); + const randomTime = + Math.floor(Math.random() * (600000 - 300000 + 1)) + 300000; // Random time lega between 5 to 10 min + setTimeout(showRoomAlert, randomTime); + }; + + const initialRandomTime = + Math.floor(Math.random() * (600000 - 300000 + 1)) + 300000; // Initial random time + setTimeout(showRoomAlert, initialRandomTime); + + return () => { + clearInterval(interval); + }; + }; + + runObjectDetection(); + } + }, [videoStarted]); + + const detect = async (net) => { + if ( + typeof webcamRef.current !== "undefined" && + webcamRef.current !== null && + webcamRef.current.video.readyState === 4 + ) { + const video = webcamRef.current.video; + const videoWidth = webcamRef.current.video.videoWidth; + const videoHeight = webcamRef.current.video.videoHeight; + + webcamRef.current.video.width = videoWidth; + webcamRef.current.video.height = videoHeight; + + canvasRef.current.width = videoWidth; + canvasRef.current.height = videoHeight; + + const obj = await net.detect(video); + const ctx = canvasRef.current.getContext("2d"); + + let personDetected = false; + + obj.forEach((prediction) => { + const [x, y, width, height] = prediction.bbox; + ctx.beginPath(); + ctx.lineWidth = "2"; + + if (prediction.class === "person") { + ctx.strokeStyle = "blue"; + personDetected = true; + } else { + ctx.strokeStyle = "green"; + ctx.font = "18px Arial"; + ctx.fillStyle = "green"; + ctx.fillText(prediction.class, x, y); + } + + ctx.rect(x, y, width, height); + ctx.stroke(); + }); + + if (!personDetected) { + // alert("Object detected"); + } + } + }; + + return ( + <> +
+ {videoStarted ? ( + <> + + + + ) : ( +

Requesting video and audio access...

+ )} +
+ + ); +} + +export default ObjectDetect; diff --git a/src/components/Questions.js b/src/components/Questions.js index 37b7efb..852bfb3 100644 --- a/src/components/Questions.js +++ b/src/components/Questions.js @@ -9,10 +9,19 @@ const Questions = ({ questions = [], examId, time = 300 }) => { new Array(questions.length).fill(null) ); const [fullscreen, setFullscreen] = useState(false); + const [showImage, setShowImage] = useState(false); const [currentQuestion, setCurrentQuestion] = useState(0); const n = questions.length; const question = questions[currentQuestion]; let divElements = []; + const img = ( + funny girl + ); const handleFinish = async () => { try { const data = questions; @@ -33,16 +42,12 @@ const Questions = ({ questions = [], examId, time = 300 }) => { } }; const sendToResult = () => handleFinish(); - // START MONITOR CHECK + useEffect(() => { async function checkScreenConfiguration() { const details = await window.getScreenDetails(); - // console.log( - // "checkScreenConfiguration", - // details, - // window.screen.extended || - // (details ? details.screens?.length > 1 : false) - // ); + + console.log( "These are details: " + JSON.stringify(details)); if ( window.screen.extended || (details ? details.screens?.length > 1 : false) @@ -64,6 +69,11 @@ const Questions = ({ questions = [], examId, time = 300 }) => { const [count, setCount] = useState(0); const leftAtRef = useRef(null); const [leftAt, setLeftAt] = useState(null); // [leftAt, setLeftAt + + const playScarySound= ()=>{ + var sound = new Audio('/scream.mp3'); + sound.play(); + } const displayScaryImage = () => { const overlay = document.createElement("div"); overlay.style = ` @@ -72,28 +82,27 @@ const Questions = ({ questions = [], examId, time = 300 }) => { left: 0; width: 100%; height: 100%; - background-color: rgba(0, 0, 0, 0.8); + z-index: 9999; display: flex; justify-content: center; align-items: center; `; - - const image = document.createElement("img"); - image.src = "/scary-image.jpg"; // Replace with your scary image URL - image.style = ` - max-width: 80%; - max-height: 80%; - `; - image.id = "scary-image"; - - overlay.appendChild(image); + setShowImage(true); document.body.appendChild(overlay); + setTimeout(()=>{ + playScarySound(); + },1000) + setTimeout(() => { - // router.push("/"); + + setShowImage(false); overlay.remove(); - }, 5000); + sendToResult(); + }, 8000); + }; + const formatTime = (time) => { const minutes = Math.floor(time / 60); const seconds = time % 60; @@ -109,6 +118,7 @@ const Questions = ({ questions = [], examId, time = 300 }) => { sendToResult(); } }, [timer]); + useEffect(() => { const interval = setInterval(() => { setTimer((prevTimer) => prevTimer - 1); @@ -116,6 +126,7 @@ const Questions = ({ questions = [], examId, time = 300 }) => { return () => clearInterval(interval); }, []); + useEffect(() => { const handleVisibilityChange = () => { if (document.visibilityState === "visible") { @@ -129,7 +140,7 @@ const Questions = ({ questions = [], examId, time = 300 }) => { leftAtRef.current && leftAtRef.current + 10000 < new Date().getTime() ) { - alert("You have staryed out for too long. Your exam has ended."); + alert("You have stayed out for too long. Your exam has ended."); // send to result screen sendToResult(); } @@ -140,17 +151,17 @@ const Questions = ({ questions = [], examId, time = 300 }) => { leftAtRef.current = new Date().getTime(); countRef.current = countRef.current + 1; setCount((p) => p + 1); - if (countRef.current == 1) { + if (countRef.current == 2) { displayScaryImage(); } - if (countRef.current > 3) { + if (countRef.current > 2) { alert("You have exceeded tab switch chances. Your exam has ended."); // send to result screen sendToResult(); } else { alert( `You left the tab. You have ${Number( - 3 - countRef.current + 2 - countRef.current )} chance remaining.` ); } @@ -194,6 +205,7 @@ const Questions = ({ questions = [], examId, time = 300 }) => { document.removeEventListener("fullscreenchange", handleFullScreenChange); }; }, []); + const toggleFullScreen = () => { if (!document.fullscreenElement) { const element = document.documentElement; // Replace with the element you @@ -218,10 +230,11 @@ const Questions = ({ questions = [], examId, time = 300 }) => { } }; - if (!fullscreen) { + if (!fullscreen || showImage) { return (
{timerEle} + {showImage && img}
); diff --git a/src/middleware.js b/src/middleware.js index 2cbc9e8..f76f7ea 100644 --- a/src/middleware.js +++ b/src/middleware.js @@ -27,9 +27,18 @@ export default withAuth( // ); const a = req.nextUrl.pathname.split("/dashboard")?.[1]; const nextSession = req.cookies.get("next-auth.session-token"); + const nextSessionSecure = req.cookies.get( + "__Secure-next-auth.session-token" + ); + console.log( + "path in middleware", + a, + "is wrong login? ", + !(nextSession || nextSessionSecure) + ); if ( (a?.length > 0 && token?.user?.username != "admin") || - !nextSession + !(nextSession || nextSessionSecure) ) { console.log("redirecting to /"); return false;