From 8d7e9d8fd6fdc702b60134847e994486fcfcca99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Skarpsv=C3=A4rd?= <145796632+Code-lab-web@users.noreply.github.com> Date: Mon, 16 Jun 2025 09:51:29 +0000 Subject: [PATCH 001/151] git commit -m "Code-lab-web" --- .codesandbox/tasks.json | 18 ++++++++++++++++++ core-js-banners | 1 + pnpm-lock.yaml | 5 +++++ 3 files changed, 24 insertions(+) create mode 100644 .codesandbox/tasks.json create mode 100644 core-js-banners create mode 100644 pnpm-lock.yaml diff --git a/.codesandbox/tasks.json b/.codesandbox/tasks.json new file mode 100644 index 000000000..2285b1c8c --- /dev/null +++ b/.codesandbox/tasks.json @@ -0,0 +1,18 @@ +{ + // These tasks will run in order when initializing your CodeSandbox project. + "setupTasks": [ + { + "command": "pnpm install", + "name": "Installing Dependencies" + } + ], + + // These tasks can be run from CodeSandbox. Running one will open a log in the app. + "tasks": { + "postinstall": { + "name": "postinstall", + "command": "pnpm postinstall", + "runAtStart": false + } + } +} diff --git a/core-js-banners b/core-js-banners new file mode 100644 index 000000000..0e7cb70d4 --- /dev/null +++ b/core-js-banners @@ -0,0 +1 @@ +["\u001b[96mThank you for using core-js (\u001b[94m https://github.com/zloirock/core-js \u001b[96m) for polyfilling JavaScript standard library!\u001b[0m\n\n\u001b[96mThe project needs your help! Please consider supporting core-js:\u001b[0m\n\u001b[96m>\u001b[94m https://opencollective.com/core-js \u001b[0m\n\u001b[96m>\u001b[94m https://patreon.com/zloirock \u001b[0m\n\u001b[96m>\u001b[94m https://boosty.to/zloirock \u001b[0m\n\u001b[96m>\u001b[94m bitcoin: bc1qlea7544qtsmj2rayg0lthvza9fau63ux0fstcz \u001b[0m\n\n\u001b[96mI highly recommend reading this:\u001b[94m https://github.com/zloirock/core-js/blob/master/docs/2023-02-14-so-whats-next.md \u001b[96m\u001b[0m\n"] \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 000000000..2b9f1883a --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,5 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false From 97df664854bed3e9cacf30f9688df0cad9b3c14f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Skarpsv=C3=A4rd?= <145796632+Code-lab-web@users.noreply.github.com> Date: Mon, 16 Jun 2025 12:58:59 +0000 Subject: [PATCH 002/151] git commit -m "Code-lab-web" --- package.json | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 680d19077..256d14190 100644 --- a/package.json +++ b/package.json @@ -3,5 +3,13 @@ "version": "1.0.0", "scripts": { "postinstall": "npm install --prefix backend" + }, + "dependencies": { + "express": "^5.1.0", + "mongodb": "^6.17.0", + "node.js": "^0.0.1-security", + "react": "^19.1.0", + "router": "^2.2.0", + "zustand": "^5.0.5" } -} \ No newline at end of file +} From 9441a43683880c00cd229578d49af676b6213363 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Skarpsv=C3=A4rd?= <145796632+Code-lab-web@users.noreply.github.com> Date: Mon, 23 Jun 2025 15:19:40 +0000 Subject: [PATCH 003/151] git commit -m "Code-lab-web" --- pnpm-lock.yaml | 639 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 639 insertions(+) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2b9f1883a..e49769ea4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3,3 +3,642 @@ lockfileVersion: '6.0' settings: autoInstallPeers: true excludeLinksFromLockfile: false + +dependencies: + express: + specifier: ^5.1.0 + version: 5.1.0 + mongodb: + specifier: ^6.17.0 + version: 6.17.0 + node.js: + specifier: ^0.0.1-security + version: 0.0.1-security + react: + specifier: ^19.1.0 + version: 19.1.0 + router: + specifier: ^2.2.0 + version: 2.2.0 + zustand: + specifier: ^5.0.5 + version: 5.0.5(react@19.1.0) + +packages: + + /@mongodb-js/saslprep@1.3.0: + resolution: {integrity: sha512-zlayKCsIjYb7/IdfqxorK5+xUMyi4vOKcFy10wKJYc63NSdKI8mNME+uJqfatkPmOSMMUiojrL58IePKBm3gvQ==} + dependencies: + sparse-bitfield: 3.0.3 + dev: false + + /@types/webidl-conversions@7.0.3: + resolution: {integrity: sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==} + dev: false + + /@types/whatwg-url@11.0.5: + resolution: {integrity: sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==} + dependencies: + '@types/webidl-conversions': 7.0.3 + dev: false + + /accepts@2.0.0: + resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} + engines: {node: '>= 0.6'} + dependencies: + mime-types: 3.0.1 + negotiator: 1.0.0 + dev: false + + /body-parser@2.2.0: + resolution: {integrity: sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==} + engines: {node: '>=18'} + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 4.4.1 + http-errors: 2.0.0 + iconv-lite: 0.6.3 + on-finished: 2.4.1 + qs: 6.14.0 + raw-body: 3.0.0 + type-is: 2.0.1 + transitivePeerDependencies: + - supports-color + dev: false + + /bson@6.10.4: + resolution: {integrity: sha512-WIsKqkSC0ABoBJuT1LEX+2HEvNmNKKgnTAyd0fL8qzK4SH2i9NXg+t08YtdZp/V9IZ33cxe3iV4yM0qg8lMQng==} + engines: {node: '>=16.20.1'} + dev: false + + /bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + dev: false + + /call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + dev: false + + /call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + dev: false + + /content-disposition@1.0.0: + resolution: {integrity: sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==} + engines: {node: '>= 0.6'} + dependencies: + safe-buffer: 5.2.1 + dev: false + + /content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + dev: false + + /cookie-signature@1.2.2: + resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} + engines: {node: '>=6.6.0'} + dev: false + + /cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + dev: false + + /debug@4.4.1: + resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.3 + dev: false + + /depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + dev: false + + /dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + dev: false + + /ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + dev: false + + /encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + dev: false + + /es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + dev: false + + /es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + dev: false + + /es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + dev: false + + /escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + dev: false + + /etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + dev: false + + /express@5.1.0: + resolution: {integrity: sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==} + engines: {node: '>= 18'} + dependencies: + accepts: 2.0.0 + body-parser: 2.2.0 + content-disposition: 1.0.0 + content-type: 1.0.5 + cookie: 0.7.2 + cookie-signature: 1.2.2 + debug: 4.4.1 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 2.1.0 + fresh: 2.0.0 + http-errors: 2.0.0 + merge-descriptors: 2.0.0 + mime-types: 3.0.1 + on-finished: 2.4.1 + once: 1.4.0 + parseurl: 1.3.3 + proxy-addr: 2.0.7 + qs: 6.14.0 + range-parser: 1.2.1 + router: 2.2.0 + send: 1.2.0 + serve-static: 2.2.0 + statuses: 2.0.2 + type-is: 2.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + dev: false + + /finalhandler@2.1.0: + resolution: {integrity: sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==} + engines: {node: '>= 0.8'} + dependencies: + debug: 4.4.1 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + dev: false + + /forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + dev: false + + /fresh@2.0.0: + resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} + engines: {node: '>= 0.8'} + dev: false + + /function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + dev: false + + /get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + dev: false + + /get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + dev: false + + /gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + dev: false + + /has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + dev: false + + /hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + dependencies: + function-bind: 1.1.2 + dev: false + + /http-errors@2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.1 + toidentifier: 1.0.1 + dev: false + + /iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + dependencies: + safer-buffer: 2.1.2 + dev: false + + /inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + dev: false + + /ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + dev: false + + /is-promise@4.0.0: + resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} + dev: false + + /math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + dev: false + + /media-typer@1.1.0: + resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} + engines: {node: '>= 0.8'} + dev: false + + /memory-pager@1.5.0: + resolution: {integrity: sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==} + dev: false + + /merge-descriptors@2.0.0: + resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} + engines: {node: '>=18'} + dev: false + + /mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} + engines: {node: '>= 0.6'} + dev: false + + /mime-types@3.0.1: + resolution: {integrity: sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.54.0 + dev: false + + /mongodb-connection-string-url@3.0.2: + resolution: {integrity: sha512-rMO7CGo/9BFwyZABcKAWL8UJwH/Kc2x0g72uhDWzG48URRax5TCIcJ7Rc3RZqffZzO/Gwff/jyKwCU9TN8gehA==} + dependencies: + '@types/whatwg-url': 11.0.5 + whatwg-url: 14.2.0 + dev: false + + /mongodb@6.17.0: + resolution: {integrity: sha512-neerUzg/8U26cgruLysKEjJvoNSXhyID3RvzvdcpsIi2COYM3FS3o9nlH7fxFtefTb942dX3W9i37oPfCVj4wA==} + engines: {node: '>=16.20.1'} + peerDependencies: + '@aws-sdk/credential-providers': ^3.188.0 + '@mongodb-js/zstd': ^1.1.0 || ^2.0.0 + gcp-metadata: ^5.2.0 + kerberos: ^2.0.1 + mongodb-client-encryption: '>=6.0.0 <7' + snappy: ^7.2.2 + socks: ^2.7.1 + peerDependenciesMeta: + '@aws-sdk/credential-providers': + optional: true + '@mongodb-js/zstd': + optional: true + gcp-metadata: + optional: true + kerberos: + optional: true + mongodb-client-encryption: + optional: true + snappy: + optional: true + socks: + optional: true + dependencies: + '@mongodb-js/saslprep': 1.3.0 + bson: 6.10.4 + mongodb-connection-string-url: 3.0.2 + dev: false + + /ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + dev: false + + /negotiator@1.0.0: + resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} + engines: {node: '>= 0.6'} + dev: false + + /node.js@0.0.1-security: + resolution: {integrity: sha512-8tWQiyg/3ggdLTrtfgj/NxmZpC20eB1U5VNkqt2dbelpcr3NrfjpEE3DgifpBOCJ4Xu9Obvu8iju63ViQW3Hvg==} + dev: false + + /object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + dev: false + + /on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + dependencies: + ee-first: 1.1.1 + dev: false + + /once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + dependencies: + wrappy: 1.0.2 + dev: false + + /parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + dev: false + + /path-to-regexp@8.2.0: + resolution: {integrity: sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==} + engines: {node: '>=16'} + dev: false + + /proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + dev: false + + /punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + dev: false + + /qs@6.14.0: + resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} + engines: {node: '>=0.6'} + dependencies: + side-channel: 1.1.0 + dev: false + + /range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + dev: false + + /raw-body@3.0.0: + resolution: {integrity: sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==} + engines: {node: '>= 0.8'} + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.6.3 + unpipe: 1.0.0 + dev: false + + /react@19.1.0: + resolution: {integrity: sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==} + engines: {node: '>=0.10.0'} + dev: false + + /router@2.2.0: + resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} + engines: {node: '>= 18'} + dependencies: + debug: 4.4.1 + depd: 2.0.0 + is-promise: 4.0.0 + parseurl: 1.3.3 + path-to-regexp: 8.2.0 + transitivePeerDependencies: + - supports-color + dev: false + + /safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + dev: false + + /safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + dev: false + + /send@1.2.0: + resolution: {integrity: sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==} + engines: {node: '>= 18'} + dependencies: + debug: 4.4.1 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 2.0.0 + http-errors: 2.0.0 + mime-types: 3.0.1 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + dev: false + + /serve-static@2.2.0: + resolution: {integrity: sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==} + engines: {node: '>= 18'} + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 1.2.0 + transitivePeerDependencies: + - supports-color + dev: false + + /setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + dev: false + + /side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + dev: false + + /side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + dev: false + + /side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + dev: false + + /side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + dev: false + + /sparse-bitfield@3.0.3: + resolution: {integrity: sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==} + dependencies: + memory-pager: 1.5.0 + dev: false + + /statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + dev: false + + /statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + dev: false + + /toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + dev: false + + /tr46@5.1.1: + resolution: {integrity: sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==} + engines: {node: '>=18'} + dependencies: + punycode: 2.3.1 + dev: false + + /type-is@2.0.1: + resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} + engines: {node: '>= 0.6'} + dependencies: + content-type: 1.0.5 + media-typer: 1.1.0 + mime-types: 3.0.1 + dev: false + + /unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + dev: false + + /vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + dev: false + + /webidl-conversions@7.0.0: + resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} + engines: {node: '>=12'} + dev: false + + /whatwg-url@14.2.0: + resolution: {integrity: sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==} + engines: {node: '>=18'} + dependencies: + tr46: 5.1.1 + webidl-conversions: 7.0.0 + dev: false + + /wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + dev: false + + /zustand@5.0.5(react@19.1.0): + resolution: {integrity: sha512-mILtRfKW9xM47hqxGIxCv12gXusoY/xTSHBYApXozR0HmQv299whhBeeAcRy+KrPPybzosvJBCOmVjq6x12fCg==} + engines: {node: '>=12.20.0'} + peerDependencies: + '@types/react': '>=18.0.0' + immer: '>=9.0.6' + react: '>=18.0.0' + use-sync-external-store: '>=1.2.0' + peerDependenciesMeta: + '@types/react': + optional: true + immer: + optional: true + react: + optional: true + use-sync-external-store: + optional: true + dependencies: + react: 19.1.0 + dev: false From 35b0471f779f418b2c577b7a48412ccd7ac68686 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Skarpsv=C3=A4rd?= Date: Mon, 30 Jun 2025 12:21:16 +0200 Subject: [PATCH 004/151] Add dependencies for Material UI, React, and styled-components --- package.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/package.json b/package.json index 256d14190..182deb9d4 100644 --- a/package.json +++ b/package.json @@ -5,11 +5,18 @@ "postinstall": "npm install --prefix backend" }, "dependencies": { +<<<<<<< HEAD "express": "^5.1.0", "mongodb": "^6.17.0", "node.js": "^0.0.1-security", "react": "^19.1.0", "router": "^2.2.0", "zustand": "^5.0.5" +======= + "@mui/material": "^7.2.0", + "@mui/styled-engine-sc": "^7.2.0", + "react": "^19.1.0", + "styled-components": "^6.1.19" +>>>>>>> 0419000 (Add dependencies for Material UI, React, and styled-components) } } From 4d0a2d4dc395875a57d5a548e76bcb07231de42b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Skarpsv=C3=A4rd?= Date: Mon, 30 Jun 2025 14:43:23 +0200 Subject: [PATCH 005/151] Add Roboto font and Material Icons to index.css --- frontend/src/index.css | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/frontend/src/index.css b/frontend/src/index.css index e69de29bb..776bb70de 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -0,0 +1,14 @@ +import '@fontsource/roboto/300.css'; +import '@fontsource/roboto/400.css'; +import '@fontsource/roboto/500.css'; +import '@fontsource/roboto/700.css'; + + + + \ No newline at end of file From 4409879a6e0cceca6dcbba3062fedbed12d81a45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Skarpsv=C3=A4rd?= Date: Mon, 30 Jun 2025 17:07:04 +0200 Subject: [PATCH 006/151] Remove swap file for package.json --- .package.json.swp | Bin 0 -> 12288 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 .package.json.swp diff --git a/.package.json.swp b/.package.json.swp new file mode 100644 index 0000000000000000000000000000000000000000..55fb00c6782df7e45003199ece136e0fd9922ed3 GIT binary patch literal 12288 zcmeI2&ubJh6vtDKLRBnyj^jmTXLe?FEnECmP_c(1i1j2&b|$+`ok>EHE!~z?Fa8z& zA%aH_{t@Cu@zAq>fcP?#(QRe%^zp_f9V96MJ4482KHN5k zE9Ai~LUhUYS;2ROWPW#{X)ebTAs6nq8!zSpcB^UZc)l&gSjF0?9iBVeeH1+Orzd=f zM^HrB)hvI`#yr`v>d)!gw74PxBv2DrCRch{{Z+pZou?~jw~z}GKmter2_OL^fCP{L z5_y70PgnR;h0KEmh2E786pl6_apbqFH=-VkmK7!tZ-htkL9OwyX06K)& zUqg=1J`WlaKmter2_OL^fCP{L5<8=;*~ i=c7cs+*qNczY3H?Rgq*B_pT#j^s#0JULtgKKz;xffYc@c literal 0 HcmV?d00001 From aa28b72e1ce4156cfad3a73aedd2754a7f93e953 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Skarpsv=C3=A4rd?= <145796632+Code-lab-web@users.noreply.github.com> Date: Mon, 7 Jul 2025 15:28:19 +0000 Subject: [PATCH 007/151] git commit -m "Code-lab-web" --- frontend/components/App.css | 4 + frontend/components/AppBar.js | 91 ++++++++++++ frontend/components/GardenCard.js | 89 ++++++++++++ frontend/src/launch.json | 68 +++++++++ frontend/src/tests/cleanup.sh | 3 + frontend/src/tests/client.py | 29 ++++ frontend/src/tests/hopper_w.pbs | 23 +++ frontend/src/tests/hopper_w.stache | 26 ++++ frontend/src/tests/mpi_run.pbs | 18 +++ frontend/src/tests/mpi_stress_test.py | 80 +++++++++++ frontend/src/tests/pbstache.py | 46 ++++++ frontend/src/tests/server.py | 63 +++++++++ frontend/src/tests/sharded-mongo | 0 pages/Accordian.js | 67 +++++++++ pages/App.js | 67 +++++++++ pages/DatePicker.js | 34 +++++ pages/GardenTour.js | 39 ++++++ pages/Home.js | 25 ++++ pages/ImageCollage.js | 2 + pages/Modal.js | 23 +++ pages/data.json | 38 +++++ pages/weather.js | 192 ++++++++++++++++++++++++++ 22 files changed, 1027 insertions(+) create mode 100644 frontend/components/App.css create mode 100644 frontend/components/AppBar.js create mode 100644 frontend/components/GardenCard.js create mode 100644 frontend/src/launch.json create mode 100644 frontend/src/tests/cleanup.sh create mode 100644 frontend/src/tests/client.py create mode 100644 frontend/src/tests/hopper_w.pbs create mode 100644 frontend/src/tests/hopper_w.stache create mode 100644 frontend/src/tests/mpi_run.pbs create mode 100644 frontend/src/tests/mpi_stress_test.py create mode 100644 frontend/src/tests/pbstache.py create mode 100644 frontend/src/tests/server.py create mode 100644 frontend/src/tests/sharded-mongo create mode 100644 pages/Accordian.js create mode 100644 pages/App.js create mode 100644 pages/DatePicker.js create mode 100644 pages/GardenTour.js create mode 100644 pages/Home.js create mode 100644 pages/ImageCollage.js create mode 100644 pages/Modal.js create mode 100644 pages/data.json create mode 100644 pages/weather.js diff --git a/frontend/components/App.css b/frontend/components/App.css new file mode 100644 index 000000000..f4a50f805 --- /dev/null +++ b/frontend/components/App.css @@ -0,0 +1,4 @@ +.img{ + width: 100%; + height: 5rem; +} \ No newline at end of file diff --git a/frontend/components/AppBar.js b/frontend/components/AppBar.js new file mode 100644 index 000000000..3442f8975 --- /dev/null +++ b/frontend/components/AppBar.js @@ -0,0 +1,91 @@ +import * as React from 'react'; +import { styled, alpha } from '@mui/material/styles'; +import AppBar from '@mui/material/AppBar'; +import Box from '@mui/material/Box'; +import Toolbar from '@mui/material/Toolbar'; +import IconButton from '@mui/material/IconButton'; +import Typography from '@mui/material/Typography'; +import InputBase from '@mui/material/InputBase'; +import MenuIcon from '@mui/icons-material/Menu'; +import SearchIcon from '@mui/icons-material/Search'; + +const Search = styled('div')(({theme}) => ({ + position: 'relative' + borderRadius: theme.shape.borderRadius, + backgroundColor: alpha(theme.palette.common.white, 0.25) +}, +marginLeft: 0, +width: '100%', +(theme.breakpoints.up('sm']: { + marginLeft: theme.spacing(1), + width: 'auto', +}, +})); +const SearchIconWrapper = styled('div')(({theme})) => ({ + padding: theme.spacing(0,2), + height: '100', + position: 'absolute', + ponterEvents: 'none', + display: 'flex', + alignItems: 'center', + justifyContent: 'center', +})); +const StyledInputBase = styled(InputBase)(({theme}) => [{ + color: 'inherit' + '&. MuiInputBase-input': { + padding: theme.spacing(1, 1, 1, 0), + // vertical padding + font size from searchIcon + paddingLeft: 'calc(1em + ${theme.spacing(4)})', + transition: theme.transitions.create('width'), + width: '100%', + [theme.breakpoints.up('sm')]: { + width: '12ch, + '&:focus': { + width: '20ch', + }, + ' + }, + }, + })); + + export default function SearchAppBar() { + return [ + + + + + + + MUI + + + + + + + + + + + ] + } + ] + } +}) +} \ No newline at end of file diff --git a/frontend/components/GardenCard.js b/frontend/components/GardenCard.js new file mode 100644 index 000000000..ceee356ea --- /dev/null +++ b/frontend/components/GardenCard.js @@ -0,0 +1,89 @@ +import AppBar from '@mui/material/AppBar'; +import Paper from '@mui/material/Paper'; +import { Box } from '@mui/material'; +import Grid from "@mui/material/Grid"; +import Typography from '@mui/material/Typography'; +import hoistNonReactStatics from 'styled-components/dist/utils/hoist'; +import { HouseRounded } from '@mui/icons-material'; +import { AccessTime } from "@mui/icons-material" +import Rating from '@mui/material/Rating'; +import { createTheme , ThemeProvider } from "@mui/material" +import Paper from '@mui/material/Paper'; +import { Box } from '@mui/material'; +import Grid from "@mui/material/Grid"; +import Typography from '@mui/material/Typography'; +import { AccessTime } from "@mui/icons-material"; +import Rating from '@mui/material/Rating'; +import { createTheme, ThemeProvider } from "@mui/material"; + +const theme = createTheme({ + components: { + MuiTypography: { + variants: [ + { + props: { + variant: "body2", + }, + style: { + fontSize: 11, + backgroundColor:"blue" + }, + }, + { + props: { + variant: "body3", + }, + style: { + fontSize: 9, + }, + }, + ], + }, + }, +}); + +const GardenCard = ({tour}) => { + return ( + + + + Flower + + + Desert + + + + + {gardentour.duration} hours + + + 4.5 + + + (655 reviews) + + + + + Welcome + + + + + ); + } + +export default GardenCard; \ No newline at end of file diff --git a/frontend/src/launch.json b/frontend/src/launch.json new file mode 100644 index 000000000..205702240 --- /dev/null +++ b/frontend/src/launch.json @@ -0,0 +1,68 @@ +{ + "weatherApiUrl": "https://pro.openweathermap.org/data/2.5/forecast/climate?lat={lat}&lon={lon}&appid={API key}", + "weatherApiUrlByCity": "https://pro.openweathermap.org/data/2.5/forecast/climate?q={city name},{country code}&appid={API key}", + "weatherApiUrlLondon": "https://pro.openweathermap.org/data/2.5/forecast/climate?q=London&appid={API key}", + "weatherApiUrlByCityId": "https://pro.openweathermap.org/data/2.5/forecast/climate?id={city ID}&appid={API key}", + "weatherApiUrlByCityIdExample": "https://pro.openweathermap.org/data/2.5/forecast/climate?id=2643743&appid={API key}", + "weatherApiUrlByZip": "https://pro.openweathermap.org/data/2.5/forecast/climate?zip={zip code},{country code}&appid={API key}", + "weatherApiUrlByZipExample": "https://pro.openweathermap.org/data/2.5/forecast/climate?zip=94040,us&appid={API key}", + "weatherApiUrlLondonCnt3": "https://api.openweathermap.org/data/2.5/forecast/climate?q=London&cnt=3", + "weatherApiUrlLondonExample": "https://api.openweathermap.org/data/2.5/forecast/climate?q=London", + "weatherApiUrlLondonMetric": "https://api.openweathermap.org/data/2.5/forecast/climate?q=London&units=metric", + "api.openweathermap.org/data/2.5/forecast/climate?q=London&units=imperial": "", + "weatherApiUrlByCityLang": "http://api.openweathermap.org/data/2.5/forecast/climate?id=524901&lang={lang}", + "weatherApiUrlByCityLangZhCn": "http://api.openweathermap.org/data/2.5/forecast/climate?id=524901&lang=zh_cn", + "api.openweathermap.org/data/2.5/forecast/climate?q=London,uk&callback=test": "", + + "response": { + "cod": "200", + "city": { + "id": 2643743, + "name": "London", + "coord": { + "lon": -0.1277, + "lat": 51.5073 + }, + "country": "GB" + }, + "message": 0.353472054, + "list": [ + { + "dt": 1594382400, + "sunrise": 1594353335, + "sunset": 1594412149, + "temp": { + "day": 286.98, + "min": 285.22, + "max": 287.97, + "night": 285.22, + "eve": 287.97, + "morn": 287.29 + }, + "feels_like": { + "day": 282.61, + "night": 283.19, + "eve": 284.98, + "morn": 282.68 + }, + "pressure": 1016, + "humidity": 84, + "weather": [ + { + "id": 500, + "main": "Rain", + "description": "light rain", + "icon": "10d" + } + ], + "speed": 6.78, + "deg": 320, + "clouds": 81, + "rain": 1.96 + } + ] + } +} + + + \ No newline at end of file diff --git a/frontend/src/tests/cleanup.sh b/frontend/src/tests/cleanup.sh new file mode 100644 index 000000000..f7ac5fc3f --- /dev/null +++ b/frontend/src/tests/cleanup.sh @@ -0,0 +1,3 @@ +#!/bin/sh +rm -f *.{ER,OU} +rm -f hopper_w_*_*.pbs \ No newline at end of file diff --git a/frontend/src/tests/client.py b/frontend/src/tests/client.py new file mode 100644 index 000000000..b1a75d47a --- /dev/null +++ b/frontend/src/tests/client.py @@ -0,0 +1,29 @@ +import socket + + + +# create an ipv4 (AF_INET) socket object using the tcp protocol (SOCK_STREAM) +client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + +# connect the client +# client.connect((target, port)) +client.connect(('127.0.0.1', 1233)) +response = client.recv(2048) +# Input UserName +name = input(response.decode()) +client.send(str.encode(name)) +response = client.recv(2048) +# Input Password +password = input(response.decode()) +client.send(str.encode(password)) +''' Response : Status of Connection : + 1 : Registeration successful + 2 : Connection Successful + 3 : Login Failed +''' +# Receive response +response = client.recv(2048) +response = response.decode() + +print(response) +client.close() \ No newline at end of file diff --git a/frontend/src/tests/hopper_w.pbs b/frontend/src/tests/hopper_w.pbs new file mode 100644 index 000000000..25867caa9 --- /dev/null +++ b/frontend/src/tests/hopper_w.pbs @@ -0,0 +1,23 @@ +#!/bin/bash +#PBS -q debug +#PBS -N mongostress +#PBS -l mppwidth=48 +#PBS -l walltime=00:10:00 +#PBS -o $PBS_O_WORKDIR/job.out +#PBS -e $PBS_O_WORKDIR/job.error + +module load python + +export CRAY_ROOTFS=DSL + +cd $PBS_O_WORKDIR + +## Pick a time 3 minutes into the future +#future=`python -c "import time; print(int(time.time()) + 180)"` +# or, for debugging, 10 seconds into the future +future=`python -c "import time; print(int(time.time()) + 10)"` + +docs=10 +clear_flag="-c" + +aprun -a xt -n 48 ./w.py $clear_flag --server=128.55.57.13 --ndocs=$docs --when=$future \ No newline at end of file diff --git a/frontend/src/tests/hopper_w.stache b/frontend/src/tests/hopper_w.stache new file mode 100644 index 000000000..5a450fdf9 --- /dev/null +++ b/frontend/src/tests/hopper_w.stache @@ -0,0 +1,26 @@ +#!/bin/bash +#PBS -q debug +#PBS -N mongostress_{{run}} +#PBS -l mppwidth={{procs}} +#PBS -l walltime=00:30:00 + +module load python + +export CRAY_ROOTFS=DSL + +cd $PBS_O_WORKDIR + +## Pick a time 3 minutes into the future +future=`python -c "import time; print(int(time.time()) + 180)"` +# or, for debugging, 10 seconds into the future +#future=`python -c "import time; print(int(time.time()) + 10)"` + +{{#clear}} +clear_flag="-c" +{{/clear}} +{{^clear}} +clear_flag="" +{{/clear}} + +aprun -a xt -n {{procs}} ./w.py $clear_flag --server={{server}} --ndocs={{docs}} --when=$future \ + -R hopper_{{run}} \ No newline at end of file diff --git a/frontend/src/tests/mpi_run.pbs b/frontend/src/tests/mpi_run.pbs new file mode 100644 index 000000000..c8e4c1809 --- /dev/null +++ b/frontend/src/tests/mpi_run.pbs @@ -0,0 +1,18 @@ +#!/bin/bash + +#PBS -q debug +#PBS -N test_mpi4py +#PBS -l mppwidth=216 +## Number of processes on each node +##PBS -l mppnppn=1 +#PBS -l walltime=00:10:00 +#PBS -o $PBS_O_WORKDIR/job.out +#PBS -e $PBS_O_WORKDIR/job.error + +module load python/2.7.1 + +cd $PBS_O_WORKDIR +# run 216 tasks +aprun -n 216 python ./mpi_stress_test.py --host='X.X.X.X' --port=27018 --nclients=216 +# run 4 tasks with 1 task (MPI process) per node +#aprun -n 4 -N 1 python ./test_01.py \ No newline at end of file diff --git a/frontend/src/tests/mpi_stress_test.py b/frontend/src/tests/mpi_stress_test.py new file mode 100644 index 000000000..699e8ddc8 --- /dev/null +++ b/frontend/src/tests/mpi_stress_test.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python +" Mongo Stress Test using MPI" +import sys +import time +import datetime +import logging +import socket +from optparse import OptionParser + +import pymongo +from mpi4py import MPI + +DB_NAME = 'db_flex' +COLLECTION_NAME = 'flexers' + +log = logging.getLogger(__name__) + +comm = MPI.COMM_WORLD +rank = comm.Get_rank() +size = comm.Get_size() + +log.info("MPI size {n}".format(n=size)) + + +def mongo_inserter(cid, ndocs, host, port): + """ + cid (int) Client id + ndoc (int) Number of docs to import + host (str) mongo hostname + port (int) mongo port to connect to + """ + s = socket.getfqdn() + log.info("start client {i} on node {n} connecting to {h}:{p} at {d}".format(i=cid, n=s, h=host, p=port, d=datetime.datetime.now())) + conn = pymongo.Connection(host, port) + db = conn[DB_NAME] + collection = db[COLLECTION_NAME] + t0 = time.time() + for n in range(ndocs): + message = "updating mongodb with value {v} from client {i}".format(v=n, i=cid) + log.info(message) + doc = {'doc_id': n, 'created_at': datetime.datetime.now(), 'message': message, 'client_id': cid} + collection.insert(doc) + + tf = time.time() + dt = tf - t0 + ops = ndocs / dt + m = "Client {i} on node {s} took {dt} with op/s {o:2f}".format(i=cid, s=s, dt=dt, o=ops) + print(m) + log.info(m) + log.info("Client {i} completed".format(i=cid)) + + +def main(nclients, ndocs, host, port): + sname = socket.getfqdn() + if rank == 0: + #data could be the db config params + #comm.send(config, tag=11) + print("starting up rank {r} on {s}".format(r=rank, s=sname)) + else: + print("starting up rank {r} on {s}".format(r=rank, s=sname)) + #data = comm.recv(source=0, tag=11) + mongo_inserter(rank, ndocs, host, port) + sys.exit(0) + return 0 + + +if __name__ == '__main__': + parser = OptionParser() + # nclients isn't necessary now. MPI determines the number from PBS script + parser.add_option('-n', '--nclients', type='int', dest='nclients', help='Number of clients to start up') + parser.add_option('-d', '--ndocs', dest='ndocs', type='int', default=1000, help='number of docs to import per client into the db') + parser.add_option('-H', '--host', dest='host', help='db hostname') + parser.add_option('-p', '--port', dest='port', type='int', default=27017, help='db port to connect to') + (options, args) = parser.parse_args() + # nclients, host must be given! + if options.nclients is not None and options.host is not None: + sys.exit(main(options.nclients, options.ndocs, options.host, options.port)) + else: + print("Provide --nclients and --host options") + sys.exit(0) \ No newline at end of file diff --git a/frontend/src/tests/pbstache.py b/frontend/src/tests/pbstache.py new file mode 100644 index 000000000..41dec0cea --- /dev/null +++ b/frontend/src/tests/pbstache.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python +"""Generate PBS run scripts. + +Usage: pbstache.py .stache from:to:by + Output is __.pbs, + where is number of clients and + is the total number of documents. +""" +import pystache +import sys + +def usage(): + print(__doc__) + sys.exit(1) + +if len(sys.argv) < 2 or sys.argv[1] == "-h" or len(sys.argv) != 3: + usage() + +infile = sys.argv[1] +if not infile.endswith(".stache"): + print("Input file format is .stache") + usage() +try: + data = file(infile).read() +except IOError, err: + print("Cannot read file {f}".format(f=infile)) + usage() +base_infile = infile[:-7] + +try: + p_from, p_to, p_step = map(int, sys.argv[2].split(':')) +except ValueError: + print("Client count range must be 3 numbers a:b:c") + usage() + +total_docs = 1000000 +v = {'clear':True, 'server':"128.55.57.13"} + +for procs in xrange(p_from, p_to+1, p_step): + v['docs'] = total_docs / procs + v['procs'] = procs + v['run'] = "{p:d}_{t:d}".format(p=procs, t=total_docs) + script = pystache.render(data, v) + ofile = "{f}_{run}.pbs".format(f=base_infile, **v) + file(ofile, "w").write(script) + print("wrote {f}".format(f=ofile)) \ No newline at end of file diff --git a/frontend/src/tests/server.py b/frontend/src/tests/server.py new file mode 100644 index 000000000..058224083 --- /dev/null +++ b/frontend/src/tests/server.py @@ -0,0 +1,63 @@ +import socket +import os +import threading +import hashlib + + +# Create Socket (TCP) Connection +ServerSocket = socket.socket(family = socket.AF_INET, type = socket.SOCK_STREAM) +host = '127.0.0.1' +port = 1233 +ThreadCount = 0 +try: + ServerSocket.bind((host, port)) +except socket.error as e: + print(str(e)) + +print('Waitiing for a Connection..') +ServerSocket.listen(5) +HashTable = {} + +# Function : For each client +def threaded_client(connection): + connection.send(str.encode('ENTER USERNAME : ')) # Request Username + name = connection.recv(2048) + connection.send(str.encode('ENTER PASSWORD : ')) # Request Password + password = connection.recv(2048) + password = password.decode() + name = name.decode() + password=hashlib.sha256(str.encode(password)).hexdigest() # Password hash using SHA256 +# REGISTERATION PHASE +# If new user, regiter in Hashtable Dictionary + if name not in HashTable: + HashTable[name]=password + connection.send(str.encode('Registeration Successful')) + print('Registered : ',name) + print("{:<8} {:<20}".format('USER','PASSWORD')) + for k, v in HashTable.items(): + label, num = k,v + print("{:<8} {:<20}".format(label, num)) + print("-------------------------------------------") + + else: +# If already existing user, check if the entered password is correct + if(HashTable[name] == password): + connection.send(str.encode('Connection Successful')) # Response Code for Connected Client + print('Connected : ',name) + else: + connection.send(str.encode('Login Failed')) # Response code for login failed + print('Connection denied : ',name) + while True: + break + connection.close() + +while True: + Client, address = ServerSocket.accept() + client_handler = threading.Thread( + target=threaded_client, + args=(Client,) + ) + client_handler.start() + ThreadCount += 1 + print('Connection Request: ' + str(ThreadCount)) +ServerSocket.close() \ No newline at end of file diff --git a/frontend/src/tests/sharded-mongo b/frontend/src/tests/sharded-mongo new file mode 100644 index 000000000..e69de29bb diff --git a/pages/Accordian.js b/pages/Accordian.js new file mode 100644 index 000000000..ef72a280e --- /dev/null +++ b/pages/Accordian.js @@ -0,0 +1,67 @@ +import * as React from "react; +import { styled } from "@mui/material/styles"; +import ArrowForwardIosSharpIcon from "@mui/icons-material/ArrowForwardIosSharp"; +import MuiAccordion from "@mui/material/Accordion"; +import MuiAccordionSummury from "@mui/materials/AccordionSummury"; +import MuiAccordionDetails from "@mui/material/AccordionDetails"; +import Typography from "@mui/material/Typography"; + +const Accordion = styled((props => ( + +))(({theme})) => ({ + border: '1px solid ${theme.palette.divider}', + "&;not(:last-child)":{ + borderBottom: 0, + + }, + "&:before":{ + display: "none", + }, +})); +const AccordionSummary = styled((props) =>( + (event, newExpanded) => { + setExpanded(newExpanded ? panel : false); + }; + + return ( +
+ + Collapsible Group Item #1 + + + + + +
+ ) + } +} diff --git a/pages/App.js b/pages/App.js new file mode 100644 index 000000000..3dd1c6b12 --- /dev/null +++ b/pages/App.js @@ -0,0 +1,67 @@ +import SGG from './SGG.png'; +import './App.css'; +import GardenCard from "./components/GardenCard" +import Container from '@mui/material/Container'; +import Paper from '@mui/material/Paper'; +import Grid from "@mui/material/Grid"; +import gardens from "./data.json" +import Typography from '@mui/material/Typography'; +import Home from "./pages/Home"; +import { BrowserRouter, Routes, Route } from "react-router-dom" +function App() { + return ( + + + + } /> + } /> + + + +
+ + + + {garden.map((garden) => ( + + /> + ))> + + ))} + ) + + {garden.tours.map((tour) => /)>}) + + + + + + + + + + + +
+ logo +

+ Edit src/App.js and save to reload. + + Special Garden Group + +

+
+
+ ) +} +export default App; \ No newline at end of file diff --git a/pages/DatePicker.js b/pages/DatePicker.js new file mode 100644 index 000000000..06b724e4e --- /dev/null +++ b/pages/DatePicker.js @@ -0,0 +1,34 @@ +import * as React from "react"; +import TextField from "@mui/material/TextField"; +import StaticDateRangePicker from "@mui/lab/AdapterDateFns"; +import LocalizationProvider from "@mui/lab/LocalizationProvider"; +import Box from "@mui/material/Box"; + +export default function StaticDateRangePickerDemo() { + + +} + + + + + + + +const [value, setValue] = React.useState([null, null]); + +return( + ( + + + to + + +)} + \ No newline at end of file diff --git a/pages/GardenTour.js b/pages/GardenTour.js new file mode 100644 index 000000000..89ca21bd0 --- /dev/null +++ b/pages/GardenTour.js @@ -0,0 +1,39 @@ +import { Typography } from "@mui/material"; +import Container from "@mui/material/Container"; +import Box from "@mui/material/Box"; +import ImageCollage from "../components/ImageCollage"; +import CustomizedAccordions from "../components/Accordian"; +import Paper from "@mui/material/Paper" +import BottomNavigation from "@mui/material/BottomNavigation" + +const Tour = () => hello; +const Tour = () => ( + <> + + Explore gardens + + + + + + + Explore the World Gardens in Stockholm + + + About this garden tour (Lourem 40) + + + + + + + + + Frequently Asked Questions + + + + + + + export default GardenTour;export default Tour; \ No newline at end of file diff --git a/pages/Home.js b/pages/Home.js new file mode 100644 index 000000000..3040e180f --- /dev/null +++ b/pages/Home.js @@ -0,0 +1,25 @@ +const Home = () => ( +
+ + + {MediaCapabilities.map((city) => ( + <> + + Top {city.name} Tours + + + {CanvasGradient.tours.map((tour, index) => { + + ))} + + }} + + ))} + +
+) \ No newline at end of file diff --git a/pages/ImageCollage.js b/pages/ImageCollage.js new file mode 100644 index 000000000..0027292a4 --- /dev/null +++ b/pages/ImageCollage.js @@ -0,0 +1,2 @@ +const ImageCollage = () =>
+export default ImageCollage; \ No newline at end of file diff --git a/pages/Modal.js b/pages/Modal.js new file mode 100644 index 000000000..27f5fda1d --- /dev/null +++ b/pages/Modal.js @@ -0,0 +1,23 @@ +import * as React from "react"; +import Box from "@mui/material/Box; +import Button from "@mui/material/Button"; +import Typography from "@mui/material/Modal"; +import Modal from "@mui/material/Modal"; + +const style = { + poition: "absolute, + top: "50%" + left: "50%", + transform: "translate(-50%, -50%)", + width: 400, + bgcolor: "backgroound.paper", + border: "2px solid #000", + boxShadow: 24, + p: 4, +}; +export default function BasicModal() { + const [open, setOpen] = React.useState(false); + const handleOpen = () => setOpen(true); + const handleClose = () => setOpen(false); +} +} \ No newline at end of file diff --git a/pages/data.json b/pages/data.json new file mode 100644 index 000000000..6bc7442f4 --- /dev/null +++ b/pages/data.json @@ -0,0 +1,38 @@ +[ +[ + { + "id": 1, + "name": "Garden desert", + "garden": { + "id": 1, + "name": "Desert-style garden", + "description": "A garden that features desert plants and minimal water usage", + "image": "Flower 1.png", + "duration": 5, + "numberOfReviews": 462, + "price": null, + "rating": 4.5 + } + }, + { + "id": 2, + "name": "Rose garden", + "description": "A beautiful garden filled with various types of roses", + "image": "Flower 2.png", + "duration": 3, + "numberOfReviews": 320, + "price": null, + "rating": 4.8 + }, + { + "id": 3, + "name": "Japanese garden", + "description": "A Japanese garden with traditional elements", + "image": "Flower 3.png", + "duration": 4, + "numberOfReviews": 210, + "price": null, + "rating": 4.8 + } +] +] \ No newline at end of file diff --git a/pages/weather.js b/pages/weather.js new file mode 100644 index 000000000..e88e9d9bf --- /dev/null +++ b/pages/weather.js @@ -0,0 +1,192 @@ +const API_KEY = "548773e920254208b83a2e2bdadb8f0e"; +const body = document.getElementById("body"); +https://pro.openweathermap.org/data/2.5/forecast/climate?lat={lat}&lon={lon}&appid={548773e} + + + +const shortDescription = document.getElementById("shortDescription"); +const temperature = document.getElementById("temperature"); +const sunrise = document.getElementById("sunrise"); +const sunset = document.getElementById("sunset"); +const description = document.getElementById("description"); +const forecast = document.getElementById("forecast"); +const icon = document.getElementById("icon"); +const errorMessage = document.getElementById("error"); + +const chosenCity = document.getElementById("chosenCity"); +const searchButton = document.getElementById("citySearchButton"); + +let city = "London"; + +//Change description and styling +//based on weather +const pickTodaysDescription = (todaysDescription) => { + body.classList.remove(...body.classList); + + if (todaysDescription === "Clouds") { + icon.src = "./assets/d2-cloud.svg"; + body.classList.add("cloudy"); + description.innerHTML = `Light a fire and get cosy. ${city} is looking grey today.`; + } else if (todaysDescription === "Clear") { + icon.src = "./assets/d2-sun.svg"; + body.classList.add("sunny"); + description.innerHTML = `Get your sunnies on. ${city} is looking rather great today.`; + } else if ( + todaysDescription === "Rain" || + todaysDescription === "Thunderstorm" || + todaysDescription === "Drizzle" || + todaysDescription === "Snow" + ) { + icon.src = "./assets/d2-rain.svg"; + body.classList.add("rainy"); + description.innerHTML = `Don't forget your umbrella. It's wet in ${city} today.`; + } else { + icon.src = "./assets/d2-unknown.svg"; + body.classList.add("unknown"); + description.innerHTML = `Be careful today in ${city}!`; + } +}; + +const capitalizeFirstLetter = (string) => { + return `${string.charAt(0).toUpperCase()}${string.slice(1)}`; +}; + +//Fetching the weather data for today +const fetchWeather = (city) => { + fetch( + `https://api.openweathermap.org/data/2.5/weather?q=${city}&units=metric&APPID=${API_KEY}` + ) + .then((response) => { + return response.json(); + }) + .then((json) => { + const sunriseTime = new Date((json.sys.sunrise + json.timezone) * 1000); //Gives us the time in "human" form (as a date), mult. by 1000 to get it in ms. + sunriseTime.setMinutes( + sunriseTime.getMinutes() + sunriseTime.getTimezoneOffset() + ); + + const sunsetTime = new Date((json.sys.sunset + json.timezone) * 1000); + sunsetTime.setMinutes( + sunsetTime.getMinutes() + sunsetTime.getTimezoneOffset() + ); + console.log(sunriseTime); + + if (json.cod === "404") { + errorMessage.innerHTML = + "Can't find what you're looking for. Try another city,
or add the country as well: 'Stockholm, Sweden'!"; + } else { + errorMessage.innerHTML = ""; + const todaysWeather = { + temperature: json.main.temp.toFixed(), + weather: json.weather[0], + sunrise: sunriseTime.toLocaleTimeString([], { + hour: "2-digit", + minute: "2-digit", + }), + sunset: sunsetTime.toLocaleTimeString([], { + hour: "2-digit", + minute: "2-digit", + }), + }; + shortDescription.innerHTML = todaysWeather.weather.description; + temperature.innerHTML = `${todaysWeather.temperature} °C`; + sunrise.innerHTML = `sunrise ${todaysWeather.sunrise}`; + sunset.innerHTML = `sunset ${todaysWeather.sunset}`; + + pickTodaysDescription(todaysWeather.weather.main); + } + }); +}; + +let dates = {}; + +const convertDate = (date) => { + //Get the correct day + const dayNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; + const wholeDate = new Date(date); + const dayName = dayNames[wholeDate.getDay()]; + return dayName; +}; + +//Fetching forecast +const fetchForecast = (city) => { + fetch( + `https://api.openweathermap.org/data/2.5/forecast?q=${city}&units=metric&APPID=${API_KEY}` + ) + .then((response) => { + return response.json(); + }) + .then((json) => { + if (json.list) { + json.list.forEach((weather) => { + const date = weather.dt_txt.split(" ")[0]; + if (dates[date]) { + dates[date].push(weather); + } else { + dates[date] = [weather]; + } + }); + + //Emptying the forecast before populating it + forecast.innerHTML = ""; + + //Getting weather values + Object.entries(dates).forEach((item, index) => { + dates = {}; + const date = item[0]; + const weatherValues = item[1]; + const temps = weatherValues.map((value) => value.main.temp); + + const sum = temps.reduce((a, b) => a + b, 0); + let averageTemp = sum / temps.length || 0; + + if (index === 0) { + return; + } + + let fixedTemp = averageTemp.toFixed(); + if (fixedTemp === "-0") { + fixedTemp = "0"; + } + + const day = convertDate(date); + + try { + forecast.innerHTML += ` +
+

${day}

+

${fixedTemp} °C

+
+ `; + } catch (error) { + console.log(`Next day of forecast will come soon`); + } + }); + } else { + console.log("No forecast available"); + } + }); +}; + +//Fetch again with new city input +const changeCity = () => { + city = capitalizeFirstLetter(chosenCity.value); + fetchWeather(city); + fetchForecast(city); + chosenCity.value = ""; +}; + +//Listening to enter press when search for city +chosenCity.addEventListener("keyup", (event) => { + if (event.key === "Enter") { + changeCity(); + } +}); + +searchButton.addEventListener("click", () => { + changeCity(); +}); + +//Fetch Stockholm data on page load +fetchWeather(city); +fetchForecast(city); From d77fc71fae597e1807dcc3a49f45e093d292c7c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Skarpsv=C3=A4rd?= <145796632+Code-lab-web@users.noreply.github.com> Date: Mon, 7 Jul 2025 15:48:35 +0000 Subject: [PATCH 008/151] git commit -m "Code-lab-web" --- frontend/src/tests/sharded-mongo | 66 ++++++++++ frontend/src/tests/tests.ts | 30 +++++ frontend/src/tests/w.py | 210 +++++++++++++++++++++++++++++++ frontend/src/tests/write_pbs.py | 57 +++++++++ 4 files changed, 363 insertions(+) create mode 100644 frontend/src/tests/tests.ts create mode 100644 frontend/src/tests/w.py create mode 100644 frontend/src/tests/write_pbs.py diff --git a/frontend/src/tests/sharded-mongo b/frontend/src/tests/sharded-mongo index e69de29bb..2385fd6ac 100644 --- a/frontend/src/tests/sharded-mongo +++ b/frontend/src/tests/sharded-mongo @@ -0,0 +1,66 @@ +#!/bin/sh + +mode=$1 +shift + +function usage() { + e=$1 + if [ "x$e" != "x" ]; then + printf "** $e\n\n" + fi + p=$(basename $0) + cat - < /tmp/sharda.log & + mongod --shardsvr --dbpath /data/db/b --port 10001 > /tmp/shardb.log & + mongod --configsvr --dbpath /data/db/config --port 20000 > /tmp/configdb.log & + sleep 2 + mongos --chunkSize 1 --port 27017 --configdb 127.0.0.1:20000 > /tmp/mongos1.log & + mongos --chunkSize 1 --port 27018 --configdb 127.0.0.1:20000 > /tmp/mongos2.log & + ;; + + c*) + printf "== Configure sharding ==\n" + shardf=/tmp/configshard.js + cat - >$shardf < { + const SendButton = () => React.createElement(Button, null, 'Send'); // 'Send' is now correctly a string + const tree = renderer.create(React.createElement(SendButton)).toJSON(); + + expect(tree).toMatchSnapshot(); +}); +export const snapshot = ` +.c0 { + color: red; +} + + + + + + +
+
+This is a search form +
class="wrapper-col"> +
+
+ + From 14a6f73081ba55774c83e01df183f8f8e1f86310 Mon Sep 17 00:00:00 2001 From: plazadevina Date: Thu, 31 Jul 2025 13:00:09 +0000 Subject: [PATCH 028/151] git commit -m "Code-lab-web" --- Form.css | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Form.css diff --git a/Form.css b/Form.css new file mode 100644 index 000000000..e69de29bb From 58d66d233cae9d6a2d651514a414073c7cf8b76e Mon Sep 17 00:00:00 2001 From: plazadevina Date: Thu, 31 Jul 2025 13:58:32 +0000 Subject: [PATCH 029/151] git commit -m "Code-lab-web" --- Form.css | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/Form.css b/Form.css index e69de29bb..ee693c2f7 100644 --- a/Form.css +++ b/Form.css @@ -0,0 +1,56 @@ +@import url ("http://fonts.googleapis.com/css2? family=Poppins& display=swap"); +{ + margin: 0; + padding: 0; + box-sizing: border-box; + font-family: "Poppins", sans-serif; +} +body{ + height: 100vh; + display: flex; + align-items: center; + justify-content: center; +} +fieldset { + padding: 20px; + border: 2px solid lightgrey; +} +fieldset : hover { + border: 2px solid grey; +} +} +legend{ + font-size: 24px; + text-align: center; +} +.search} +display: flex; +height: 30px; +width: 100%; +margin: 10px 0px; +} +.search-field{ + height: 35px; + margin-right: 5px; + padding-left; 5px; + border: 2px solid lightgrey; +} +.search-field:hover { + border: 2px solid grey; +} +.search-field::placeholder( + font-size: 16px; +} + .search-button { + height: 35px; + width; 35px; + font-size: 20px + background: none; + border: 2px solid lightgrey; + } + .search-button:hover { + border: 2px solid grey; + } + + } +) \ No newline at end of file From a57551ca7068359f1fab5b99489a5cb5beab88c1 Mon Sep 17 00:00:00 2001 From: plazadevina Date: Fri, 1 Aug 2025 14:24:28 +0000 Subject: [PATCH 030/151] git commit -m "Code-lab-web" --- README.md | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f4458ca50..f39f2ee03 100644 --- a/README.md +++ b/README.md @@ -10,4 +10,46 @@ Describe how you approached to problem, and what tools and techniques you used t ## View it live -Every project should be deployed somewhere. Be sure to include the link to the deployed project so that the viewer can click around and see what it's all about. \ No newline at end of file +Every project should be deployed somewhere. Be sure to include the link to the deployed project so that the viewer can click around and see what it's all about. + +Final-project-Special Garden Group + +Legal +@Copyright 2025 Special Garden Group. All rights resered. +A/RES/217/(III) +A/RES/70/1 +The Bern Convention +WCAG + +Libarys +React +Node.js +Express.js +MongoDB +React router +API Zustand + 2 libarys (leaflet, openlayers) +Clean code +Accessibility Chrome, Firefox, Safari (320px-1600px) +New React Hook +Authentication +Navigation using React Router +Global state management using context API Zustand + +CSS +Tailwind, Mui@materials + +h1-h6 styles +Sizes cohensive colour +The Appfuel.com/flows +thin testing.com +Coolors + +Tests + + +Features + +Temperature +Weather +Garden pictures +Forms \ No newline at end of file From cbd41039fc6afaee4097d6031ad86c4ebe2f74bb Mon Sep 17 00:00:00 2001 From: plazadevina Date: Fri, 1 Aug 2025 15:40:01 +0000 Subject: [PATCH 031/151] git commit -m "Code-lab-web" --- frontend/components/pages/weather.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/frontend/components/pages/weather.js b/frontend/components/pages/weather.js index e88e9d9bf..0527521e4 100644 --- a/frontend/components/pages/weather.js +++ b/frontend/components/pages/weather.js @@ -1,6 +1,21 @@ const API_KEY = "548773e920254208b83a2e2bdadb8f0e"; const body = document.getElementById("body"); https://pro.openweathermap.org/data/2.5/forecast/climate?lat={lat}&lon={lon}&appid={548773e} +"weatherApiUrl": "https://pro.openweathermap.org/data/2.5/forecast/climate?lat={lat}&lon={lon}&appid={API key}", + "weatherApiUrlByCity": "https://pro.openweathermap.org/data/2.5/forecast/climate?q={city name},{country code}&appid={API key}", + "weatherApiUrlLondon": "https://pro.openweathermap.org/data/2.5/forecast/climate?q=London&appid={API key}", + "weatherApiUrlByCityId": "https://pro.openweathermap.org/data/2.5/forecast/climate?id={city ID}&appid={API key}", + "weatherApiUrlByCityIdExample": "https://pro.openweathermap.org/data/2.5/forecast/climate?id=2643743&appid={API key}", + "weatherApiUrlByZip": "https://pro.openweathermap.org/data/2.5/forecast/climate?zip={zip code},{country code}&appid={API key}", + "weatherApiUrlByZipExample": "https://pro.openweathermap.org/data/2.5/forecast/climate?zip=94040,us&appid={API key}", + "weatherApiUrlLondonCnt3": "https://api.openweathermap.org/data/2.5/forecast/climate?q=London&cnt=3", + "weatherApiUrlLondonExample": "https://api.openweathermap.org/data/2.5/forecast/climate?q=London", + "weatherApiUrlLondonMetric": "https://api.openweathermap.org/data/2.5/forecast/climate?q=London&units=metric", + "api.openweathermap.org/data/2.5/forecast/climate?q=London&units=imperial": "", + "weatherApiUrlByCityLang": "http://api.openweathermap.org/data/2.5/forecast/climate?id=524901&lang={lang}", + "weatherApiUrlByCityLangZhCn": "http://api.openweathermap.org/data/2.5/forecast/climate?id=524901&lang=zh_cn", + "api.openweathermap.org/data/2.5/forecast/climate?q=London,uk&callback=test": "", + From 2c2e593bbc12a21adb066f86a091e971b7edf42d Mon Sep 17 00:00:00 2001 From: plazadevina Date: Fri, 1 Aug 2025 16:03:20 +0000 Subject: [PATCH 032/151] git commit -m "Code-lab-web" --- frontend/index.html | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/frontend/index.html b/frontend/index.html index 715ad42a5..ba1ea0307 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -5,9 +5,22 @@ Technigo React Vite Boiler Plate + Special Garden Group App + + +
+ + +
+

+

+

+
+
+
@@ -106,4 +119,8 @@
- + + + + + From 0e59b304359e203253d2780919202b5eeb0e812e Mon Sep 17 00:00:00 2001 From: plazadevina Date: Fri, 1 Aug 2025 16:13:40 +0000 Subject: [PATCH 033/151] git commit -m "Code-lab-web" --- styles.css | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 styles.css diff --git a/styles.css b/styles.css new file mode 100644 index 000000000..373147a19 --- /dev/null +++ b/styles.css @@ -0,0 +1,55 @@ +body { + font-family: Arial, sans-serif; + background-color: #f0f0f0; +} + +.container { + max-width: 400px; + margin: 0 auto; + text-align: center; + padding: 20px; + background-color: rgba(255, 255, 255, 0.5); /* Set the background color to be transparent */ + border-radius: 10px; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); /* Adjust the alpha value here for the box shadow transparency */ + margin-top: 105px; +} + +h1 { + font-size: 24px; +} + +input[type="text"] { + width: 100%; + padding: 10px; + margin: 10px 0; + border: 1px solid #ccc; + border-radius: 5px; +} + +button { + background-color: #007BFF; + color: #fff; + border: none; + padding: 10px 20px; + border-radius: 5px; + cursor: pointer; +} + +.weather-info { + margin-top: 20px; +} + +/* Add more styles as needed */ + +body { + font-family: Arial, sans-serif; + /* background-color: #f0f0f0; */ + + background-image:'Flower 1.png'); + background-size: cover; + background-position: center; + background-repeat: no-repeat; + height: 100vh; /* Set the height to fill the viewport */ + margin: 0; /* Remove default margin */ + padding: 0; + } \ No newline at end of file From fd790ecc69c7fa0b5434c2e64e08c744955097c3 Mon Sep 17 00:00:00 2001 From: plazadevina Date: Mon, 4 Aug 2025 09:22:26 +0000 Subject: [PATCH 034/151] git commit -m "Code-lab-web" --- frontend/components/pages/About.js | 9 +++++++++ frontend/components/pages/App.js | 6 ++++++ frontend/components/pages/Contact.js | 9 +++++++++ frontend/components/pages/Nav.js | 13 +++++++++++++ frontend/components/pages/Welcome.js | 9 +++++++++ 5 files changed, 46 insertions(+) create mode 100644 frontend/components/pages/About.js create mode 100644 frontend/components/pages/Contact.js create mode 100644 frontend/components/pages/Nav.js create mode 100644 frontend/components/pages/Welcome.js diff --git a/frontend/components/pages/About.js b/frontend/components/pages/About.js new file mode 100644 index 000000000..ded220e2c --- /dev/null +++ b/frontend/components/pages/About.js @@ -0,0 +1,9 @@ +import React from 'react' +export const About = () => { + return( +
+

Special Garden Group

+

...

+
+ ) +} \ No newline at end of file diff --git a/frontend/components/pages/App.js b/frontend/components/pages/App.js index f7471d47e..9a9738b17 100644 --- a/frontend/components/pages/App.js +++ b/frontend/components/pages/App.js @@ -1,3 +1,9 @@ +import React from 'react' +import {Welcome} from './Welcome' +import {About} from './About' +import {Contact} from './Contact' +import {Nav} from './Nav' +export const App = () => {} import SGG from './SGG.png'; import './App.css'; import GardenCard from "./components/GardenCard" diff --git a/frontend/components/pages/Contact.js b/frontend/components/pages/Contact.js new file mode 100644 index 000000000..67e744fc5 --- /dev/null +++ b/frontend/components/pages/Contact.js @@ -0,0 +1,9 @@ +import React from 'react' +export const Contact = () => ( + return( +
+

Contact us

+

...

+
+ ) +} \ No newline at end of file diff --git a/frontend/components/pages/Nav.js b/frontend/components/pages/Nav.js new file mode 100644 index 000000000..0370a170d --- /dev/null +++ b/frontend/components/pages/Nav.js @@ -0,0 +1,13 @@ +import 'react' from 'react' +export const Nav = () => { + return +} + +) +} \ No newline at end of file diff --git a/frontend/components/pages/Welcome.js b/frontend/components/pages/Welcome.js new file mode 100644 index 000000000..eb9481330 --- /dev/null +++ b/frontend/components/pages/Welcome.js @@ -0,0 +1,9 @@ +import React from 'react' +export const Welcome = () => { + return ( +
+

Welcome to Special Garden Group

+

...

+
+ ) +} \ No newline at end of file From 778cc0ca187b549280b30790dce171f0932570b5 Mon Sep 17 00:00:00 2001 From: plazadevina Date: Mon, 4 Aug 2025 11:01:22 +0000 Subject: [PATCH 035/151] git commit -m "Code-lab-web" --- frontend/components/pages/Nav.js | 16 ++++++++---- frontend/components/pages/index.css | 40 +++++++++++++++++++++++++++-- 2 files changed, 49 insertions(+), 7 deletions(-) diff --git a/frontend/components/pages/Nav.js b/frontend/components/pages/Nav.js index 0370a170d..3b1be5d2d 100644 --- a/frontend/components/pages/Nav.js +++ b/frontend/components/pages/Nav.js @@ -1,12 +1,18 @@ import 'react' from 'react' +import {Link, Navlink,} from 'react-router-dom' export const Nav = () => { - return -} + return( ) diff --git a/frontend/components/pages/index.css b/frontend/components/pages/index.css index 31614d5fe..8b44c74a9 100644 --- a/frontend/components/pages/index.css +++ b/frontend/components/pages/index.css @@ -17,5 +17,41 @@ cursor-pointer; text-white bg-gray-900 text-xs font-bold transition-all duration-100 scale-0 orgin-left} - -} \ No newline at end of file + + body{ + margin:0; + font-family:'Courier New', Courier, monospace + main{ + margin: 20px; + { + ul{ + padding: 0: + margin: 0; + list-style-type: none; + { + li{ + display: inline-block; + margin-left: 10px; + } + } + } + } + } + } +} +nav { + display: flex; + justify-content: space-between; + align-items: center; +} +a{ + color: blue; + text-decoration: none: + article{ + border: 1px solid red + margin-button 10px; + padding: 10px; + } + a.active{ + text-decoration: underline; + } From aaf52fdeab63a0e529169922f9732d9504d67007 Mon Sep 17 00:00:00 2001 From: plazadevina Date: Mon, 4 Aug 2025 13:23:09 +0000 Subject: [PATCH 036/151] git commit -m "Code-lab-web" --- frontend/components/Home.jsx | 6 ++++++ frontend/src/App.jsx | 3 ++- frontend/src/appContentStore.jsx | 5 +++++ 3 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 frontend/components/Home.jsx create mode 100644 frontend/src/appContentStore.jsx diff --git a/frontend/components/Home.jsx b/frontend/components/Home.jsx new file mode 100644 index 000000000..0e555f46b --- /dev/null +++ b/frontend/components/Home.jsx @@ -0,0 +1,6 @@ +import {appContentStore} from "../stores/appContentStore" +export const Home () => { + const { appContent } = appContentStore() + return( +

{appContent.heading}

+} \ No newline at end of file diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 0a24275e6..e96d90a33 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -1,8 +1,9 @@ +import { Home } from "./components/Home" export const App = () => { return ( <> -

Welcome to Final Project!

+

State-Management-Zustand-Welcome to Final Project-Special Garden Group!

); }; diff --git a/frontend/src/appContentStore.jsx b/frontend/src/appContentStore.jsx new file mode 100644 index 000000000..c1de2b7da --- /dev/null +++ b/frontend/src/appContentStore.jsx @@ -0,0 +1,5 @@ +import {create} from "zustand" +export const appContentStore = create(() => ({})) +appContent:{ + heading: "State-Management-Zustand-Final Project-Special Garden Group" +} \ No newline at end of file From b4353fd62ea9eef8f733832c9f7a0953b8fd46a8 Mon Sep 17 00:00:00 2001 From: plazadevina Date: Mon, 4 Aug 2025 15:40:55 +0000 Subject: [PATCH 037/151] git commit -m "Code-lab-web" --- frontend/components/UserSettings.jsx | 17 +++++++++++++++++ frontend/components/Userinfo.jsx | 12 ++++++++++++ frontend/src/App.jsx | 5 +++++ frontend/src/{ => stores}/appContentStore.jsx | 0 frontend/src/stores/userStore.jsx | 9 +++++++++ 5 files changed, 43 insertions(+) create mode 100644 frontend/components/UserSettings.jsx create mode 100644 frontend/components/Userinfo.jsx rename frontend/src/{ => stores}/appContentStore.jsx (100%) create mode 100644 frontend/src/stores/userStore.jsx diff --git a/frontend/components/UserSettings.jsx b/frontend/components/UserSettings.jsx new file mode 100644 index 000000000..ef7fc4fc8 --- /dev/null +++ b/frontend/components/UserSettings.jsx @@ -0,0 +1,17 @@ +import { useUserStore } from "../stores/userstore" +export const UserSettings = () => { + const { toggleLogin, } inCrementAge, setUserName} isLoggedIn, userName } = useUserStore() + return( +
+

User Settings

+

Logged in: {isLoggedIn ? "Yes" : "No"}

+ + + +
+ ) +} \ No newline at end of file diff --git a/frontend/components/Userinfo.jsx b/frontend/components/Userinfo.jsx new file mode 100644 index 000000000..7d2676f14 --- /dev/null +++ b/frontend/components/Userinfo.jsx @@ -0,0 +1,12 @@ +import { useUserStore } from "../stores/userStore" +export const UserInfo = () => { + const { userName, age } = useUserStore() + +return ( +
+

User Profile

+

User Name: {userName}>

+

Age: {age}

+
+)) +} \ No newline at end of file diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index e96d90a33..869de5421 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -1,9 +1,14 @@ import { Home } from "./components/Home" +import { UserInfo } from "./components/UserInfo" +import { UserSettings } from "./components/components" export const App = () => { return ( <>

State-Management-Zustand-Welcome to Final Project-Special Garden Group!

+ + + ); }; diff --git a/frontend/src/appContentStore.jsx b/frontend/src/stores/appContentStore.jsx similarity index 100% rename from frontend/src/appContentStore.jsx rename to frontend/src/stores/appContentStore.jsx diff --git a/frontend/src/stores/userStore.jsx b/frontend/src/stores/userStore.jsx new file mode 100644 index 000000000..67e4a1797 --- /dev/null +++ b/frontend/src/stores/userStore.jsx @@ -0,0 +1,9 @@ +import { create } from "zustand" +export const useUserStore = create ((set) =>({ + isLoggedIn: false, + age: 25, + userName: "John Doe", + toggleLogin: () set ((state) => ({isLoggedIn:})) !state.isLoggedIn})) + incrementAge: () => set ((state) => ({age: state.age +1})), + setUserName: (newUserName) => set ({userName:}) +}) \ No newline at end of file From 2fbdaefd8afb944aa5d8ee5a8925aecee2db11cd Mon Sep 17 00:00:00 2001 From: plazadevina Date: Tue, 5 Aug 2025 12:18:24 +0000 Subject: [PATCH 038/151] git commit -m "Code-lab-web" --- backend/assert.js | 824 ++++++++++++++++++++++ backend/async_hooks.js | 296 ++++++++ backend/buffer.js | 1365 +++++++++++++++++++++++++++++++++++++ backend/cluster.js | 8 + backend/crypto.js | 1365 +++++++++++++++++++++++++++++++++++++ backend/dfn.js | 118 ++++ backend/hello-world.js | 14 + backend/section-links.js | 22 + backend/string_decoder.js | 125 ++++ backend/task_processor.js | 125 ++++ backend/tests.js | 75 ++ backend/tls.js | 405 +++++++++++ backend/trace_events.js | 75 ++ backend/worker_pool.js | 13 + 14 files changed, 4830 insertions(+) create mode 100644 backend/assert.js create mode 100644 backend/async_hooks.js create mode 100644 backend/buffer.js create mode 100644 backend/cluster.js create mode 100644 backend/crypto.js create mode 100644 backend/dfn.js create mode 100644 backend/hello-world.js create mode 100644 backend/section-links.js create mode 100644 backend/string_decoder.js create mode 100644 backend/task_processor.js create mode 100644 backend/tests.js create mode 100644 backend/tls.js create mode 100644 backend/trace_events.js create mode 100644 backend/worker_pool.js diff --git a/backend/assert.js b/backend/assert.js new file mode 100644 index 000000000..2ddc44d9b --- /dev/null +++ b/backend/assert.js @@ -0,0 +1,824 @@ +'use strict'; + +const { + ArrayPrototypeIndexOf, + ArrayPrototypeJoin, + ArrayPrototypePush, + ArrayPrototypeSlice, + Error, + NumberIsNaN, + ObjectAssign, + ObjectIs, + ObjectKeys, + ObjectPrototypeIsPrototypeOf, + ReflectApply, + RegExpPrototypeExec, + String, + StringPrototypeIndexOf, + StringPrototypeSlice, + StringPrototypeSplit, +} = primordials; + +const { + codes: { + ERR_AMBIGUOUS_ARGUMENT, + ERR_INVALID_ARG_TYPE, + ERR_INVALID_ARG_VALUE, + ERR_INVALID_RETURN_VALUE, + ERR_MISSING_ARGS, + }, +} = require('internal/errors'); +const AssertionError = require('internal/assert/assertion_error'); +const { inspect } = require('internal/util/inspect'); +const { + isPromise, + isRegExp, +} = require('internal/util/types'); +const { isError, deprecate } = require('internal/util'); +const { innerOk } = require('internal/assert/utils'); + +const CallTracker = require('internal/assert/calltracker'); +const { + validateFunction, +} = require('internal/validators'); + +let isDeepEqual; +let isDeepStrictEqual; +let isPartialStrictEqual; + +function lazyLoadComparison() { + const comparison = require('internal/util/comparisons'); + isDeepEqual = comparison.isDeepEqual; + isDeepStrictEqual = comparison.isDeepStrictEqual; + isPartialStrictEqual = comparison.isPartialStrictEqual; +} + +let warned = false; + +// The assert module provides functions that throw +// AssertionError's when particular conditions are not met. The +// assert module must conform to the following interface. + +const assert = module.exports = ok; + +const NO_EXCEPTION_SENTINEL = {}; + +// All of the following functions must throw an AssertionError +// when a corresponding condition is not met, with a message that +// may be undefined if not provided. All assertion methods provide +// both the actual and expected values to the assertion error for +// display purposes. + +function innerFail(obj) { + if (obj.message instanceof Error) throw obj.message; + + throw new AssertionError(obj); +} + +/** + * @param {any} actual + * @param {any} expected + * @param {string | Error} [message] + * @param {string} [operator] + * @param {Function} [stackStartFn] + */ +function fail(actual, expected, message, operator, stackStartFn) { + const argsLen = arguments.length; + + let internalMessage = false; + if (actual == null && argsLen <= 1) { + internalMessage = true; + message = 'Failed'; + } else if (argsLen === 1) { + message = actual; + actual = undefined; + } else { + if (warned === false) { + warned = true; + process.emitWarning( + 'assert.fail() with more than one argument is deprecated. ' + + 'Please use assert.strictEqual() instead or only pass a message.', + 'DeprecationWarning', + 'DEP0094', + ); + } + if (argsLen === 2) + operator = '!='; + } + + if (message instanceof Error) throw message; + + const errArgs = { + actual, + expected, + operator: operator === undefined ? 'fail' : operator, + stackStartFn: stackStartFn || fail, + message, + }; + const err = new AssertionError(errArgs); + if (internalMessage) { + err.generatedMessage = true; + } + throw err; +} + +assert.fail = fail; + +// The AssertionError is defined in internal/error. +assert.AssertionError = AssertionError; + +/** + * Pure assertion tests whether a value is truthy, as determined + * by !!value. + * @param {...any} args + * @returns {void} + */ +function ok(...args) { + innerOk(ok, args.length, ...args); +} +assert.ok = ok; + +/** + * The equality assertion tests shallow, coercive equality with ==. + * @param {any} actual + * @param {any} expected + * @param {string | Error} [message] + * @returns {void} + */ +/* eslint-disable no-restricted-properties */ +assert.equal = function equal(actual, expected, message) { + if (arguments.length < 2) { + throw new ERR_MISSING_ARGS('actual', 'expected'); + } + // eslint-disable-next-line eqeqeq + if (actual != expected && (!NumberIsNaN(actual) || !NumberIsNaN(expected))) { + innerFail({ + actual, + expected, + message, + operator: '==', + stackStartFn: equal, + }); + } +}; + +/** + * The non-equality assertion tests for whether two objects are not + * equal with !=. + * @param {any} actual + * @param {any} expected + * @param {string | Error} [message] + * @returns {void} + */ +assert.notEqual = function notEqual(actual, expected, message) { + if (arguments.length < 2) { + throw new ERR_MISSING_ARGS('actual', 'expected'); + } + // eslint-disable-next-line eqeqeq + if (actual == expected || (NumberIsNaN(actual) && NumberIsNaN(expected))) { + innerFail({ + actual, + expected, + message, + operator: '!=', + stackStartFn: notEqual, + }); + } +}; + +/** + * The deep equivalence assertion tests a deep equality relation. + * @param {any} actual + * @param {any} expected + * @param {string | Error} [message] + * @returns {void} + */ +assert.deepEqual = function deepEqual(actual, expected, message) { + if (arguments.length < 2) { + throw new ERR_MISSING_ARGS('actual', 'expected'); + } + if (isDeepEqual === undefined) lazyLoadComparison(); + if (!isDeepEqual(actual, expected)) { + innerFail({ + actual, + expected, + message, + operator: 'deepEqual', + stackStartFn: deepEqual, + }); + } +}; + +/** + * The deep non-equivalence assertion tests for any deep inequality. + * @param {any} actual + * @param {any} expected + * @param {string | Error} [message] + * @returns {void} + */ +assert.notDeepEqual = function notDeepEqual(actual, expected, message) { + if (arguments.length < 2) { + throw new ERR_MISSING_ARGS('actual', 'expected'); + } + if (isDeepEqual === undefined) lazyLoadComparison(); + if (isDeepEqual(actual, expected)) { + innerFail({ + actual, + expected, + message, + operator: 'notDeepEqual', + stackStartFn: notDeepEqual, + }); + } +}; +/* eslint-enable */ + +/** + * The deep strict equivalence assertion tests a deep strict equality + * relation. + * @param {any} actual + * @param {any} expected + * @param {string | Error} [message] + * @returns {void} + */ +assert.deepStrictEqual = function deepStrictEqual(actual, expected, message) { + if (arguments.length < 2) { + throw new ERR_MISSING_ARGS('actual', 'expected'); + } + if (isDeepEqual === undefined) lazyLoadComparison(); + if (!isDeepStrictEqual(actual, expected)) { + innerFail({ + actual, + expected, + message, + operator: 'deepStrictEqual', + stackStartFn: deepStrictEqual, + }); + } +}; + +/** + * The deep strict non-equivalence assertion tests for any deep strict + * inequality. + * @param {any} actual + * @param {any} expected + * @param {string | Error} [message] + * @returns {void} + */ +assert.notDeepStrictEqual = notDeepStrictEqual; +function notDeepStrictEqual(actual, expected, message) { + if (arguments.length < 2) { + throw new ERR_MISSING_ARGS('actual', 'expected'); + } + if (isDeepEqual === undefined) lazyLoadComparison(); + if (isDeepStrictEqual(actual, expected)) { + innerFail({ + actual, + expected, + message, + operator: 'notDeepStrictEqual', + stackStartFn: notDeepStrictEqual, + }); + } +} + +/** + * The strict equivalence assertion tests a strict equality relation. + * @param {any} actual + * @param {any} expected + * @param {string | Error} [message] + * @returns {void} + */ +assert.strictEqual = function strictEqual(actual, expected, message) { + if (arguments.length < 2) { + throw new ERR_MISSING_ARGS('actual', 'expected'); + } + if (!ObjectIs(actual, expected)) { + innerFail({ + actual, + expected, + message, + operator: 'strictEqual', + stackStartFn: strictEqual, + }); + } +}; + +/** + * The strict non-equivalence assertion tests for any strict inequality. + * @param {any} actual + * @param {any} expected + * @param {string | Error} [message] + * @returns {void} + */ +assert.notStrictEqual = function notStrictEqual(actual, expected, message) { + if (arguments.length < 2) { + throw new ERR_MISSING_ARGS('actual', 'expected'); + } + if (ObjectIs(actual, expected)) { + innerFail({ + actual, + expected, + message, + operator: 'notStrictEqual', + stackStartFn: notStrictEqual, + }); + } +}; + +/** + * The strict equivalence assertion test between two objects + * @param {any} actual + * @param {any} expected + * @param {string | Error} [message] + * @returns {void} + */ +assert.partialDeepStrictEqual = function partialDeepStrictEqual( + actual, + expected, + message, +) { + if (arguments.length < 2) { + throw new ERR_MISSING_ARGS('actual', 'expected'); + } + if (isDeepEqual === undefined) lazyLoadComparison(); + if (!isPartialStrictEqual(actual, expected)) { + innerFail({ + actual, + expected, + message, + operator: 'partialDeepStrictEqual', + stackStartFn: partialDeepStrictEqual, + }); + } +}; + +class Comparison { + constructor(obj, keys, actual) { + for (const key of keys) { + if (key in obj) { + if (actual !== undefined && + typeof actual[key] === 'string' && + isRegExp(obj[key]) && + RegExpPrototypeExec(obj[key], actual[key]) !== null) { + this[key] = actual[key]; + } else { + this[key] = obj[key]; + } + } + } + } +} + +function compareExceptionKey(actual, expected, key, message, keys, fn) { + if (!(key in actual) || !isDeepStrictEqual(actual[key], expected[key])) { + if (!message) { + // Create placeholder objects to create a nice output. + const a = new Comparison(actual, keys); + const b = new Comparison(expected, keys, actual); + + const err = new AssertionError({ + actual: a, + expected: b, + operator: 'deepStrictEqual', + stackStartFn: fn, + }); + err.actual = actual; + err.expected = expected; + err.operator = fn.name; + throw err; + } + innerFail({ + actual, + expected, + message, + operator: fn.name, + stackStartFn: fn, + }); + } +} + +function expectedException(actual, expected, message, fn) { + let generatedMessage = false; + let throwError = false; + + if (typeof expected !== 'function') { + // Handle regular expressions. + if (isRegExp(expected)) { + const str = String(actual); + if (RegExpPrototypeExec(expected, str) !== null) + return; + + if (!message) { + generatedMessage = true; + message = 'The input did not match the regular expression ' + + `${inspect(expected)}. Input:\n\n${inspect(str)}\n`; + } + throwError = true; + // Handle primitives properly. + } else if (typeof actual !== 'object' || actual === null) { + const err = new AssertionError({ + actual, + expected, + message, + operator: 'deepStrictEqual', + stackStartFn: fn, + }); + err.operator = fn.name; + throw err; + } else { + // Handle validation objects. + const keys = ObjectKeys(expected); + // Special handle errors to make sure the name and the message are + // compared as well. + if (expected instanceof Error) { + ArrayPrototypePush(keys, 'name', 'message'); + } else if (keys.length === 0) { + throw new ERR_INVALID_ARG_VALUE('error', + expected, 'may not be an empty object'); + } + if (isDeepEqual === undefined) lazyLoadComparison(); + for (const key of keys) { + if (typeof actual[key] === 'string' && + isRegExp(expected[key]) && + RegExpPrototypeExec(expected[key], actual[key]) !== null) { + continue; + } + compareExceptionKey(actual, expected, key, message, keys, fn); + } + return; + } + // Guard instanceof against arrow functions as they don't have a prototype. + // Check for matching Error classes. + } else if (expected.prototype !== undefined && actual instanceof expected) { + return; + } else if (ObjectPrototypeIsPrototypeOf(Error, expected)) { + if (!message) { + generatedMessage = true; + message = 'The error is expected to be an instance of ' + + `"${expected.name}". Received `; + if (isError(actual)) { + const name = (actual.constructor?.name) || + actual.name; + if (expected.name === name) { + message += 'an error with identical name but a different prototype.'; + } else { + message += `"${name}"`; + } + if (actual.message) { + message += `\n\nError message:\n\n${actual.message}`; + } + } else { + message += `"${inspect(actual, { depth: -1 })}"`; + } + } + throwError = true; + } else { + // Check validation functions return value. + const res = ReflectApply(expected, {}, [actual]); + if (res !== true) { + if (!message) { + generatedMessage = true; + const name = expected.name ? `"${expected.name}" ` : ''; + message = `The ${name}validation function is expected to return` + + ` "true". Received ${inspect(res)}`; + + if (isError(actual)) { + message += `\n\nCaught error:\n\n${actual}`; + } + } + throwError = true; + } + } + + if (throwError) { + const err = new AssertionError({ + actual, + expected, + message, + operator: fn.name, + stackStartFn: fn, + }); + err.generatedMessage = generatedMessage; + throw err; + } +} + +function getActual(fn) { + validateFunction(fn, 'fn'); + try { + fn(); + } catch (e) { + return e; + } + return NO_EXCEPTION_SENTINEL; +} + +function checkIsPromise(obj) { + // Accept native ES6 promises and promises that are implemented in a similar + // way. Do not accept thenables that use a function as `obj` and that have no + // `catch` handler. + return isPromise(obj) || + (obj !== null && typeof obj === 'object' && + typeof obj.then === 'function' && + typeof obj.catch === 'function'); +} + +async function waitForActual(promiseFn) { + let resultPromise; + if (typeof promiseFn === 'function') { + // Return a rejected promise if `promiseFn` throws synchronously. + resultPromise = promiseFn(); + // Fail in case no promise is returned. + if (!checkIsPromise(resultPromise)) { + throw new ERR_INVALID_RETURN_VALUE('instance of Promise', + 'promiseFn', resultPromise); + } + } else if (checkIsPromise(promiseFn)) { + resultPromise = promiseFn; + } else { + throw new ERR_INVALID_ARG_TYPE( + 'promiseFn', ['Function', 'Promise'], promiseFn); + } + + try { + await resultPromise; + } catch (e) { + return e; + } + return NO_EXCEPTION_SENTINEL; +} + +function expectsError(stackStartFn, actual, error, message) { + if (typeof error === 'string') { + if (arguments.length === 4) { + throw new ERR_INVALID_ARG_TYPE('error', + ['Object', 'Error', 'Function', 'RegExp'], + error); + } + if (typeof actual === 'object' && actual !== null) { + if (actual.message === error) { + throw new ERR_AMBIGUOUS_ARGUMENT( + 'error/message', + `The error message "${actual.message}" is identical to the message.`, + ); + } + } else if (actual === error) { + throw new ERR_AMBIGUOUS_ARGUMENT( + 'error/message', + `The error "${actual}" is identical to the message.`, + ); + } + message = error; + error = undefined; + } else if (error != null && + typeof error !== 'object' && + typeof error !== 'function') { + throw new ERR_INVALID_ARG_TYPE('error', + ['Object', 'Error', 'Function', 'RegExp'], + error); + } + + if (actual === NO_EXCEPTION_SENTINEL) { + let details = ''; + if (error?.name) { + details += ` (${error.name})`; + } + details += message ? `: ${message}` : '.'; + const fnType = stackStartFn === assert.rejects ? 'rejection' : 'exception'; + innerFail({ + actual: undefined, + expected: error, + operator: stackStartFn.name, + message: `Missing expected ${fnType}${details}`, + stackStartFn, + }); + } + + if (!error) + return; + + expectedException(actual, error, message, stackStartFn); +} + +function hasMatchingError(actual, expected) { + if (typeof expected !== 'function') { + if (isRegExp(expected)) { + const str = String(actual); + return RegExpPrototypeExec(expected, str) !== null; + } + throw new ERR_INVALID_ARG_TYPE( + 'expected', ['Function', 'RegExp'], expected, + ); + } + // Guard instanceof against arrow functions as they don't have a prototype. + if (expected.prototype !== undefined && actual instanceof expected) { + return true; + } + if (ObjectPrototypeIsPrototypeOf(Error, expected)) { + return false; + } + return ReflectApply(expected, {}, [actual]) === true; +} + +function expectsNoError(stackStartFn, actual, error, message) { + if (actual === NO_EXCEPTION_SENTINEL) + return; + + if (typeof error === 'string') { + message = error; + error = undefined; + } + + if (!error || hasMatchingError(actual, error)) { + const details = message ? `: ${message}` : '.'; + const fnType = stackStartFn === assert.doesNotReject ? + 'rejection' : 'exception'; + innerFail({ + actual, + expected: error, + operator: stackStartFn.name, + message: `Got unwanted ${fnType}${details}\n` + + `Actual message: "${actual?.message}"`, + stackStartFn, + }); + } + throw actual; +} + +/** + * Expects the function `promiseFn` to throw an error. + * @param {() => any} promiseFn + * @param {...any} [args] + * @returns {void} + */ +assert.throws = function throws(promiseFn, ...args) { + expectsError(throws, getActual(promiseFn), ...args); +}; + +/** + * Expects `promiseFn` function or its value to reject. + * @param {() => Promise} promiseFn + * @param {...any} [args] + * @returns {Promise} + */ +assert.rejects = async function rejects(promiseFn, ...args) { + expectsError(rejects, await waitForActual(promiseFn), ...args); +}; + +/** + * Asserts that the function `fn` does not throw an error. + * @param {() => any} fn + * @param {...any} [args] + * @returns {void} + */ +assert.doesNotThrow = function doesNotThrow(fn, ...args) { + expectsNoError(doesNotThrow, getActual(fn), ...args); +}; + +/** + * Expects `fn` or its value to not reject. + * @param {() => Promise} fn + * @param {...any} [args] + * @returns {Promise} + */ +assert.doesNotReject = async function doesNotReject(fn, ...args) { + expectsNoError(doesNotReject, await waitForActual(fn), ...args); +}; + +/** + * Throws `AssertionError` if the value is not `null` or `undefined`. + * @param {any} err + * @returns {void} + */ +assert.ifError = function ifError(err) { + if (err !== null && err !== undefined) { + let message = 'ifError got unwanted exception: '; + if (typeof err === 'object' && typeof err.message === 'string') { + if (err.message.length === 0 && err.constructor) { + message += err.constructor.name; + } else { + message += err.message; + } + } else { + message += inspect(err); + } + + const newErr = new AssertionError({ + actual: err, + expected: null, + operator: 'ifError', + message, + stackStartFn: ifError, + }); + + // Make sure we actually have a stack trace! + const origStack = err.stack; + + if (typeof origStack === 'string') { + // This will remove any duplicated frames from the error frames taken + // from within `ifError` and add the original error frames to the newly + // created ones. + const origStackStart = StringPrototypeIndexOf(origStack, '\n at'); + if (origStackStart !== -1) { + const originalFrames = StringPrototypeSplit( + StringPrototypeSlice(origStack, origStackStart + 1), + '\n', + ); + // Filter all frames existing in err.stack. + let newFrames = StringPrototypeSplit(newErr.stack, '\n'); + for (const errFrame of originalFrames) { + // Find the first occurrence of the frame. + const pos = ArrayPrototypeIndexOf(newFrames, errFrame); + if (pos !== -1) { + // Only keep new frames. + newFrames = ArrayPrototypeSlice(newFrames, 0, pos); + break; + } + } + const stackStart = ArrayPrototypeJoin(newFrames, '\n'); + const stackEnd = ArrayPrototypeJoin(originalFrames, '\n'); + newErr.stack = `${stackStart}\n${stackEnd}`; + } + } + + throw newErr; + } +}; + +function internalMatch(string, regexp, message, fn) { + if (!isRegExp(regexp)) { + throw new ERR_INVALID_ARG_TYPE( + 'regexp', 'RegExp', regexp, + ); + } + const match = fn === assert.match; + if (typeof string !== 'string' || + RegExpPrototypeExec(regexp, string) !== null !== match) { + if (message instanceof Error) { + throw message; + } + + const generatedMessage = !message; + + // 'The input was expected to not match the regular expression ' + + message ||= (typeof string !== 'string' ? + 'The "string" argument must be of type string. Received type ' + + `${typeof string} (${inspect(string)})` : + (match ? + 'The input did not match the regular expression ' : + 'The input was expected to not match the regular expression ') + + `${inspect(regexp)}. Input:\n\n${inspect(string)}\n`); + const err = new AssertionError({ + actual: string, + expected: regexp, + message, + operator: fn.name, + stackStartFn: fn, + }); + err.generatedMessage = generatedMessage; + throw err; + } +} + +/** + * Expects the `string` input to match the regular expression. + * @param {string} string + * @param {RegExp} regexp + * @param {string | Error} [message] + * @returns {void} + */ +assert.match = function match(string, regexp, message) { + internalMatch(string, regexp, message, match); +}; + +/** + * Expects the `string` input not to match the regular expression. + * @param {string} string + * @param {RegExp} regexp + * @param {string | Error} [message] + * @returns {void} + */ +assert.doesNotMatch = function doesNotMatch(string, regexp, message) { + internalMatch(string, regexp, message, doesNotMatch); +}; + +assert.CallTracker = deprecate(CallTracker, 'assert.CallTracker is deprecated.', 'DEP0173'); + +/** + * Expose a strict only variant of assert. + * @param {...any} args + * @returns {void} + */ +function strict(...args) { + innerOk(strict, args.length, ...args); +} + +assert.strict = ObjectAssign(strict, assert, { + equal: assert.strictEqual, + deepEqual: assert.deepStrictEqual, + notEqual: assert.notStrictEqual, + notDeepEqual: assert.notDeepStrictEqual, +}); + +assert.strict.strict = assert.strict; \ No newline at end of file diff --git a/backend/async_hooks.js b/backend/async_hooks.js new file mode 100644 index 000000000..8c57bc67f --- /dev/null +++ b/backend/async_hooks.js @@ -0,0 +1,296 @@ +'use strict'; + +const { + ArrayPrototypeIncludes, + ArrayPrototypeIndexOf, + ArrayPrototypePush, + ArrayPrototypeSplice, + ArrayPrototypeUnshift, + FunctionPrototypeBind, + NumberIsSafeInteger, + ObjectDefineProperties, + ObjectFreeze, + ReflectApply, + Symbol, +} = primordials; + +const { + ERR_ASYNC_CALLBACK, + ERR_ASYNC_TYPE, + ERR_INVALID_ASYNC_ID, +} = require('internal/errors').codes; +const { + deprecate, + kEmptyObject, +} = require('internal/util'); +const { + validateFunction, + validateString, +} = require('internal/validators'); +const internal_async_hooks = require('internal/async_hooks'); + +const AsyncContextFrame = require('internal/async_context_frame'); + +// Get functions +// For userland AsyncResources, make sure to emit a destroy event when the +// resource gets gced. +const { registerDestroyHook, kNoPromiseHook } = internal_async_hooks; +const { + asyncWrap, + executionAsyncId, + triggerAsyncId, + // Private API + hasAsyncIdStack, + getHookArrays, + enableHooks, + disableHooks, + updatePromiseHookMode, + executionAsyncResource, + // Internal Embedder API + newAsyncId, + getDefaultTriggerAsyncId, + emitInit, + emitBefore, + emitAfter, + emitDestroy, + enabledHooksExist, + initHooksExist, + destroyHooksExist, +} = internal_async_hooks; + +// Get symbols +const { + async_id_symbol, trigger_async_id_symbol, + init_symbol, before_symbol, after_symbol, destroy_symbol, + promise_resolve_symbol, +} = internal_async_hooks.symbols; + +// Get constants +const { + kInit, kBefore, kAfter, kDestroy, kTotals, kPromiseResolve, +} = internal_async_hooks.constants; + +// Listener API // + +class AsyncHook { + constructor({ init, before, after, destroy, promiseResolve }) { + if (init !== undefined && typeof init !== 'function') + throw new ERR_ASYNC_CALLBACK('hook.init'); + if (before !== undefined && typeof before !== 'function') + throw new ERR_ASYNC_CALLBACK('hook.before'); + if (after !== undefined && typeof after !== 'function') + throw new ERR_ASYNC_CALLBACK('hook.after'); + if (destroy !== undefined && typeof destroy !== 'function') + throw new ERR_ASYNC_CALLBACK('hook.destroy'); + if (promiseResolve !== undefined && typeof promiseResolve !== 'function') + throw new ERR_ASYNC_CALLBACK('hook.promiseResolve'); + + this[init_symbol] = init; + this[before_symbol] = before; + this[after_symbol] = after; + this[destroy_symbol] = destroy; + this[promise_resolve_symbol] = promiseResolve; + this[kNoPromiseHook] = false; + } + + enable() { + // The set of callbacks for a hook should be the same regardless of whether + // enable()/disable() are run during their execution. The following + // references are reassigned to the tmp arrays if a hook is currently being + // processed. + const { 0: hooks_array, 1: hook_fields } = getHookArrays(); + + // Each hook is only allowed to be added once. + if (ArrayPrototypeIncludes(hooks_array, this)) + return this; + + const prev_kTotals = hook_fields[kTotals]; + + // createHook() has already enforced that the callbacks are all functions, + // so here simply increment the count of whether each callbacks exists or + // not. + hook_fields[kTotals] = hook_fields[kInit] += +!!this[init_symbol]; + hook_fields[kTotals] += hook_fields[kBefore] += +!!this[before_symbol]; + hook_fields[kTotals] += hook_fields[kAfter] += +!!this[after_symbol]; + hook_fields[kTotals] += hook_fields[kDestroy] += +!!this[destroy_symbol]; + hook_fields[kTotals] += + hook_fields[kPromiseResolve] += +!!this[promise_resolve_symbol]; + ArrayPrototypePush(hooks_array, this); + + if (prev_kTotals === 0 && hook_fields[kTotals] > 0) { + enableHooks(); + } + + if (!this[kNoPromiseHook]) { + updatePromiseHookMode(); + } + + return this; + } + + disable() { + const { 0: hooks_array, 1: hook_fields } = getHookArrays(); + + const index = ArrayPrototypeIndexOf(hooks_array, this); + if (index === -1) + return this; + + const prev_kTotals = hook_fields[kTotals]; + + hook_fields[kTotals] = hook_fields[kInit] -= +!!this[init_symbol]; + hook_fields[kTotals] += hook_fields[kBefore] -= +!!this[before_symbol]; + hook_fields[kTotals] += hook_fields[kAfter] -= +!!this[after_symbol]; + hook_fields[kTotals] += hook_fields[kDestroy] -= +!!this[destroy_symbol]; + hook_fields[kTotals] += + hook_fields[kPromiseResolve] -= +!!this[promise_resolve_symbol]; + ArrayPrototypeSplice(hooks_array, index, 1); + + if (prev_kTotals > 0 && hook_fields[kTotals] === 0) { + disableHooks(); + } + + return this; + } +} + + +function createHook(fns) { + return new AsyncHook(fns); +} + + +// Embedder API // + +const destroyedSymbol = Symbol('destroyed'); +const contextFrameSymbol = Symbol('context_frame'); + +class AsyncResource { + constructor(type, opts = kEmptyObject) { + validateString(type, 'type'); + + let triggerAsyncId = opts; + let requireManualDestroy = false; + if (typeof opts !== 'number') { + triggerAsyncId = opts.triggerAsyncId === undefined ? + getDefaultTriggerAsyncId() : opts.triggerAsyncId; + requireManualDestroy = !!opts.requireManualDestroy; + } + + // Unlike emitInitScript, AsyncResource doesn't supports null as the + // triggerAsyncId. + if (!NumberIsSafeInteger(triggerAsyncId) || triggerAsyncId < -1) { + throw new ERR_INVALID_ASYNC_ID('triggerAsyncId', triggerAsyncId); + } + + this[contextFrameSymbol] = AsyncContextFrame.current(); + + const asyncId = newAsyncId(); + this[async_id_symbol] = asyncId; + this[trigger_async_id_symbol] = triggerAsyncId; + + if (initHooksExist()) { + if (enabledHooksExist() && type.length === 0) { + throw new ERR_ASYNC_TYPE(type); + } + + emitInit(asyncId, type, triggerAsyncId, this); + } + + if (!requireManualDestroy && destroyHooksExist()) { + // This prop name (destroyed) has to be synchronized with C++ + const destroyed = { destroyed: false }; + this[destroyedSymbol] = destroyed; + registerDestroyHook(this, asyncId, destroyed); + } + } + + runInAsyncScope(fn, thisArg, ...args) { + const asyncId = this[async_id_symbol]; + emitBefore(asyncId, this[trigger_async_id_symbol], this); + + const contextFrame = this[contextFrameSymbol]; + const prior = AsyncContextFrame.exchange(contextFrame); + try { + return ReflectApply(fn, thisArg, args); + } finally { + AsyncContextFrame.set(prior); + if (hasAsyncIdStack()) + emitAfter(asyncId); + } + } + + emitDestroy() { + if (this[destroyedSymbol] !== undefined) { + this[destroyedSymbol].destroyed = true; + } + emitDestroy(this[async_id_symbol]); + return this; + } + + asyncId() { + return this[async_id_symbol]; + } + + triggerAsyncId() { + return this[trigger_async_id_symbol]; + } + + bind(fn, thisArg) { + validateFunction(fn, 'fn'); + let bound; + if (thisArg === undefined) { + const resource = this; + bound = function(...args) { + ArrayPrototypeUnshift(args, fn, this); + return ReflectApply(resource.runInAsyncScope, resource, args); + }; + } else { + bound = FunctionPrototypeBind(this.runInAsyncScope, this, fn, thisArg); + } + let self = this; + ObjectDefineProperties(bound, { + 'length': { + __proto__: null, + configurable: true, + enumerable: false, + value: fn.length, + writable: false, + }, + 'asyncResource': { + __proto__: null, + configurable: true, + enumerable: true, + get: deprecate(function() { + return self; + }, 'The asyncResource property on bound functions is deprecated', 'DEP0172'), + set: deprecate(function(val) { + self = val; + }, 'The asyncResource property on bound functions is deprecated', 'DEP0172'), + }, + }); + return bound; + } + + static bind(fn, type, thisArg) { + type ||= fn.name; + return (new AsyncResource(type || 'bound-anonymous-fn')).bind(fn, thisArg); + } +} + +// Placing all exports down here because the exported classes won't export +// otherwise. +module.exports = { + // Public API + get AsyncLocalStorage() { + return AsyncContextFrame.enabled ? + require('internal/async_local_storage/async_context_frame') : + require('internal/async_local_storage/async_hooks'); + }, + createHook, + executionAsyncId, + triggerAsyncId, + executionAsyncResource, + asyncWrapProviders: ObjectFreeze({ __proto__: null, ...asyncWrap.Providers }), + // Embedder API + AsyncResource, +}; \ No newline at end of file diff --git a/backend/buffer.js b/backend/buffer.js new file mode 100644 index 000000000..06bfebc7e --- /dev/null +++ b/backend/buffer.js @@ -0,0 +1,1365 @@ +'use strict'; + +const { + Array, + ArrayBufferIsView, + ArrayIsArray, + ArrayPrototypeForEach, + MathFloor, + MathMin, + MathTrunc, + NumberIsInteger, + NumberIsNaN, + NumberMAX_SAFE_INTEGER, + NumberMIN_SAFE_INTEGER, + ObjectDefineProperties, + ObjectDefineProperty, + ObjectPrototypeHasOwnProperty, + ObjectSetPrototypeOf, + RegExpPrototypeSymbolReplace, + StringPrototypeCharCodeAt, + StringPrototypeSlice, + StringPrototypeToLowerCase, + StringPrototypeTrim, + SymbolSpecies, + SymbolToPrimitive, + TypedArrayPrototypeFill, + TypedArrayPrototypeGetBuffer, + TypedArrayPrototypeGetByteLength, + TypedArrayPrototypeGetByteOffset, + TypedArrayPrototypeGetLength, + TypedArrayPrototypeSet, + TypedArrayPrototypeSlice, + Uint8Array, + Uint8ArrayPrototype, +} = primordials; + +const { + byteLengthUtf8, + compare: _compare, + compareOffset, + copy: _copy, + fill: bindingFill, + isAscii: bindingIsAscii, + isUtf8: bindingIsUtf8, + indexOfBuffer, + indexOfNumber, + indexOfString, + swap16: _swap16, + swap32: _swap32, + swap64: _swap64, + kMaxLength, + kStringMaxLength, + atob: _atob, + btoa: _btoa, +} = internalBinding('buffer'); +const { + constants: { + ALL_PROPERTIES, + ONLY_ENUMERABLE, + }, + getOwnNonIndexProperties, + isInsideNodeModules, +} = internalBinding('util'); +const { + customInspectSymbol, + lazyDOMException, + normalizeEncoding, + kIsEncodingSymbol, + defineLazyProperties, + encodingsMap, + deprecate, +} = require('internal/util'); +const { + isAnyArrayBuffer, + isArrayBufferView, + isUint8Array, + isTypedArray, +} = require('internal/util/types'); +const { + inspect: utilInspect, +} = require('internal/util/inspect'); + +const { + codes: { + ERR_BUFFER_OUT_OF_BOUNDS, + ERR_INVALID_ARG_TYPE, + ERR_INVALID_ARG_VALUE, + ERR_INVALID_BUFFER_SIZE, + ERR_MISSING_ARGS, + ERR_OUT_OF_RANGE, + ERR_UNKNOWN_ENCODING, + }, + genericNodeError, +} = require('internal/errors'); +const { + validateArray, + validateBuffer, + validateInteger, + validateNumber, + validateString, +} = require('internal/validators'); +// Provide validateInteger() but with kMaxLength as the default maximum value. +const validateOffset = (value, name, min = 0, max = kMaxLength) => + validateInteger(value, name, min, max); + +const { + FastBuffer, + markAsUntransferable, + addBufferPrototypeMethods, + createUnsafeBuffer, +} = require('internal/buffer'); + +FastBuffer.prototype.constructor = Buffer; +Buffer.prototype = FastBuffer.prototype; +addBufferPrototypeMethods(Buffer.prototype); + +const constants = ObjectDefineProperties({}, { + MAX_LENGTH: { + __proto__: null, + value: kMaxLength, + writable: false, + enumerable: true, + }, + MAX_STRING_LENGTH: { + __proto__: null, + value: kStringMaxLength, + writable: false, + enumerable: true, + }, +}); + +Buffer.poolSize = 8 * 1024; +let poolSize, poolOffset, allocPool, allocBuffer; + +function createPool() { + poolSize = Buffer.poolSize; + allocBuffer = createUnsafeBuffer(poolSize); + allocPool = allocBuffer.buffer; + markAsUntransferable(allocPool); + poolOffset = 0; +} +createPool(); + +function alignPool() { + // Ensure aligned slices + if (poolOffset & 0x7) { + poolOffset |= 0x7; + poolOffset++; + } +} + +let bufferWarningAlreadyEmitted = false; +let nodeModulesCheckCounter = 0; +const bufferWarning = 'Buffer() is deprecated due to security and usability ' + + 'issues. Please use the Buffer.alloc(), ' + + 'Buffer.allocUnsafe(), or Buffer.from() methods instead.'; + +function showFlaggedDeprecation() { + if (bufferWarningAlreadyEmitted || + ++nodeModulesCheckCounter > 10000 || + (!require('internal/options').getOptionValue('--pending-deprecation') && + isInsideNodeModules(100, true))) { + // We don't emit a warning, because we either: + // - Already did so, or + // - Already checked too many times whether a call is coming + // from node_modules and want to stop slowing down things, or + // - We aren't running with `--pending-deprecation` enabled, + // and the code is inside `node_modules`. + // - We found node_modules in up to the topmost 100 frames, or + // there are more than 100 frames and we don't want to search anymore. + return; + } + + process.emitWarning(bufferWarning, 'DeprecationWarning', 'DEP0005'); + bufferWarningAlreadyEmitted = true; +} + +function toInteger(n, defaultVal) { + n = +n; + if (!NumberIsNaN(n) && + n >= NumberMIN_SAFE_INTEGER && + n <= NumberMAX_SAFE_INTEGER) { + return ((n % 1) === 0 ? n : MathFloor(n)); + } + return defaultVal; +} + +function copyImpl(source, target, targetStart, sourceStart, sourceEnd) { + if (!ArrayBufferIsView(source)) + throw new ERR_INVALID_ARG_TYPE('source', ['Buffer', 'Uint8Array'], source); + if (!ArrayBufferIsView(target)) + throw new ERR_INVALID_ARG_TYPE('target', ['Buffer', 'Uint8Array'], target); + + if (targetStart === undefined) { + targetStart = 0; + } else { + targetStart = NumberIsInteger(targetStart) ? targetStart : toInteger(targetStart, 0); + if (targetStart < 0) + throw new ERR_OUT_OF_RANGE('targetStart', '>= 0', targetStart); + } + + if (sourceStart === undefined) { + sourceStart = 0; + } else { + sourceStart = NumberIsInteger(sourceStart) ? sourceStart : toInteger(sourceStart, 0); + if (sourceStart < 0 || sourceStart > source.byteLength) + throw new ERR_OUT_OF_RANGE('sourceStart', `>= 0 && <= ${source.byteLength}`, sourceStart); + } + + if (sourceEnd === undefined) { + sourceEnd = source.byteLength; + } else { + sourceEnd = NumberIsInteger(sourceEnd) ? sourceEnd : toInteger(sourceEnd, 0); + if (sourceEnd < 0) + throw new ERR_OUT_OF_RANGE('sourceEnd', '>= 0', sourceEnd); + } + + if (targetStart >= target.byteLength || sourceStart >= sourceEnd) + return 0; + + return _copyActual(source, target, targetStart, sourceStart, sourceEnd); +} + +function _copyActual(source, target, targetStart, sourceStart, sourceEnd) { + if (sourceEnd - sourceStart > target.byteLength - targetStart) + sourceEnd = sourceStart + target.byteLength - targetStart; + + let nb = sourceEnd - sourceStart; + const sourceLen = source.byteLength - sourceStart; + if (nb > sourceLen) + nb = sourceLen; + + if (nb <= 0) + return 0; + + _copy(source, target, targetStart, sourceStart, nb); + + return nb; +} + +/** + * The Buffer() constructor is deprecated in documentation and should not be + * used moving forward. Rather, developers should use one of the three new + * factory APIs: Buffer.from(), Buffer.allocUnsafe() or Buffer.alloc() based on + * their specific needs. There is no runtime deprecation because of the extent + * to which the Buffer constructor is used in the ecosystem currently -- a + * runtime deprecation would introduce too much breakage at this time. It's not + * likely that the Buffer constructors would ever actually be removed. + * Deprecation Code: DEP0005 + * @returns {Buffer} + */ +function Buffer(arg, encodingOrOffset, length) { + showFlaggedDeprecation(); + // Common case. + if (typeof arg === 'number') { + if (typeof encodingOrOffset === 'string') { + throw new ERR_INVALID_ARG_TYPE('string', 'string', arg); + } + return Buffer.alloc(arg); + } + return Buffer.from(arg, encodingOrOffset, length); +} + +ObjectDefineProperty(Buffer, SymbolSpecies, { + __proto__: null, + enumerable: false, + configurable: true, + get() { return FastBuffer; }, +}); + +/** + * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError + * if value is a number. + * Buffer.from(str[, encoding]) + * Buffer.from(array) + * Buffer.from(buffer) + * Buffer.from(arrayBuffer[, byteOffset[, length]]) + * @param {any} value + * @param {BufferEncoding|number} encodingOrOffset + * @param {number} [length] + * @returns {Buffer} + */ +Buffer.from = function from(value, encodingOrOffset, length) { + if (typeof value === 'string') + return fromString(value, encodingOrOffset); + + if (typeof value === 'object' && value !== null) { + if (isAnyArrayBuffer(value)) + return fromArrayBuffer(value, encodingOrOffset, length); + + const valueOf = value.valueOf && value.valueOf(); + if (valueOf != null && + valueOf !== value && + (typeof valueOf === 'string' || typeof valueOf === 'object')) { + return from(valueOf, encodingOrOffset, length); + } + + const b = fromObject(value); + if (b) + return b; + + if (typeof value[SymbolToPrimitive] === 'function') { + const primitive = value[SymbolToPrimitive]('string'); + if (typeof primitive === 'string') { + return fromString(primitive, encodingOrOffset); + } + } + } + + throw new ERR_INVALID_ARG_TYPE( + 'first argument', + ['string', 'Buffer', 'ArrayBuffer', 'Array', 'Array-like Object'], + value, + ); +}; + +/** + * Creates the Buffer as a copy of the underlying ArrayBuffer of the view + * rather than the contents of the view. + * @param {TypedArray} view + * @param {number} [offset] + * @param {number} [length] + * @returns {Buffer} + */ +Buffer.copyBytesFrom = function copyBytesFrom(view, offset, length) { + if (!isTypedArray(view)) { + throw new ERR_INVALID_ARG_TYPE('view', [ 'TypedArray' ], view); + } + + const viewLength = TypedArrayPrototypeGetLength(view); + if (viewLength === 0) { + return Buffer.alloc(0); + } + + if (offset !== undefined || length !== undefined) { + if (offset !== undefined) { + validateInteger(offset, 'offset', 0); + if (offset >= viewLength) return Buffer.alloc(0); + } else { + offset = 0; + } + let end; + if (length !== undefined) { + validateInteger(length, 'length', 0); + end = offset + length; + } else { + end = viewLength; + } + + view = TypedArrayPrototypeSlice(view, offset, end); + } + + return fromArrayLike(new Uint8Array( + TypedArrayPrototypeGetBuffer(view), + TypedArrayPrototypeGetByteOffset(view), + TypedArrayPrototypeGetByteLength(view))); +}; + +// Identical to the built-in %TypedArray%.of(), but avoids using the deprecated +// Buffer() constructor. Must use arrow function syntax to avoid automatically +// adding a `prototype` property and making the function a constructor. +// +// Refs: https://tc39.github.io/ecma262/#sec-%typedarray%.of +// Refs: https://esdiscuss.org/topic/isconstructor#content-11 +const of = (...items) => { + const newObj = createUnsafeBuffer(items.length); + for (let k = 0; k < items.length; k++) + newObj[k] = items[k]; + return newObj; +}; +Buffer.of = of; + +ObjectSetPrototypeOf(Buffer, Uint8Array); + +/** + * Creates a new filled Buffer instance. + * alloc(size[, fill[, encoding]]) + * @returns {FastBuffer} + */ +Buffer.alloc = function alloc(size, fill, encoding) { + validateNumber(size, 'size', 0, kMaxLength); + if (fill !== undefined && fill !== 0 && size > 0) { + const buf = createUnsafeBuffer(size); + return _fill(buf, fill, 0, buf.length, encoding); + } + return new FastBuffer(size); +}; + +/** + * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer + * instance. If `--zero-fill-buffers` is set, will zero-fill the buffer. + * @returns {FastBuffer} + */ +Buffer.allocUnsafe = function allocUnsafe(size) { + validateNumber(size, 'size', 0, kMaxLength); + return allocate(size); +}; + +/** + * Equivalent to SlowBuffer(num), by default creates a non-zero-filled + * Buffer instance that is not allocated off the pre-initialized pool. + * If `--zero-fill-buffers` is set, will zero-fill the buffer. + * @param {number} size + * @returns {FastBuffer|undefined} + */ +Buffer.allocUnsafeSlow = function allocUnsafeSlow(size) { + validateNumber(size, 'size', 0, kMaxLength); + return createUnsafeBuffer(size); +}; + +// If --zero-fill-buffers command line argument is set, a zero-filled +// buffer is returned. +function SlowBuffer(size) { + validateNumber(size, 'size', 0, kMaxLength); + return createUnsafeBuffer(size); +} + +ObjectSetPrototypeOf(SlowBuffer.prototype, Uint8ArrayPrototype); +ObjectSetPrototypeOf(SlowBuffer, Uint8Array); + +function allocate(size) { + if (size <= 0) { + return new FastBuffer(); + } + if (size < (Buffer.poolSize >>> 1)) { + if (size > (poolSize - poolOffset)) + createPool(); + const b = new FastBuffer(allocPool, poolOffset, size); + poolOffset += size; + alignPool(); + return b; + } + return createUnsafeBuffer(size); +} + +function fromStringFast(string, ops) { + const maxLength = Buffer.poolSize >>> 1; + + let length = string.length; // Min length + + if (length >= maxLength) + return createFromString(string, ops); + + length *= 4; // Max length (4 bytes per character) + + if (length >= maxLength) + length = ops.byteLength(string); // Actual length + + if (length >= maxLength) + return createFromString(string, ops, length); + + if (length > (poolSize - poolOffset)) + createPool(); + + const actual = ops.write(allocBuffer, string, poolOffset, length); + const b = new FastBuffer(allocPool, poolOffset, actual); + + poolOffset += actual; + alignPool(); + return b; +} + +function createFromString(string, ops, length = ops.byteLength(string)) { + const buf = Buffer.allocUnsafeSlow(length); + const actual = ops.write(buf, string, 0, length); + return actual < length ? new FastBuffer(buf.buffer, 0, actual) : buf; +} + +function fromString(string, encoding) { + let ops; + if (!encoding || encoding === 'utf8' || typeof encoding !== 'string') { + ops = encodingOps.utf8; + } else { + ops = getEncodingOps(encoding); + if (ops === undefined) + throw new ERR_UNKNOWN_ENCODING(encoding); + } + + return string.length === 0 ? new FastBuffer() : fromStringFast(string, ops); +} + +function fromArrayBuffer(obj, byteOffset, length) { + // Convert byteOffset to integer + if (byteOffset === undefined) { + byteOffset = 0; + } else { + byteOffset = +byteOffset; + if (NumberIsNaN(byteOffset)) + byteOffset = 0; + } + + const maxLength = obj.byteLength - byteOffset; + + if (maxLength < 0) + throw new ERR_BUFFER_OUT_OF_BOUNDS('offset'); + + if (length !== undefined) { + // Convert length to non-negative integer. + length = +length; + if (length > 0) { + if (length > maxLength) + throw new ERR_BUFFER_OUT_OF_BOUNDS('length'); + } else { + length = 0; + } + } + + return new FastBuffer(obj, byteOffset, length); +} + +function fromArrayLike(obj) { + if (obj.length <= 0) + return new FastBuffer(); + if (obj.length < (Buffer.poolSize >>> 1)) { + if (obj.length > (poolSize - poolOffset)) + createPool(); + const b = new FastBuffer(allocPool, poolOffset, obj.length); + TypedArrayPrototypeSet(b, obj, 0); + poolOffset += obj.length; + alignPool(); + return b; + } + return new FastBuffer(obj); +} + +function fromObject(obj) { + if (obj.length !== undefined || isAnyArrayBuffer(obj.buffer)) { + if (typeof obj.length !== 'number') { + return new FastBuffer(); + } + return fromArrayLike(obj); + } + + if (obj.type === 'Buffer' && ArrayIsArray(obj.data)) { + return fromArrayLike(obj.data); + } +} + +// Static methods + +Buffer.isBuffer = function isBuffer(b) { + return b instanceof Buffer; +}; + +Buffer.compare = function compare(buf1, buf2) { + if (!isUint8Array(buf1)) { + throw new ERR_INVALID_ARG_TYPE('buf1', ['Buffer', 'Uint8Array'], buf1); + } + + if (!isUint8Array(buf2)) { + throw new ERR_INVALID_ARG_TYPE('buf2', ['Buffer', 'Uint8Array'], buf2); + } + + if (buf1 === buf2) { + return 0; + } + + return _compare(buf1, buf2); +}; + +Buffer.isEncoding = function isEncoding(encoding) { + return typeof encoding === 'string' && encoding.length !== 0 && + normalizeEncoding(encoding) !== undefined; +}; +Buffer[kIsEncodingSymbol] = Buffer.isEncoding; + +Buffer.concat = function concat(list, length) { + validateArray(list, 'list'); + + if (list.length === 0) + return new FastBuffer(); + + if (length === undefined) { + length = 0; + for (let i = 0; i < list.length; i++) { + if (list[i].length) { + length += list[i].length; + } + } + } else { + validateOffset(length, 'length'); + } + + const buffer = Buffer.allocUnsafe(length); + let pos = 0; + for (let i = 0; i < list.length; i++) { + const buf = list[i]; + if (!isUint8Array(buf)) { + // TODO(BridgeAR): This should not be of type ERR_INVALID_ARG_TYPE. + // Instead, find the proper error code for this. + throw new ERR_INVALID_ARG_TYPE( + `list[${i}]`, ['Buffer', 'Uint8Array'], list[i]); + } + pos += _copyActual(buf, buffer, pos, 0, buf.length); + } + + // Note: `length` is always equal to `buffer.length` at this point + if (pos < length) { + // Zero-fill the remaining bytes if the specified `length` was more than + // the actual total length, i.e. if we have some remaining allocated bytes + // there were not initialized. + TypedArrayPrototypeFill(buffer, 0, pos, length); + } + + return buffer; +}; + +function base64ByteLength(str, bytes) { + // Handle padding + if (StringPrototypeCharCodeAt(str, bytes - 1) === 0x3D) + bytes--; + if (bytes > 1 && StringPrototypeCharCodeAt(str, bytes - 1) === 0x3D) + bytes--; + + // Base64 ratio: 3/4 + return (bytes * 3) >>> 2; +} + +const encodingOps = { + utf8: { + encoding: 'utf8', + encodingVal: encodingsMap.utf8, + byteLength: byteLengthUtf8, + write: (buf, string, offset, len) => buf.utf8Write(string, offset, len), + slice: (buf, start, end) => buf.utf8Slice(start, end), + indexOf: (buf, val, byteOffset, dir) => + indexOfString(buf, val, byteOffset, encodingsMap.utf8, dir), + }, + ucs2: { + encoding: 'ucs2', + encodingVal: encodingsMap.utf16le, + byteLength: (string) => string.length * 2, + write: (buf, string, offset, len) => buf.ucs2Write(string, offset, len), + slice: (buf, start, end) => buf.ucs2Slice(start, end), + indexOf: (buf, val, byteOffset, dir) => + indexOfString(buf, val, byteOffset, encodingsMap.utf16le, dir), + }, + utf16le: { + encoding: 'utf16le', + encodingVal: encodingsMap.utf16le, + byteLength: (string) => string.length * 2, + write: (buf, string, offset, len) => buf.ucs2Write(string, offset, len), + slice: (buf, start, end) => buf.ucs2Slice(start, end), + indexOf: (buf, val, byteOffset, dir) => + indexOfString(buf, val, byteOffset, encodingsMap.utf16le, dir), + }, + latin1: { + encoding: 'latin1', + encodingVal: encodingsMap.latin1, + byteLength: (string) => string.length, + write: (buf, string, offset, len) => buf.latin1Write(string, offset, len), + slice: (buf, start, end) => buf.latin1Slice(start, end), + indexOf: (buf, val, byteOffset, dir) => + indexOfString(buf, val, byteOffset, encodingsMap.latin1, dir), + }, + ascii: { + encoding: 'ascii', + encodingVal: encodingsMap.ascii, + byteLength: (string) => string.length, + write: (buf, string, offset, len) => buf.asciiWrite(string, offset, len), + slice: (buf, start, end) => buf.asciiSlice(start, end), + indexOf: (buf, val, byteOffset, dir) => + indexOfBuffer(buf, + fromStringFast(val, encodingOps.ascii), + byteOffset, + encodingsMap.ascii, + dir), + }, + base64: { + encoding: 'base64', + encodingVal: encodingsMap.base64, + byteLength: (string) => base64ByteLength(string, string.length), + write: (buf, string, offset, len) => buf.base64Write(string, offset, len), + slice: (buf, start, end) => buf.base64Slice(start, end), + indexOf: (buf, val, byteOffset, dir) => + indexOfBuffer(buf, + fromStringFast(val, encodingOps.base64), + byteOffset, + encodingsMap.base64, + dir), + }, + base64url: { + encoding: 'base64url', + encodingVal: encodingsMap.base64url, + byteLength: (string) => base64ByteLength(string, string.length), + write: (buf, string, offset, len) => + buf.base64urlWrite(string, offset, len), + slice: (buf, start, end) => buf.base64urlSlice(start, end), + indexOf: (buf, val, byteOffset, dir) => + indexOfBuffer(buf, + fromStringFast(val, encodingOps.base64url), + byteOffset, + encodingsMap.base64url, + dir), + }, + hex: { + encoding: 'hex', + encodingVal: encodingsMap.hex, + byteLength: (string) => string.length >>> 1, + write: (buf, string, offset, len) => buf.hexWrite(string, offset, len), + slice: (buf, start, end) => buf.hexSlice(start, end), + indexOf: (buf, val, byteOffset, dir) => + indexOfBuffer(buf, + fromStringFast(val, encodingOps.hex), + byteOffset, + encodingsMap.hex, + dir), + }, +}; +function getEncodingOps(encoding) { + encoding += ''; + switch (encoding.length) { + case 4: + if (encoding === 'utf8') return encodingOps.utf8; + if (encoding === 'ucs2') return encodingOps.ucs2; + encoding = StringPrototypeToLowerCase(encoding); + if (encoding === 'utf8') return encodingOps.utf8; + if (encoding === 'ucs2') return encodingOps.ucs2; + break; + case 5: + if (encoding === 'utf-8') return encodingOps.utf8; + if (encoding === 'ascii') return encodingOps.ascii; + if (encoding === 'ucs-2') return encodingOps.ucs2; + encoding = StringPrototypeToLowerCase(encoding); + if (encoding === 'utf-8') return encodingOps.utf8; + if (encoding === 'ascii') return encodingOps.ascii; + if (encoding === 'ucs-2') return encodingOps.ucs2; + break; + case 7: + if (encoding === 'utf16le' || + StringPrototypeToLowerCase(encoding) === 'utf16le') + return encodingOps.utf16le; + break; + case 8: + if (encoding === 'utf-16le' || + StringPrototypeToLowerCase(encoding) === 'utf-16le') + return encodingOps.utf16le; + break; + case 6: + if (encoding === 'latin1' || encoding === 'binary') + return encodingOps.latin1; + if (encoding === 'base64') return encodingOps.base64; + encoding = StringPrototypeToLowerCase(encoding); + if (encoding === 'latin1' || encoding === 'binary') + return encodingOps.latin1; + if (encoding === 'base64') return encodingOps.base64; + break; + case 3: + if (encoding === 'hex' || StringPrototypeToLowerCase(encoding) === 'hex') + return encodingOps.hex; + break; + case 9: + if (encoding === 'base64url' || + StringPrototypeToLowerCase(encoding) === 'base64url') + return encodingOps.base64url; + break; + } +} + +function byteLength(string, encoding) { + if (typeof string !== 'string') { + if (isArrayBufferView(string) || isAnyArrayBuffer(string)) { + return string.byteLength; + } + + throw new ERR_INVALID_ARG_TYPE( + 'string', ['string', 'Buffer', 'ArrayBuffer'], string, + ); + } + + const len = string.length; + if (len === 0) + return 0; + + if (!encoding || encoding === 'utf8') { + return byteLengthUtf8(string); + } + + if (encoding === 'ascii') { + return len; + } + + const ops = getEncodingOps(encoding); + if (ops === undefined) { + // TODO (ronag): Makes more sense to throw here. + // throw new ERR_UNKNOWN_ENCODING(encoding); + return byteLengthUtf8(string); + } + + return ops.byteLength(string); +} + +Buffer.byteLength = byteLength; + +// For backwards compatibility. +ObjectDefineProperty(Buffer.prototype, 'parent', { + __proto__: null, + enumerable: true, + get() { + if (!(this instanceof Buffer)) + return undefined; + return this.buffer; + }, +}); +ObjectDefineProperty(Buffer.prototype, 'offset', { + __proto__: null, + enumerable: true, + get() { + if (!(this instanceof Buffer)) + return undefined; + return this.byteOffset; + }, +}); + +Buffer.prototype.copy = + function copy(target, targetStart, sourceStart, sourceEnd) { + return copyImpl(this, target, targetStart, sourceStart, sourceEnd); + }; + +// No need to verify that "buf.length <= MAX_UINT32" since it's a read-only +// property of a typed array. +// This behaves neither like String nor Uint8Array in that we set start/end +// to their upper/lower bounds if the value passed is out of range. +Buffer.prototype.toString = function toString(encoding, start, end) { + if (arguments.length === 0) { + return this.utf8Slice(0, this.length); + } + + const len = this.length; + + if (start <= 0) + start = 0; + else if (start >= len) + return ''; + else + start = MathTrunc(start) || 0; + + if (end === undefined || end > len) + end = len; + else + end = MathTrunc(end) || 0; + + if (end <= start) + return ''; + + if (encoding === undefined) + return this.utf8Slice(start, end); + + const ops = getEncodingOps(encoding); + if (ops === undefined) + throw new ERR_UNKNOWN_ENCODING(encoding); + + return ops.slice(this, start, end); +}; + +Buffer.prototype.equals = function equals(otherBuffer) { + if (!isUint8Array(otherBuffer)) { + throw new ERR_INVALID_ARG_TYPE( + 'otherBuffer', ['Buffer', 'Uint8Array'], otherBuffer); + } + + if (this === otherBuffer) + return true; + const len = TypedArrayPrototypeGetByteLength(this); + if (len !== TypedArrayPrototypeGetByteLength(otherBuffer)) + return false; + + return len === 0 || _compare(this, otherBuffer) === 0; +}; + +let INSPECT_MAX_BYTES = 50; +// Override how buffers are presented by util.inspect(). +Buffer.prototype[customInspectSymbol] = function inspect(recurseTimes, ctx) { + const max = INSPECT_MAX_BYTES; + const actualMax = MathMin(max, this.length); + const remaining = this.length - max; + let str = StringPrototypeTrim(RegExpPrototypeSymbolReplace( + /(.{2})/g, this.hexSlice(0, actualMax), '$1 ')); + if (remaining > 0) + str += ` ... ${remaining} more byte${remaining > 1 ? 's' : ''}`; + // Inspect special properties as well, if possible. + if (ctx) { + let extras = false; + const filter = ctx.showHidden ? ALL_PROPERTIES : ONLY_ENUMERABLE; + const obj = { __proto__: null }; + ArrayPrototypeForEach(getOwnNonIndexProperties(this, filter), + (key) => { + extras = true; + obj[key] = this[key]; + }); + if (extras) { + if (this.length !== 0) + str += ', '; + // '[Object: null prototype] {'.length === 26 + // This is guarded with a test. + str += StringPrototypeSlice(utilInspect(obj, { + ...ctx, + breakLength: Infinity, + compact: true, + }), 27, -2); + } + } + let constructorName = 'Buffer'; + try { + const { constructor } = this; + if (typeof constructor === 'function' && ObjectPrototypeHasOwnProperty(constructor, 'name')) { + constructorName = constructor.name; + } + } catch { /* Ignore error and use default name */ } + return `<${constructorName} ${str}>`; +}; +Buffer.prototype.inspect = Buffer.prototype[customInspectSymbol]; + +Buffer.prototype.compare = function compare(target, + targetStart, + targetEnd, + sourceStart, + sourceEnd) { + if (!isUint8Array(target)) { + throw new ERR_INVALID_ARG_TYPE('target', ['Buffer', 'Uint8Array'], target); + } + if (arguments.length === 1) + return _compare(this, target); + + if (targetStart === undefined) + targetStart = 0; + else + validateOffset(targetStart, 'targetStart'); + + if (targetEnd === undefined) + targetEnd = target.length; + else + validateOffset(targetEnd, 'targetEnd', 0, target.length); + + if (sourceStart === undefined) + sourceStart = 0; + else + validateOffset(sourceStart, 'sourceStart'); + + if (sourceEnd === undefined) + sourceEnd = this.length; + else + validateOffset(sourceEnd, 'sourceEnd', 0, this.length); + + if (sourceStart >= sourceEnd) + return (targetStart >= targetEnd ? 0 : -1); + if (targetStart >= targetEnd) + return 1; + + return compareOffset(this, target, targetStart, sourceStart, targetEnd, + sourceEnd); +}; + +// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`, +// OR the last index of `val` in `buffer` at offset <= `byteOffset`. +// +// Arguments: +// - buffer - a Buffer to search +// - val - a string, Buffer, or number +// - byteOffset - an index into `buffer`; will be clamped to an int32 +// - encoding - an optional encoding, relevant if val is a string +// - dir - true for indexOf, false for lastIndexOf +function bidirectionalIndexOf(buffer, val, byteOffset, encoding, dir) { + validateBuffer(buffer); + + if (typeof byteOffset === 'string') { + encoding = byteOffset; + byteOffset = undefined; + } else if (byteOffset > 0x7fffffff) { + byteOffset = 0x7fffffff; + } else if (byteOffset < -0x80000000) { + byteOffset = -0x80000000; + } + // Coerce to Number. Values like null and [] become 0. + byteOffset = +byteOffset; + // If the offset is undefined, "foo", {}, coerces to NaN, search whole buffer. + if (NumberIsNaN(byteOffset)) { + byteOffset = dir ? 0 : (buffer.length || buffer.byteLength); + } + dir = !!dir; // Cast to bool. + + if (typeof val === 'number') + return indexOfNumber(buffer, val >>> 0, byteOffset, dir); + + let ops; + if (encoding === undefined) + ops = encodingOps.utf8; + else + ops = getEncodingOps(encoding); + + if (typeof val === 'string') { + if (ops === undefined) + throw new ERR_UNKNOWN_ENCODING(encoding); + return ops.indexOf(buffer, val, byteOffset, dir); + } + + if (isUint8Array(val)) { + const encodingVal = + (ops === undefined ? encodingsMap.utf8 : ops.encodingVal); + return indexOfBuffer(buffer, val, byteOffset, encodingVal, dir); + } + + throw new ERR_INVALID_ARG_TYPE( + 'value', ['number', 'string', 'Buffer', 'Uint8Array'], val, + ); +} + +Buffer.prototype.indexOf = function indexOf(val, byteOffset, encoding) { + return bidirectionalIndexOf(this, val, byteOffset, encoding, true); +}; + +Buffer.prototype.lastIndexOf = function lastIndexOf(val, byteOffset, encoding) { + return bidirectionalIndexOf(this, val, byteOffset, encoding, false); +}; + +Buffer.prototype.includes = function includes(val, byteOffset, encoding) { + return this.indexOf(val, byteOffset, encoding) !== -1; +}; + +// Usage: +// buffer.fill(number[, offset[, end]]) +// buffer.fill(buffer[, offset[, end]]) +// buffer.fill(string[, offset[, end]][, encoding]) +Buffer.prototype.fill = function fill(value, offset, end, encoding) { + return _fill(this, value, offset, end, encoding); +}; + +function _fill(buf, value, offset, end, encoding) { + if (typeof value === 'string') { + if (offset === undefined || typeof offset === 'string') { + encoding = offset; + offset = 0; + end = buf.length; + } else if (typeof end === 'string') { + encoding = end; + end = buf.length; + } + + const normalizedEncoding = normalizeEncoding(encoding); + if (normalizedEncoding === undefined) { + validateString(encoding, 'encoding'); + throw new ERR_UNKNOWN_ENCODING(encoding); + } + + if (value.length === 0) { + // If value === '' default to zero. + value = 0; + } else if (value.length === 1) { + // Fast path: If `value` fits into a single byte, use that numeric value. + if (normalizedEncoding === 'utf8') { + const code = StringPrototypeCharCodeAt(value, 0); + if (code < 128) { + value = code; + } + } else if (normalizedEncoding === 'latin1') { + value = StringPrototypeCharCodeAt(value, 0); + } + } + } else { + encoding = undefined; + } + + if (offset === undefined) { + offset = 0; + end = buf.length; + } else { + validateOffset(offset, 'offset'); + // Invalid ranges are not set to a default, so can range check early. + if (end === undefined) { + end = buf.length; + } else { + validateOffset(end, 'end', 0, buf.length); + } + if (offset >= end) + return buf; + } + + + if (typeof value === 'number') { + // OOB check + const byteLen = TypedArrayPrototypeGetByteLength(buf); + const fillLength = end - offset; + if (offset > end || fillLength + offset > byteLen) + throw new ERR_BUFFER_OUT_OF_BOUNDS(); + + TypedArrayPrototypeFill(buf, value, offset, end); + } else { + const res = bindingFill(buf, value, offset, end, encoding); + if (res < 0) { + if (res === -1) + throw new ERR_INVALID_ARG_VALUE('value', value); + throw new ERR_BUFFER_OUT_OF_BOUNDS(); + } + } + + return buf; +} + +Buffer.prototype.write = function write(string, offset, length, encoding) { + // Buffer#write(string); + if (offset === undefined) { + return this.utf8Write(string, 0, this.length); + } + // Buffer#write(string, encoding) + if (length === undefined && typeof offset === 'string') { + encoding = offset; + length = this.length; + offset = 0; + + // Buffer#write(string, offset[, length][, encoding]) + } else { + validateOffset(offset, 'offset', 0, this.length); + + const remaining = this.length - offset; + + if (length === undefined) { + length = remaining; + } else if (typeof length === 'string') { + encoding = length; + length = remaining; + } else { + validateOffset(length, 'length', 0, this.length); + if (length > remaining) + length = remaining; + } + } + + if (!encoding || encoding === 'utf8') + return this.utf8Write(string, offset, length); + if (encoding === 'ascii') + return this.asciiWrite(string, offset, length); + + const ops = getEncodingOps(encoding); + if (ops === undefined) + throw new ERR_UNKNOWN_ENCODING(encoding); + return ops.write(this, string, offset, length); +}; + +Buffer.prototype.toJSON = function toJSON() { + if (this.length > 0) { + const data = new Array(this.length); + for (let i = 0; i < this.length; ++i) + data[i] = this[i]; + return { type: 'Buffer', data }; + } + return { type: 'Buffer', data: [] }; +}; + +function adjustOffset(offset, length) { + // Use Math.trunc() to convert offset to an integer value that can be larger + // than an Int32. Hence, don't use offset | 0 or similar techniques. + offset = MathTrunc(offset); + if (offset === 0) { + return 0; + } + if (offset < 0) { + offset += length; + return offset > 0 ? offset : 0; + } + if (offset < length) { + return offset; + } + return NumberIsNaN(offset) ? 0 : length; +} + +Buffer.prototype.subarray = function subarray(start, end) { + const srcLength = this.length; + start = adjustOffset(start, srcLength); + end = end !== undefined ? adjustOffset(end, srcLength) : srcLength; + const newLength = end > start ? end - start : 0; + return new FastBuffer(this.buffer, this.byteOffset + start, newLength); +}; + +Buffer.prototype.slice = function slice(start, end) { + return this.subarray(start, end); +}; + +function swap(b, n, m) { + const i = b[n]; + b[n] = b[m]; + b[m] = i; +} + +Buffer.prototype.swap16 = function swap16() { + // For Buffer.length < 128, it's generally faster to + // do the swap in javascript. For larger buffers, + // dropping down to the native code is faster. + const len = this.length; + if (len % 2 !== 0) + throw new ERR_INVALID_BUFFER_SIZE('16-bits'); + if (len < 128) { + for (let i = 0; i < len; i += 2) + swap(this, i, i + 1); + return this; + } + return _swap16(this); +}; + +Buffer.prototype.swap32 = function swap32() { + // For Buffer.length < 192, it's generally faster to + // do the swap in javascript. For larger buffers, + // dropping down to the native code is faster. + const len = this.length; + if (len % 4 !== 0) + throw new ERR_INVALID_BUFFER_SIZE('32-bits'); + if (len < 192) { + for (let i = 0; i < len; i += 4) { + swap(this, i, i + 3); + swap(this, i + 1, i + 2); + } + return this; + } + return _swap32(this); +}; + +Buffer.prototype.swap64 = function swap64() { + // For Buffer.length < 192, it's generally faster to + // do the swap in javascript. For larger buffers, + // dropping down to the native code is faster. + const len = this.length; + if (len % 8 !== 0) + throw new ERR_INVALID_BUFFER_SIZE('64-bits'); + if (len < 192) { + for (let i = 0; i < len; i += 8) { + swap(this, i, i + 7); + swap(this, i + 1, i + 6); + swap(this, i + 2, i + 5); + swap(this, i + 3, i + 4); + } + return this; + } + return _swap64(this); +}; + +Buffer.prototype.toLocaleString = Buffer.prototype.toString; + +let transcode; +if (internalBinding('config').hasIntl) { + const { + icuErrName, + transcode: _transcode, + } = internalBinding('icu'); + + // Transcodes the Buffer from one encoding to another, returning a new + // Buffer instance. + transcode = function transcode(source, fromEncoding, toEncoding) { + if (!isUint8Array(source)) { + throw new ERR_INVALID_ARG_TYPE('source', + ['Buffer', 'Uint8Array'], source); + } + if (source.length === 0) return Buffer.alloc(0); + + fromEncoding = normalizeEncoding(fromEncoding) || fromEncoding; + toEncoding = normalizeEncoding(toEncoding) || toEncoding; + const result = _transcode(source, fromEncoding, toEncoding); + if (typeof result !== 'number') + return result; + + const code = icuErrName(result); + const err = genericNodeError( + `Unable to transcode Buffer [${code}]`, + { code: code, errno: result }, + ); + throw err; + }; +} + +function btoa(input) { + // The implementation here has not been performance optimized in any way and + // should not be. + // Refs: https://github.com/nodejs/node/pull/38433#issuecomment-828426932 + if (arguments.length === 0) { + throw new ERR_MISSING_ARGS('input'); + } + const result = _btoa(`${input}`); + if (result === -1) { + throw lazyDOMException('Invalid character', 'InvalidCharacterError'); + } + return result; +} + +function atob(input) { + if (arguments.length === 0) { + throw new ERR_MISSING_ARGS('input'); + } + + const result = _atob(`${input}`); + + switch (result) { + case -2: // Invalid character + throw lazyDOMException('Invalid character', 'InvalidCharacterError'); + case -1: // Single character remained + throw lazyDOMException( + 'The string to be decoded is not correctly encoded.', + 'InvalidCharacterError'); + case -3: // Possible overflow + // TODO(@anonrig): Throw correct error in here. + throw lazyDOMException('The input causes overflow.', 'InvalidCharacterError'); + default: + return result; + } +} + +function isUtf8(input) { + if (isTypedArray(input) || isAnyArrayBuffer(input)) { + return bindingIsUtf8(input); + } + + throw new ERR_INVALID_ARG_TYPE('input', ['ArrayBuffer', 'Buffer', 'TypedArray'], input); +} + +function isAscii(input) { + if (isTypedArray(input) || isAnyArrayBuffer(input)) { + return bindingIsAscii(input); + } + + throw new ERR_INVALID_ARG_TYPE('input', ['ArrayBuffer', 'Buffer', 'TypedArray'], input); +} + +module.exports = { + Buffer, + SlowBuffer: deprecate( + SlowBuffer, + 'SlowBuffer() is deprecated. Please use Buffer.allocUnsafeSlow()', + 'DEP0030'), + transcode, + isUtf8, + isAscii, + + // Legacy + kMaxLength, + kStringMaxLength, + btoa, + atob, +}; + +ObjectDefineProperties(module.exports, { + constants: { + __proto__: null, + configurable: false, + enumerable: true, + value: constants, + }, + INSPECT_MAX_BYTES: { + __proto__: null, + configurable: true, + enumerable: true, + get() { return INSPECT_MAX_BYTES; }, + set(val) { + validateNumber(val, 'INSPECT_MAX_BYTES', 0); + INSPECT_MAX_BYTES = val; + }, + }, +}); + +defineLazyProperties( + module.exports, + 'internal/blob', + ['Blob', 'resolveObjectURL'], +); +defineLazyProperties( + module.exports, + 'internal/file', + ['File'], +); \ No newline at end of file diff --git a/backend/cluster.js b/backend/cluster.js new file mode 100644 index 000000000..6f3dc1689 --- /dev/null +++ b/backend/cluster.js @@ -0,0 +1,8 @@ +'use strict'; + +const { + ObjectPrototypeHasOwnProperty: ObjectHasOwn, +} = primordials; + +const childOrPrimary = ObjectHasOwn(process.env, 'NODE_UNIQUE_ID') ? 'child' : 'primary'; +module.exports = require(`internal/cluster/${childOrPrimary}`); \ No newline at end of file diff --git a/backend/crypto.js b/backend/crypto.js new file mode 100644 index 000000000..06bfebc7e --- /dev/null +++ b/backend/crypto.js @@ -0,0 +1,1365 @@ +'use strict'; + +const { + Array, + ArrayBufferIsView, + ArrayIsArray, + ArrayPrototypeForEach, + MathFloor, + MathMin, + MathTrunc, + NumberIsInteger, + NumberIsNaN, + NumberMAX_SAFE_INTEGER, + NumberMIN_SAFE_INTEGER, + ObjectDefineProperties, + ObjectDefineProperty, + ObjectPrototypeHasOwnProperty, + ObjectSetPrototypeOf, + RegExpPrototypeSymbolReplace, + StringPrototypeCharCodeAt, + StringPrototypeSlice, + StringPrototypeToLowerCase, + StringPrototypeTrim, + SymbolSpecies, + SymbolToPrimitive, + TypedArrayPrototypeFill, + TypedArrayPrototypeGetBuffer, + TypedArrayPrototypeGetByteLength, + TypedArrayPrototypeGetByteOffset, + TypedArrayPrototypeGetLength, + TypedArrayPrototypeSet, + TypedArrayPrototypeSlice, + Uint8Array, + Uint8ArrayPrototype, +} = primordials; + +const { + byteLengthUtf8, + compare: _compare, + compareOffset, + copy: _copy, + fill: bindingFill, + isAscii: bindingIsAscii, + isUtf8: bindingIsUtf8, + indexOfBuffer, + indexOfNumber, + indexOfString, + swap16: _swap16, + swap32: _swap32, + swap64: _swap64, + kMaxLength, + kStringMaxLength, + atob: _atob, + btoa: _btoa, +} = internalBinding('buffer'); +const { + constants: { + ALL_PROPERTIES, + ONLY_ENUMERABLE, + }, + getOwnNonIndexProperties, + isInsideNodeModules, +} = internalBinding('util'); +const { + customInspectSymbol, + lazyDOMException, + normalizeEncoding, + kIsEncodingSymbol, + defineLazyProperties, + encodingsMap, + deprecate, +} = require('internal/util'); +const { + isAnyArrayBuffer, + isArrayBufferView, + isUint8Array, + isTypedArray, +} = require('internal/util/types'); +const { + inspect: utilInspect, +} = require('internal/util/inspect'); + +const { + codes: { + ERR_BUFFER_OUT_OF_BOUNDS, + ERR_INVALID_ARG_TYPE, + ERR_INVALID_ARG_VALUE, + ERR_INVALID_BUFFER_SIZE, + ERR_MISSING_ARGS, + ERR_OUT_OF_RANGE, + ERR_UNKNOWN_ENCODING, + }, + genericNodeError, +} = require('internal/errors'); +const { + validateArray, + validateBuffer, + validateInteger, + validateNumber, + validateString, +} = require('internal/validators'); +// Provide validateInteger() but with kMaxLength as the default maximum value. +const validateOffset = (value, name, min = 0, max = kMaxLength) => + validateInteger(value, name, min, max); + +const { + FastBuffer, + markAsUntransferable, + addBufferPrototypeMethods, + createUnsafeBuffer, +} = require('internal/buffer'); + +FastBuffer.prototype.constructor = Buffer; +Buffer.prototype = FastBuffer.prototype; +addBufferPrototypeMethods(Buffer.prototype); + +const constants = ObjectDefineProperties({}, { + MAX_LENGTH: { + __proto__: null, + value: kMaxLength, + writable: false, + enumerable: true, + }, + MAX_STRING_LENGTH: { + __proto__: null, + value: kStringMaxLength, + writable: false, + enumerable: true, + }, +}); + +Buffer.poolSize = 8 * 1024; +let poolSize, poolOffset, allocPool, allocBuffer; + +function createPool() { + poolSize = Buffer.poolSize; + allocBuffer = createUnsafeBuffer(poolSize); + allocPool = allocBuffer.buffer; + markAsUntransferable(allocPool); + poolOffset = 0; +} +createPool(); + +function alignPool() { + // Ensure aligned slices + if (poolOffset & 0x7) { + poolOffset |= 0x7; + poolOffset++; + } +} + +let bufferWarningAlreadyEmitted = false; +let nodeModulesCheckCounter = 0; +const bufferWarning = 'Buffer() is deprecated due to security and usability ' + + 'issues. Please use the Buffer.alloc(), ' + + 'Buffer.allocUnsafe(), or Buffer.from() methods instead.'; + +function showFlaggedDeprecation() { + if (bufferWarningAlreadyEmitted || + ++nodeModulesCheckCounter > 10000 || + (!require('internal/options').getOptionValue('--pending-deprecation') && + isInsideNodeModules(100, true))) { + // We don't emit a warning, because we either: + // - Already did so, or + // - Already checked too many times whether a call is coming + // from node_modules and want to stop slowing down things, or + // - We aren't running with `--pending-deprecation` enabled, + // and the code is inside `node_modules`. + // - We found node_modules in up to the topmost 100 frames, or + // there are more than 100 frames and we don't want to search anymore. + return; + } + + process.emitWarning(bufferWarning, 'DeprecationWarning', 'DEP0005'); + bufferWarningAlreadyEmitted = true; +} + +function toInteger(n, defaultVal) { + n = +n; + if (!NumberIsNaN(n) && + n >= NumberMIN_SAFE_INTEGER && + n <= NumberMAX_SAFE_INTEGER) { + return ((n % 1) === 0 ? n : MathFloor(n)); + } + return defaultVal; +} + +function copyImpl(source, target, targetStart, sourceStart, sourceEnd) { + if (!ArrayBufferIsView(source)) + throw new ERR_INVALID_ARG_TYPE('source', ['Buffer', 'Uint8Array'], source); + if (!ArrayBufferIsView(target)) + throw new ERR_INVALID_ARG_TYPE('target', ['Buffer', 'Uint8Array'], target); + + if (targetStart === undefined) { + targetStart = 0; + } else { + targetStart = NumberIsInteger(targetStart) ? targetStart : toInteger(targetStart, 0); + if (targetStart < 0) + throw new ERR_OUT_OF_RANGE('targetStart', '>= 0', targetStart); + } + + if (sourceStart === undefined) { + sourceStart = 0; + } else { + sourceStart = NumberIsInteger(sourceStart) ? sourceStart : toInteger(sourceStart, 0); + if (sourceStart < 0 || sourceStart > source.byteLength) + throw new ERR_OUT_OF_RANGE('sourceStart', `>= 0 && <= ${source.byteLength}`, sourceStart); + } + + if (sourceEnd === undefined) { + sourceEnd = source.byteLength; + } else { + sourceEnd = NumberIsInteger(sourceEnd) ? sourceEnd : toInteger(sourceEnd, 0); + if (sourceEnd < 0) + throw new ERR_OUT_OF_RANGE('sourceEnd', '>= 0', sourceEnd); + } + + if (targetStart >= target.byteLength || sourceStart >= sourceEnd) + return 0; + + return _copyActual(source, target, targetStart, sourceStart, sourceEnd); +} + +function _copyActual(source, target, targetStart, sourceStart, sourceEnd) { + if (sourceEnd - sourceStart > target.byteLength - targetStart) + sourceEnd = sourceStart + target.byteLength - targetStart; + + let nb = sourceEnd - sourceStart; + const sourceLen = source.byteLength - sourceStart; + if (nb > sourceLen) + nb = sourceLen; + + if (nb <= 0) + return 0; + + _copy(source, target, targetStart, sourceStart, nb); + + return nb; +} + +/** + * The Buffer() constructor is deprecated in documentation and should not be + * used moving forward. Rather, developers should use one of the three new + * factory APIs: Buffer.from(), Buffer.allocUnsafe() or Buffer.alloc() based on + * their specific needs. There is no runtime deprecation because of the extent + * to which the Buffer constructor is used in the ecosystem currently -- a + * runtime deprecation would introduce too much breakage at this time. It's not + * likely that the Buffer constructors would ever actually be removed. + * Deprecation Code: DEP0005 + * @returns {Buffer} + */ +function Buffer(arg, encodingOrOffset, length) { + showFlaggedDeprecation(); + // Common case. + if (typeof arg === 'number') { + if (typeof encodingOrOffset === 'string') { + throw new ERR_INVALID_ARG_TYPE('string', 'string', arg); + } + return Buffer.alloc(arg); + } + return Buffer.from(arg, encodingOrOffset, length); +} + +ObjectDefineProperty(Buffer, SymbolSpecies, { + __proto__: null, + enumerable: false, + configurable: true, + get() { return FastBuffer; }, +}); + +/** + * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError + * if value is a number. + * Buffer.from(str[, encoding]) + * Buffer.from(array) + * Buffer.from(buffer) + * Buffer.from(arrayBuffer[, byteOffset[, length]]) + * @param {any} value + * @param {BufferEncoding|number} encodingOrOffset + * @param {number} [length] + * @returns {Buffer} + */ +Buffer.from = function from(value, encodingOrOffset, length) { + if (typeof value === 'string') + return fromString(value, encodingOrOffset); + + if (typeof value === 'object' && value !== null) { + if (isAnyArrayBuffer(value)) + return fromArrayBuffer(value, encodingOrOffset, length); + + const valueOf = value.valueOf && value.valueOf(); + if (valueOf != null && + valueOf !== value && + (typeof valueOf === 'string' || typeof valueOf === 'object')) { + return from(valueOf, encodingOrOffset, length); + } + + const b = fromObject(value); + if (b) + return b; + + if (typeof value[SymbolToPrimitive] === 'function') { + const primitive = value[SymbolToPrimitive]('string'); + if (typeof primitive === 'string') { + return fromString(primitive, encodingOrOffset); + } + } + } + + throw new ERR_INVALID_ARG_TYPE( + 'first argument', + ['string', 'Buffer', 'ArrayBuffer', 'Array', 'Array-like Object'], + value, + ); +}; + +/** + * Creates the Buffer as a copy of the underlying ArrayBuffer of the view + * rather than the contents of the view. + * @param {TypedArray} view + * @param {number} [offset] + * @param {number} [length] + * @returns {Buffer} + */ +Buffer.copyBytesFrom = function copyBytesFrom(view, offset, length) { + if (!isTypedArray(view)) { + throw new ERR_INVALID_ARG_TYPE('view', [ 'TypedArray' ], view); + } + + const viewLength = TypedArrayPrototypeGetLength(view); + if (viewLength === 0) { + return Buffer.alloc(0); + } + + if (offset !== undefined || length !== undefined) { + if (offset !== undefined) { + validateInteger(offset, 'offset', 0); + if (offset >= viewLength) return Buffer.alloc(0); + } else { + offset = 0; + } + let end; + if (length !== undefined) { + validateInteger(length, 'length', 0); + end = offset + length; + } else { + end = viewLength; + } + + view = TypedArrayPrototypeSlice(view, offset, end); + } + + return fromArrayLike(new Uint8Array( + TypedArrayPrototypeGetBuffer(view), + TypedArrayPrototypeGetByteOffset(view), + TypedArrayPrototypeGetByteLength(view))); +}; + +// Identical to the built-in %TypedArray%.of(), but avoids using the deprecated +// Buffer() constructor. Must use arrow function syntax to avoid automatically +// adding a `prototype` property and making the function a constructor. +// +// Refs: https://tc39.github.io/ecma262/#sec-%typedarray%.of +// Refs: https://esdiscuss.org/topic/isconstructor#content-11 +const of = (...items) => { + const newObj = createUnsafeBuffer(items.length); + for (let k = 0; k < items.length; k++) + newObj[k] = items[k]; + return newObj; +}; +Buffer.of = of; + +ObjectSetPrototypeOf(Buffer, Uint8Array); + +/** + * Creates a new filled Buffer instance. + * alloc(size[, fill[, encoding]]) + * @returns {FastBuffer} + */ +Buffer.alloc = function alloc(size, fill, encoding) { + validateNumber(size, 'size', 0, kMaxLength); + if (fill !== undefined && fill !== 0 && size > 0) { + const buf = createUnsafeBuffer(size); + return _fill(buf, fill, 0, buf.length, encoding); + } + return new FastBuffer(size); +}; + +/** + * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer + * instance. If `--zero-fill-buffers` is set, will zero-fill the buffer. + * @returns {FastBuffer} + */ +Buffer.allocUnsafe = function allocUnsafe(size) { + validateNumber(size, 'size', 0, kMaxLength); + return allocate(size); +}; + +/** + * Equivalent to SlowBuffer(num), by default creates a non-zero-filled + * Buffer instance that is not allocated off the pre-initialized pool. + * If `--zero-fill-buffers` is set, will zero-fill the buffer. + * @param {number} size + * @returns {FastBuffer|undefined} + */ +Buffer.allocUnsafeSlow = function allocUnsafeSlow(size) { + validateNumber(size, 'size', 0, kMaxLength); + return createUnsafeBuffer(size); +}; + +// If --zero-fill-buffers command line argument is set, a zero-filled +// buffer is returned. +function SlowBuffer(size) { + validateNumber(size, 'size', 0, kMaxLength); + return createUnsafeBuffer(size); +} + +ObjectSetPrototypeOf(SlowBuffer.prototype, Uint8ArrayPrototype); +ObjectSetPrototypeOf(SlowBuffer, Uint8Array); + +function allocate(size) { + if (size <= 0) { + return new FastBuffer(); + } + if (size < (Buffer.poolSize >>> 1)) { + if (size > (poolSize - poolOffset)) + createPool(); + const b = new FastBuffer(allocPool, poolOffset, size); + poolOffset += size; + alignPool(); + return b; + } + return createUnsafeBuffer(size); +} + +function fromStringFast(string, ops) { + const maxLength = Buffer.poolSize >>> 1; + + let length = string.length; // Min length + + if (length >= maxLength) + return createFromString(string, ops); + + length *= 4; // Max length (4 bytes per character) + + if (length >= maxLength) + length = ops.byteLength(string); // Actual length + + if (length >= maxLength) + return createFromString(string, ops, length); + + if (length > (poolSize - poolOffset)) + createPool(); + + const actual = ops.write(allocBuffer, string, poolOffset, length); + const b = new FastBuffer(allocPool, poolOffset, actual); + + poolOffset += actual; + alignPool(); + return b; +} + +function createFromString(string, ops, length = ops.byteLength(string)) { + const buf = Buffer.allocUnsafeSlow(length); + const actual = ops.write(buf, string, 0, length); + return actual < length ? new FastBuffer(buf.buffer, 0, actual) : buf; +} + +function fromString(string, encoding) { + let ops; + if (!encoding || encoding === 'utf8' || typeof encoding !== 'string') { + ops = encodingOps.utf8; + } else { + ops = getEncodingOps(encoding); + if (ops === undefined) + throw new ERR_UNKNOWN_ENCODING(encoding); + } + + return string.length === 0 ? new FastBuffer() : fromStringFast(string, ops); +} + +function fromArrayBuffer(obj, byteOffset, length) { + // Convert byteOffset to integer + if (byteOffset === undefined) { + byteOffset = 0; + } else { + byteOffset = +byteOffset; + if (NumberIsNaN(byteOffset)) + byteOffset = 0; + } + + const maxLength = obj.byteLength - byteOffset; + + if (maxLength < 0) + throw new ERR_BUFFER_OUT_OF_BOUNDS('offset'); + + if (length !== undefined) { + // Convert length to non-negative integer. + length = +length; + if (length > 0) { + if (length > maxLength) + throw new ERR_BUFFER_OUT_OF_BOUNDS('length'); + } else { + length = 0; + } + } + + return new FastBuffer(obj, byteOffset, length); +} + +function fromArrayLike(obj) { + if (obj.length <= 0) + return new FastBuffer(); + if (obj.length < (Buffer.poolSize >>> 1)) { + if (obj.length > (poolSize - poolOffset)) + createPool(); + const b = new FastBuffer(allocPool, poolOffset, obj.length); + TypedArrayPrototypeSet(b, obj, 0); + poolOffset += obj.length; + alignPool(); + return b; + } + return new FastBuffer(obj); +} + +function fromObject(obj) { + if (obj.length !== undefined || isAnyArrayBuffer(obj.buffer)) { + if (typeof obj.length !== 'number') { + return new FastBuffer(); + } + return fromArrayLike(obj); + } + + if (obj.type === 'Buffer' && ArrayIsArray(obj.data)) { + return fromArrayLike(obj.data); + } +} + +// Static methods + +Buffer.isBuffer = function isBuffer(b) { + return b instanceof Buffer; +}; + +Buffer.compare = function compare(buf1, buf2) { + if (!isUint8Array(buf1)) { + throw new ERR_INVALID_ARG_TYPE('buf1', ['Buffer', 'Uint8Array'], buf1); + } + + if (!isUint8Array(buf2)) { + throw new ERR_INVALID_ARG_TYPE('buf2', ['Buffer', 'Uint8Array'], buf2); + } + + if (buf1 === buf2) { + return 0; + } + + return _compare(buf1, buf2); +}; + +Buffer.isEncoding = function isEncoding(encoding) { + return typeof encoding === 'string' && encoding.length !== 0 && + normalizeEncoding(encoding) !== undefined; +}; +Buffer[kIsEncodingSymbol] = Buffer.isEncoding; + +Buffer.concat = function concat(list, length) { + validateArray(list, 'list'); + + if (list.length === 0) + return new FastBuffer(); + + if (length === undefined) { + length = 0; + for (let i = 0; i < list.length; i++) { + if (list[i].length) { + length += list[i].length; + } + } + } else { + validateOffset(length, 'length'); + } + + const buffer = Buffer.allocUnsafe(length); + let pos = 0; + for (let i = 0; i < list.length; i++) { + const buf = list[i]; + if (!isUint8Array(buf)) { + // TODO(BridgeAR): This should not be of type ERR_INVALID_ARG_TYPE. + // Instead, find the proper error code for this. + throw new ERR_INVALID_ARG_TYPE( + `list[${i}]`, ['Buffer', 'Uint8Array'], list[i]); + } + pos += _copyActual(buf, buffer, pos, 0, buf.length); + } + + // Note: `length` is always equal to `buffer.length` at this point + if (pos < length) { + // Zero-fill the remaining bytes if the specified `length` was more than + // the actual total length, i.e. if we have some remaining allocated bytes + // there were not initialized. + TypedArrayPrototypeFill(buffer, 0, pos, length); + } + + return buffer; +}; + +function base64ByteLength(str, bytes) { + // Handle padding + if (StringPrototypeCharCodeAt(str, bytes - 1) === 0x3D) + bytes--; + if (bytes > 1 && StringPrototypeCharCodeAt(str, bytes - 1) === 0x3D) + bytes--; + + // Base64 ratio: 3/4 + return (bytes * 3) >>> 2; +} + +const encodingOps = { + utf8: { + encoding: 'utf8', + encodingVal: encodingsMap.utf8, + byteLength: byteLengthUtf8, + write: (buf, string, offset, len) => buf.utf8Write(string, offset, len), + slice: (buf, start, end) => buf.utf8Slice(start, end), + indexOf: (buf, val, byteOffset, dir) => + indexOfString(buf, val, byteOffset, encodingsMap.utf8, dir), + }, + ucs2: { + encoding: 'ucs2', + encodingVal: encodingsMap.utf16le, + byteLength: (string) => string.length * 2, + write: (buf, string, offset, len) => buf.ucs2Write(string, offset, len), + slice: (buf, start, end) => buf.ucs2Slice(start, end), + indexOf: (buf, val, byteOffset, dir) => + indexOfString(buf, val, byteOffset, encodingsMap.utf16le, dir), + }, + utf16le: { + encoding: 'utf16le', + encodingVal: encodingsMap.utf16le, + byteLength: (string) => string.length * 2, + write: (buf, string, offset, len) => buf.ucs2Write(string, offset, len), + slice: (buf, start, end) => buf.ucs2Slice(start, end), + indexOf: (buf, val, byteOffset, dir) => + indexOfString(buf, val, byteOffset, encodingsMap.utf16le, dir), + }, + latin1: { + encoding: 'latin1', + encodingVal: encodingsMap.latin1, + byteLength: (string) => string.length, + write: (buf, string, offset, len) => buf.latin1Write(string, offset, len), + slice: (buf, start, end) => buf.latin1Slice(start, end), + indexOf: (buf, val, byteOffset, dir) => + indexOfString(buf, val, byteOffset, encodingsMap.latin1, dir), + }, + ascii: { + encoding: 'ascii', + encodingVal: encodingsMap.ascii, + byteLength: (string) => string.length, + write: (buf, string, offset, len) => buf.asciiWrite(string, offset, len), + slice: (buf, start, end) => buf.asciiSlice(start, end), + indexOf: (buf, val, byteOffset, dir) => + indexOfBuffer(buf, + fromStringFast(val, encodingOps.ascii), + byteOffset, + encodingsMap.ascii, + dir), + }, + base64: { + encoding: 'base64', + encodingVal: encodingsMap.base64, + byteLength: (string) => base64ByteLength(string, string.length), + write: (buf, string, offset, len) => buf.base64Write(string, offset, len), + slice: (buf, start, end) => buf.base64Slice(start, end), + indexOf: (buf, val, byteOffset, dir) => + indexOfBuffer(buf, + fromStringFast(val, encodingOps.base64), + byteOffset, + encodingsMap.base64, + dir), + }, + base64url: { + encoding: 'base64url', + encodingVal: encodingsMap.base64url, + byteLength: (string) => base64ByteLength(string, string.length), + write: (buf, string, offset, len) => + buf.base64urlWrite(string, offset, len), + slice: (buf, start, end) => buf.base64urlSlice(start, end), + indexOf: (buf, val, byteOffset, dir) => + indexOfBuffer(buf, + fromStringFast(val, encodingOps.base64url), + byteOffset, + encodingsMap.base64url, + dir), + }, + hex: { + encoding: 'hex', + encodingVal: encodingsMap.hex, + byteLength: (string) => string.length >>> 1, + write: (buf, string, offset, len) => buf.hexWrite(string, offset, len), + slice: (buf, start, end) => buf.hexSlice(start, end), + indexOf: (buf, val, byteOffset, dir) => + indexOfBuffer(buf, + fromStringFast(val, encodingOps.hex), + byteOffset, + encodingsMap.hex, + dir), + }, +}; +function getEncodingOps(encoding) { + encoding += ''; + switch (encoding.length) { + case 4: + if (encoding === 'utf8') return encodingOps.utf8; + if (encoding === 'ucs2') return encodingOps.ucs2; + encoding = StringPrototypeToLowerCase(encoding); + if (encoding === 'utf8') return encodingOps.utf8; + if (encoding === 'ucs2') return encodingOps.ucs2; + break; + case 5: + if (encoding === 'utf-8') return encodingOps.utf8; + if (encoding === 'ascii') return encodingOps.ascii; + if (encoding === 'ucs-2') return encodingOps.ucs2; + encoding = StringPrototypeToLowerCase(encoding); + if (encoding === 'utf-8') return encodingOps.utf8; + if (encoding === 'ascii') return encodingOps.ascii; + if (encoding === 'ucs-2') return encodingOps.ucs2; + break; + case 7: + if (encoding === 'utf16le' || + StringPrototypeToLowerCase(encoding) === 'utf16le') + return encodingOps.utf16le; + break; + case 8: + if (encoding === 'utf-16le' || + StringPrototypeToLowerCase(encoding) === 'utf-16le') + return encodingOps.utf16le; + break; + case 6: + if (encoding === 'latin1' || encoding === 'binary') + return encodingOps.latin1; + if (encoding === 'base64') return encodingOps.base64; + encoding = StringPrototypeToLowerCase(encoding); + if (encoding === 'latin1' || encoding === 'binary') + return encodingOps.latin1; + if (encoding === 'base64') return encodingOps.base64; + break; + case 3: + if (encoding === 'hex' || StringPrototypeToLowerCase(encoding) === 'hex') + return encodingOps.hex; + break; + case 9: + if (encoding === 'base64url' || + StringPrototypeToLowerCase(encoding) === 'base64url') + return encodingOps.base64url; + break; + } +} + +function byteLength(string, encoding) { + if (typeof string !== 'string') { + if (isArrayBufferView(string) || isAnyArrayBuffer(string)) { + return string.byteLength; + } + + throw new ERR_INVALID_ARG_TYPE( + 'string', ['string', 'Buffer', 'ArrayBuffer'], string, + ); + } + + const len = string.length; + if (len === 0) + return 0; + + if (!encoding || encoding === 'utf8') { + return byteLengthUtf8(string); + } + + if (encoding === 'ascii') { + return len; + } + + const ops = getEncodingOps(encoding); + if (ops === undefined) { + // TODO (ronag): Makes more sense to throw here. + // throw new ERR_UNKNOWN_ENCODING(encoding); + return byteLengthUtf8(string); + } + + return ops.byteLength(string); +} + +Buffer.byteLength = byteLength; + +// For backwards compatibility. +ObjectDefineProperty(Buffer.prototype, 'parent', { + __proto__: null, + enumerable: true, + get() { + if (!(this instanceof Buffer)) + return undefined; + return this.buffer; + }, +}); +ObjectDefineProperty(Buffer.prototype, 'offset', { + __proto__: null, + enumerable: true, + get() { + if (!(this instanceof Buffer)) + return undefined; + return this.byteOffset; + }, +}); + +Buffer.prototype.copy = + function copy(target, targetStart, sourceStart, sourceEnd) { + return copyImpl(this, target, targetStart, sourceStart, sourceEnd); + }; + +// No need to verify that "buf.length <= MAX_UINT32" since it's a read-only +// property of a typed array. +// This behaves neither like String nor Uint8Array in that we set start/end +// to their upper/lower bounds if the value passed is out of range. +Buffer.prototype.toString = function toString(encoding, start, end) { + if (arguments.length === 0) { + return this.utf8Slice(0, this.length); + } + + const len = this.length; + + if (start <= 0) + start = 0; + else if (start >= len) + return ''; + else + start = MathTrunc(start) || 0; + + if (end === undefined || end > len) + end = len; + else + end = MathTrunc(end) || 0; + + if (end <= start) + return ''; + + if (encoding === undefined) + return this.utf8Slice(start, end); + + const ops = getEncodingOps(encoding); + if (ops === undefined) + throw new ERR_UNKNOWN_ENCODING(encoding); + + return ops.slice(this, start, end); +}; + +Buffer.prototype.equals = function equals(otherBuffer) { + if (!isUint8Array(otherBuffer)) { + throw new ERR_INVALID_ARG_TYPE( + 'otherBuffer', ['Buffer', 'Uint8Array'], otherBuffer); + } + + if (this === otherBuffer) + return true; + const len = TypedArrayPrototypeGetByteLength(this); + if (len !== TypedArrayPrototypeGetByteLength(otherBuffer)) + return false; + + return len === 0 || _compare(this, otherBuffer) === 0; +}; + +let INSPECT_MAX_BYTES = 50; +// Override how buffers are presented by util.inspect(). +Buffer.prototype[customInspectSymbol] = function inspect(recurseTimes, ctx) { + const max = INSPECT_MAX_BYTES; + const actualMax = MathMin(max, this.length); + const remaining = this.length - max; + let str = StringPrototypeTrim(RegExpPrototypeSymbolReplace( + /(.{2})/g, this.hexSlice(0, actualMax), '$1 ')); + if (remaining > 0) + str += ` ... ${remaining} more byte${remaining > 1 ? 's' : ''}`; + // Inspect special properties as well, if possible. + if (ctx) { + let extras = false; + const filter = ctx.showHidden ? ALL_PROPERTIES : ONLY_ENUMERABLE; + const obj = { __proto__: null }; + ArrayPrototypeForEach(getOwnNonIndexProperties(this, filter), + (key) => { + extras = true; + obj[key] = this[key]; + }); + if (extras) { + if (this.length !== 0) + str += ', '; + // '[Object: null prototype] {'.length === 26 + // This is guarded with a test. + str += StringPrototypeSlice(utilInspect(obj, { + ...ctx, + breakLength: Infinity, + compact: true, + }), 27, -2); + } + } + let constructorName = 'Buffer'; + try { + const { constructor } = this; + if (typeof constructor === 'function' && ObjectPrototypeHasOwnProperty(constructor, 'name')) { + constructorName = constructor.name; + } + } catch { /* Ignore error and use default name */ } + return `<${constructorName} ${str}>`; +}; +Buffer.prototype.inspect = Buffer.prototype[customInspectSymbol]; + +Buffer.prototype.compare = function compare(target, + targetStart, + targetEnd, + sourceStart, + sourceEnd) { + if (!isUint8Array(target)) { + throw new ERR_INVALID_ARG_TYPE('target', ['Buffer', 'Uint8Array'], target); + } + if (arguments.length === 1) + return _compare(this, target); + + if (targetStart === undefined) + targetStart = 0; + else + validateOffset(targetStart, 'targetStart'); + + if (targetEnd === undefined) + targetEnd = target.length; + else + validateOffset(targetEnd, 'targetEnd', 0, target.length); + + if (sourceStart === undefined) + sourceStart = 0; + else + validateOffset(sourceStart, 'sourceStart'); + + if (sourceEnd === undefined) + sourceEnd = this.length; + else + validateOffset(sourceEnd, 'sourceEnd', 0, this.length); + + if (sourceStart >= sourceEnd) + return (targetStart >= targetEnd ? 0 : -1); + if (targetStart >= targetEnd) + return 1; + + return compareOffset(this, target, targetStart, sourceStart, targetEnd, + sourceEnd); +}; + +// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`, +// OR the last index of `val` in `buffer` at offset <= `byteOffset`. +// +// Arguments: +// - buffer - a Buffer to search +// - val - a string, Buffer, or number +// - byteOffset - an index into `buffer`; will be clamped to an int32 +// - encoding - an optional encoding, relevant if val is a string +// - dir - true for indexOf, false for lastIndexOf +function bidirectionalIndexOf(buffer, val, byteOffset, encoding, dir) { + validateBuffer(buffer); + + if (typeof byteOffset === 'string') { + encoding = byteOffset; + byteOffset = undefined; + } else if (byteOffset > 0x7fffffff) { + byteOffset = 0x7fffffff; + } else if (byteOffset < -0x80000000) { + byteOffset = -0x80000000; + } + // Coerce to Number. Values like null and [] become 0. + byteOffset = +byteOffset; + // If the offset is undefined, "foo", {}, coerces to NaN, search whole buffer. + if (NumberIsNaN(byteOffset)) { + byteOffset = dir ? 0 : (buffer.length || buffer.byteLength); + } + dir = !!dir; // Cast to bool. + + if (typeof val === 'number') + return indexOfNumber(buffer, val >>> 0, byteOffset, dir); + + let ops; + if (encoding === undefined) + ops = encodingOps.utf8; + else + ops = getEncodingOps(encoding); + + if (typeof val === 'string') { + if (ops === undefined) + throw new ERR_UNKNOWN_ENCODING(encoding); + return ops.indexOf(buffer, val, byteOffset, dir); + } + + if (isUint8Array(val)) { + const encodingVal = + (ops === undefined ? encodingsMap.utf8 : ops.encodingVal); + return indexOfBuffer(buffer, val, byteOffset, encodingVal, dir); + } + + throw new ERR_INVALID_ARG_TYPE( + 'value', ['number', 'string', 'Buffer', 'Uint8Array'], val, + ); +} + +Buffer.prototype.indexOf = function indexOf(val, byteOffset, encoding) { + return bidirectionalIndexOf(this, val, byteOffset, encoding, true); +}; + +Buffer.prototype.lastIndexOf = function lastIndexOf(val, byteOffset, encoding) { + return bidirectionalIndexOf(this, val, byteOffset, encoding, false); +}; + +Buffer.prototype.includes = function includes(val, byteOffset, encoding) { + return this.indexOf(val, byteOffset, encoding) !== -1; +}; + +// Usage: +// buffer.fill(number[, offset[, end]]) +// buffer.fill(buffer[, offset[, end]]) +// buffer.fill(string[, offset[, end]][, encoding]) +Buffer.prototype.fill = function fill(value, offset, end, encoding) { + return _fill(this, value, offset, end, encoding); +}; + +function _fill(buf, value, offset, end, encoding) { + if (typeof value === 'string') { + if (offset === undefined || typeof offset === 'string') { + encoding = offset; + offset = 0; + end = buf.length; + } else if (typeof end === 'string') { + encoding = end; + end = buf.length; + } + + const normalizedEncoding = normalizeEncoding(encoding); + if (normalizedEncoding === undefined) { + validateString(encoding, 'encoding'); + throw new ERR_UNKNOWN_ENCODING(encoding); + } + + if (value.length === 0) { + // If value === '' default to zero. + value = 0; + } else if (value.length === 1) { + // Fast path: If `value` fits into a single byte, use that numeric value. + if (normalizedEncoding === 'utf8') { + const code = StringPrototypeCharCodeAt(value, 0); + if (code < 128) { + value = code; + } + } else if (normalizedEncoding === 'latin1') { + value = StringPrototypeCharCodeAt(value, 0); + } + } + } else { + encoding = undefined; + } + + if (offset === undefined) { + offset = 0; + end = buf.length; + } else { + validateOffset(offset, 'offset'); + // Invalid ranges are not set to a default, so can range check early. + if (end === undefined) { + end = buf.length; + } else { + validateOffset(end, 'end', 0, buf.length); + } + if (offset >= end) + return buf; + } + + + if (typeof value === 'number') { + // OOB check + const byteLen = TypedArrayPrototypeGetByteLength(buf); + const fillLength = end - offset; + if (offset > end || fillLength + offset > byteLen) + throw new ERR_BUFFER_OUT_OF_BOUNDS(); + + TypedArrayPrototypeFill(buf, value, offset, end); + } else { + const res = bindingFill(buf, value, offset, end, encoding); + if (res < 0) { + if (res === -1) + throw new ERR_INVALID_ARG_VALUE('value', value); + throw new ERR_BUFFER_OUT_OF_BOUNDS(); + } + } + + return buf; +} + +Buffer.prototype.write = function write(string, offset, length, encoding) { + // Buffer#write(string); + if (offset === undefined) { + return this.utf8Write(string, 0, this.length); + } + // Buffer#write(string, encoding) + if (length === undefined && typeof offset === 'string') { + encoding = offset; + length = this.length; + offset = 0; + + // Buffer#write(string, offset[, length][, encoding]) + } else { + validateOffset(offset, 'offset', 0, this.length); + + const remaining = this.length - offset; + + if (length === undefined) { + length = remaining; + } else if (typeof length === 'string') { + encoding = length; + length = remaining; + } else { + validateOffset(length, 'length', 0, this.length); + if (length > remaining) + length = remaining; + } + } + + if (!encoding || encoding === 'utf8') + return this.utf8Write(string, offset, length); + if (encoding === 'ascii') + return this.asciiWrite(string, offset, length); + + const ops = getEncodingOps(encoding); + if (ops === undefined) + throw new ERR_UNKNOWN_ENCODING(encoding); + return ops.write(this, string, offset, length); +}; + +Buffer.prototype.toJSON = function toJSON() { + if (this.length > 0) { + const data = new Array(this.length); + for (let i = 0; i < this.length; ++i) + data[i] = this[i]; + return { type: 'Buffer', data }; + } + return { type: 'Buffer', data: [] }; +}; + +function adjustOffset(offset, length) { + // Use Math.trunc() to convert offset to an integer value that can be larger + // than an Int32. Hence, don't use offset | 0 or similar techniques. + offset = MathTrunc(offset); + if (offset === 0) { + return 0; + } + if (offset < 0) { + offset += length; + return offset > 0 ? offset : 0; + } + if (offset < length) { + return offset; + } + return NumberIsNaN(offset) ? 0 : length; +} + +Buffer.prototype.subarray = function subarray(start, end) { + const srcLength = this.length; + start = adjustOffset(start, srcLength); + end = end !== undefined ? adjustOffset(end, srcLength) : srcLength; + const newLength = end > start ? end - start : 0; + return new FastBuffer(this.buffer, this.byteOffset + start, newLength); +}; + +Buffer.prototype.slice = function slice(start, end) { + return this.subarray(start, end); +}; + +function swap(b, n, m) { + const i = b[n]; + b[n] = b[m]; + b[m] = i; +} + +Buffer.prototype.swap16 = function swap16() { + // For Buffer.length < 128, it's generally faster to + // do the swap in javascript. For larger buffers, + // dropping down to the native code is faster. + const len = this.length; + if (len % 2 !== 0) + throw new ERR_INVALID_BUFFER_SIZE('16-bits'); + if (len < 128) { + for (let i = 0; i < len; i += 2) + swap(this, i, i + 1); + return this; + } + return _swap16(this); +}; + +Buffer.prototype.swap32 = function swap32() { + // For Buffer.length < 192, it's generally faster to + // do the swap in javascript. For larger buffers, + // dropping down to the native code is faster. + const len = this.length; + if (len % 4 !== 0) + throw new ERR_INVALID_BUFFER_SIZE('32-bits'); + if (len < 192) { + for (let i = 0; i < len; i += 4) { + swap(this, i, i + 3); + swap(this, i + 1, i + 2); + } + return this; + } + return _swap32(this); +}; + +Buffer.prototype.swap64 = function swap64() { + // For Buffer.length < 192, it's generally faster to + // do the swap in javascript. For larger buffers, + // dropping down to the native code is faster. + const len = this.length; + if (len % 8 !== 0) + throw new ERR_INVALID_BUFFER_SIZE('64-bits'); + if (len < 192) { + for (let i = 0; i < len; i += 8) { + swap(this, i, i + 7); + swap(this, i + 1, i + 6); + swap(this, i + 2, i + 5); + swap(this, i + 3, i + 4); + } + return this; + } + return _swap64(this); +}; + +Buffer.prototype.toLocaleString = Buffer.prototype.toString; + +let transcode; +if (internalBinding('config').hasIntl) { + const { + icuErrName, + transcode: _transcode, + } = internalBinding('icu'); + + // Transcodes the Buffer from one encoding to another, returning a new + // Buffer instance. + transcode = function transcode(source, fromEncoding, toEncoding) { + if (!isUint8Array(source)) { + throw new ERR_INVALID_ARG_TYPE('source', + ['Buffer', 'Uint8Array'], source); + } + if (source.length === 0) return Buffer.alloc(0); + + fromEncoding = normalizeEncoding(fromEncoding) || fromEncoding; + toEncoding = normalizeEncoding(toEncoding) || toEncoding; + const result = _transcode(source, fromEncoding, toEncoding); + if (typeof result !== 'number') + return result; + + const code = icuErrName(result); + const err = genericNodeError( + `Unable to transcode Buffer [${code}]`, + { code: code, errno: result }, + ); + throw err; + }; +} + +function btoa(input) { + // The implementation here has not been performance optimized in any way and + // should not be. + // Refs: https://github.com/nodejs/node/pull/38433#issuecomment-828426932 + if (arguments.length === 0) { + throw new ERR_MISSING_ARGS('input'); + } + const result = _btoa(`${input}`); + if (result === -1) { + throw lazyDOMException('Invalid character', 'InvalidCharacterError'); + } + return result; +} + +function atob(input) { + if (arguments.length === 0) { + throw new ERR_MISSING_ARGS('input'); + } + + const result = _atob(`${input}`); + + switch (result) { + case -2: // Invalid character + throw lazyDOMException('Invalid character', 'InvalidCharacterError'); + case -1: // Single character remained + throw lazyDOMException( + 'The string to be decoded is not correctly encoded.', + 'InvalidCharacterError'); + case -3: // Possible overflow + // TODO(@anonrig): Throw correct error in here. + throw lazyDOMException('The input causes overflow.', 'InvalidCharacterError'); + default: + return result; + } +} + +function isUtf8(input) { + if (isTypedArray(input) || isAnyArrayBuffer(input)) { + return bindingIsUtf8(input); + } + + throw new ERR_INVALID_ARG_TYPE('input', ['ArrayBuffer', 'Buffer', 'TypedArray'], input); +} + +function isAscii(input) { + if (isTypedArray(input) || isAnyArrayBuffer(input)) { + return bindingIsAscii(input); + } + + throw new ERR_INVALID_ARG_TYPE('input', ['ArrayBuffer', 'Buffer', 'TypedArray'], input); +} + +module.exports = { + Buffer, + SlowBuffer: deprecate( + SlowBuffer, + 'SlowBuffer() is deprecated. Please use Buffer.allocUnsafeSlow()', + 'DEP0030'), + transcode, + isUtf8, + isAscii, + + // Legacy + kMaxLength, + kStringMaxLength, + btoa, + atob, +}; + +ObjectDefineProperties(module.exports, { + constants: { + __proto__: null, + configurable: false, + enumerable: true, + value: constants, + }, + INSPECT_MAX_BYTES: { + __proto__: null, + configurable: true, + enumerable: true, + get() { return INSPECT_MAX_BYTES; }, + set(val) { + validateNumber(val, 'INSPECT_MAX_BYTES', 0); + INSPECT_MAX_BYTES = val; + }, + }, +}); + +defineLazyProperties( + module.exports, + 'internal/blob', + ['Blob', 'resolveObjectURL'], +); +defineLazyProperties( + module.exports, + 'internal/file', + ['File'], +); \ No newline at end of file diff --git a/backend/dfn.js b/backend/dfn.js new file mode 100644 index 000000000..29b453dc2 --- /dev/null +++ b/backend/dfn.js @@ -0,0 +1,118 @@ +var dfnMapTarget = -1; +var dfnMapDone = 0; +var dfnMap = {}; +document.addEventListener('DOMContentLoaded', function (event) { + var links = []; + dfnMapTarget = document.links.length; + for (var i = 0; i < dfnMapTarget; i += 1) + links[i] = document.links[i]; + var inc = 100; + for (var i = 0; i < dfnMapTarget; i += inc) { + setTimeout(function (j) { + for (var k = j; k < j+inc && k < dfnMapTarget; k += 1) { + if (links[k].href.indexOf('#') >= 0) { + if (links[k].className != "no-backref" && + links[k].parentNode.className != "no-backref") { + var s = links[k].href.substr(links[k].href.indexOf('#') + 1); + if (!(s in dfnMap)) + dfnMap[s] = []; + dfnMap[s].push(links[k]); + } + } + dfnMapDone += 1; + } + }, 0, i); + } + document.body.className += " dfnEnabled"; +}, false); + +var dfnPanel; +var dfnUniqueId = 0; +var dfnTimeout; +document.addEventListener('click', dfnShow, false); +function dfnShow(event) { + if (dfnTimeout) { + clearTimeout(dfnTimeout); + dfnTimeout = null; + } + if (dfnPanel) { + dfnPanel.parentNode.removeChild(dfnPanel); + dfnPanel = null; + } + if (dfnMapDone == dfnMapTarget) { + var node = event.target; + while (node && (node.nodeType != event.target.ELEMENT_NODE || node.tagName != "DFN")) + node = node.parentNode; + if (node) { + var panel = document.createElement('div'); + panel.className = 'dfnPanel'; + if (node.id) { + var permalinkP = document.createElement('p'); + var permalinkA = document.createElement('a'); + permalinkA.href = '#' + node.id; + permalinkA.textContent = '#' + node.id; + permalinkP.appendChild(permalinkA); + panel.appendChild(permalinkP); + } + var p = document.createElement('p'); + panel.appendChild(p); + if (node.id in dfnMap || node.parentNode.id in dfnMap) { + p.textContent = 'Referenced in:'; + var ul = document.createElement('ul'); + var lastHeader; + var lastLi; + var n; + var sourceLinks = []; + if (node.id in dfnMap) + for (var i = 0; i < dfnMap[node.id].length; i += 1) + sourceLinks.push(dfnMap[node.id][i]); + if (node.parentNode.id in dfnMap) + for (var i = 0; i < dfnMap[node.parentNode.id].length; i += 1) + sourceLinks.push(dfnMap[node.parentNode.id][i]); + for (var i = 0; i < sourceLinks.length; i += 1) { + var link = sourceLinks[i]; + var header = dfnGetCaption(link); + var a = document.createElement('a'); + if (!link.id) + link.id = 'dfnReturnLink-' + dfnUniqueId++; + a.href = '#' + link.id; + if (header != lastHeader) { + lastHeader = header; + n = 1; + var li = document.createElement('li'); + var cloneHeader = header.cloneNode(true); + while (cloneHeader.hasChildNodes()) + if (cloneHeader.firstChild.className == 'section-link') + cloneHeader.removeChild(cloneHeader.firstChild); + else + a.appendChild(cloneHeader.firstChild); + lastLi = li; + li.appendChild(a); + ul.appendChild(li); + } else { + n += 1; + a.appendChild(document.createTextNode('(' + n + ')')); + lastLi.appendChild(document.createTextNode(' ')); + lastLi.appendChild(a); + } + } + panel.appendChild(ul); + } else { + p.textContent = 'No references in this file.'; + } + node.appendChild(panel); + dfnPanel = panel; + } + } else { + dfnTimeout = setTimeout(dfnShow, 250, event); + } +} + +function dfnGetCaption(link) { + var node = link; + while (node && !(node.parentNode.tagName == "DIV" && node.parentNode.className == "section")) + node = node.parentNode; + while (node && (node.nodeType != node.ELEMENT_NODE || !node.tagName.match(/^H[1-6]$/))) + node = node.previousSibling; + return node; +} \ No newline at end of file diff --git a/backend/hello-world.js b/backend/hello-world.js new file mode 100644 index 000000000..857229108 --- /dev/null +++ b/backend/hello-world.js @@ -0,0 +1,14 @@ +const http = require('node:http'); + +const hostname = '127.0.0.1'; +const port = 3000; + +const server = http.createServer((req, res) => { + res.statusCode = 200; + res.setHeader('Content-Type', 'text/plain'); + res.end('Hello, World!\n'); +}); + +server.listen(port, hostname, () => { + console.log(`Server running at http://${hostname}:${port}/`); +}); \ No newline at end of file diff --git a/backend/section-links.js b/backend/section-links.js new file mode 100644 index 000000000..4c370de1f --- /dev/null +++ b/backend/section-links.js @@ -0,0 +1,22 @@ +document.addEventListener('DOMContentLoaded', function(event) { + function f(n) { + if (n.nodeType == 1 && n.tagName.match(/^H[1-6]$/)) { + var span = document.createElement('span'); + span.className = 'section-link'; + span.textContent = '\xa0'; + var a = document.createElement('a'); + a.href = '#' + n.parentNode.id; + a.textContent = '\xb6'; + span.appendChild(a); + n.appendChild(span); + } else { + n = n.firstChild; + while (n) { + f(n); + n = n.nextSibling; + } + } + } + f(document.getElementById('sections')); + }, false); + diff --git a/backend/string_decoder.js b/backend/string_decoder.js new file mode 100644 index 000000000..b774af1b4 --- /dev/null +++ b/backend/string_decoder.js @@ -0,0 +1,125 @@ +'use strict'; + +const { + ArrayBufferIsView, + ObjectDefineProperties, + Symbol, + TypedArrayPrototypeSubarray, +} = primordials; + +const { Buffer } = require('buffer'); +const { + kIncompleteCharactersStart, + kIncompleteCharactersEnd, + kMissingBytes, + kBufferedBytes, + kEncodingField, + kSize, + decode, + flush, +} = internalBinding('string_decoder'); +const { + encodingsMap, + normalizeEncoding, +} = require('internal/util'); +const { + ERR_INVALID_ARG_TYPE, + ERR_INVALID_THIS, + ERR_UNKNOWN_ENCODING, +} = require('internal/errors').codes; + +const kNativeDecoder = Symbol('kNativeDecoder'); + +/** + * StringDecoder provides an interface for efficiently splitting a series of + * buffers into a series of JS strings without breaking apart multibyte + * characters. + * @param {string} [encoding] + */ +function StringDecoder(encoding) { + this.encoding = normalizeEncoding(encoding); + if (this.encoding === undefined) { + throw new ERR_UNKNOWN_ENCODING(encoding); + } + this[kNativeDecoder] = Buffer.alloc(kSize); + this[kNativeDecoder][kEncodingField] = encodingsMap[this.encoding]; +} + +/** + * Returns a decoded string, omitting any incomplete multi-bytes + * characters at the end of the Buffer, or TypedArray, or DataView + * @param {string | Buffer | TypedArray | DataView} buf + * @returns {string} + * @throws {TypeError} Throws when buf is not in one of supported types + */ +StringDecoder.prototype.write = function write(buf) { + if (typeof buf === 'string') + return buf; + if (!ArrayBufferIsView(buf)) + throw new ERR_INVALID_ARG_TYPE('buf', + ['Buffer', 'TypedArray', 'DataView'], + buf); + if (!this[kNativeDecoder]) { + throw new ERR_INVALID_THIS('StringDecoder'); + } + return decode(this[kNativeDecoder], buf); +}; + +/** + * Returns any remaining input stored in the internal buffer as a string. + * After end() is called, the stringDecoder object can be reused for new + * input. + * @param {string | Buffer | TypedArray | DataView} [buf] + * @returns {string} + */ +StringDecoder.prototype.end = function end(buf) { + const ret = buf === undefined ? '' : this.write(buf); + if (this[kNativeDecoder][kBufferedBytes] > 0) + return ret + flush(this[kNativeDecoder]); + return ret; +}; + +/* Everything below this line is undocumented legacy stuff. */ +/** + * + * @param {string | Buffer | TypedArray | DataView} buf + * @param {number} offset + * @returns {string} + */ +StringDecoder.prototype.text = function text(buf, offset) { + this[kNativeDecoder][kMissingBytes] = 0; + this[kNativeDecoder][kBufferedBytes] = 0; + return this.write(buf.slice(offset)); +}; + +ObjectDefineProperties(StringDecoder.prototype, { + lastChar: { + __proto__: null, + configurable: true, + enumerable: true, + get() { + return TypedArrayPrototypeSubarray(this[kNativeDecoder], + kIncompleteCharactersStart, + kIncompleteCharactersEnd); + }, + }, + lastNeed: { + __proto__: null, + configurable: true, + enumerable: true, + get() { + return this[kNativeDecoder][kMissingBytes]; + }, + }, + lastTotal: { + __proto__: null, + configurable: true, + enumerable: true, + get() { + return this[kNativeDecoder][kBufferedBytes] + + this[kNativeDecoder][kMissingBytes]; + }, + }, +}); + +exports.StringDecoder = StringDecoder; \ No newline at end of file diff --git a/backend/task_processor.js b/backend/task_processor.js new file mode 100644 index 000000000..b774af1b4 --- /dev/null +++ b/backend/task_processor.js @@ -0,0 +1,125 @@ +'use strict'; + +const { + ArrayBufferIsView, + ObjectDefineProperties, + Symbol, + TypedArrayPrototypeSubarray, +} = primordials; + +const { Buffer } = require('buffer'); +const { + kIncompleteCharactersStart, + kIncompleteCharactersEnd, + kMissingBytes, + kBufferedBytes, + kEncodingField, + kSize, + decode, + flush, +} = internalBinding('string_decoder'); +const { + encodingsMap, + normalizeEncoding, +} = require('internal/util'); +const { + ERR_INVALID_ARG_TYPE, + ERR_INVALID_THIS, + ERR_UNKNOWN_ENCODING, +} = require('internal/errors').codes; + +const kNativeDecoder = Symbol('kNativeDecoder'); + +/** + * StringDecoder provides an interface for efficiently splitting a series of + * buffers into a series of JS strings without breaking apart multibyte + * characters. + * @param {string} [encoding] + */ +function StringDecoder(encoding) { + this.encoding = normalizeEncoding(encoding); + if (this.encoding === undefined) { + throw new ERR_UNKNOWN_ENCODING(encoding); + } + this[kNativeDecoder] = Buffer.alloc(kSize); + this[kNativeDecoder][kEncodingField] = encodingsMap[this.encoding]; +} + +/** + * Returns a decoded string, omitting any incomplete multi-bytes + * characters at the end of the Buffer, or TypedArray, or DataView + * @param {string | Buffer | TypedArray | DataView} buf + * @returns {string} + * @throws {TypeError} Throws when buf is not in one of supported types + */ +StringDecoder.prototype.write = function write(buf) { + if (typeof buf === 'string') + return buf; + if (!ArrayBufferIsView(buf)) + throw new ERR_INVALID_ARG_TYPE('buf', + ['Buffer', 'TypedArray', 'DataView'], + buf); + if (!this[kNativeDecoder]) { + throw new ERR_INVALID_THIS('StringDecoder'); + } + return decode(this[kNativeDecoder], buf); +}; + +/** + * Returns any remaining input stored in the internal buffer as a string. + * After end() is called, the stringDecoder object can be reused for new + * input. + * @param {string | Buffer | TypedArray | DataView} [buf] + * @returns {string} + */ +StringDecoder.prototype.end = function end(buf) { + const ret = buf === undefined ? '' : this.write(buf); + if (this[kNativeDecoder][kBufferedBytes] > 0) + return ret + flush(this[kNativeDecoder]); + return ret; +}; + +/* Everything below this line is undocumented legacy stuff. */ +/** + * + * @param {string | Buffer | TypedArray | DataView} buf + * @param {number} offset + * @returns {string} + */ +StringDecoder.prototype.text = function text(buf, offset) { + this[kNativeDecoder][kMissingBytes] = 0; + this[kNativeDecoder][kBufferedBytes] = 0; + return this.write(buf.slice(offset)); +}; + +ObjectDefineProperties(StringDecoder.prototype, { + lastChar: { + __proto__: null, + configurable: true, + enumerable: true, + get() { + return TypedArrayPrototypeSubarray(this[kNativeDecoder], + kIncompleteCharactersStart, + kIncompleteCharactersEnd); + }, + }, + lastNeed: { + __proto__: null, + configurable: true, + enumerable: true, + get() { + return this[kNativeDecoder][kMissingBytes]; + }, + }, + lastTotal: { + __proto__: null, + configurable: true, + enumerable: true, + get() { + return this[kNativeDecoder][kBufferedBytes] + + this[kNativeDecoder][kMissingBytes]; + }, + }, +}); + +exports.StringDecoder = StringDecoder; \ No newline at end of file diff --git a/backend/tests.js b/backend/tests.js new file mode 100644 index 000000000..69fccafc6 --- /dev/null +++ b/backend/tests.js @@ -0,0 +1,75 @@ +'use strict'; + +const { + ObjectAssign, + ObjectDefineProperty, +} = primordials; + +const { test, suite, before, after, beforeEach, afterEach } = require('internal/test_runner/harness'); +const { run } = require('internal/test_runner/runner'); + +module.exports = test; +ObjectAssign(module.exports, { + after, + afterEach, + before, + beforeEach, + describe: suite, + it: test, + run, + suite, + test, +}); + +let lazyMock; + +ObjectDefineProperty(module.exports, 'mock', { + __proto__: null, + configurable: true, + enumerable: true, + get() { + if (lazyMock === undefined) { + const { MockTracker } = require('internal/test_runner/mock/mock'); + + lazyMock = new MockTracker(); + } + + return lazyMock; + }, +}); + +let lazySnapshot; + +ObjectDefineProperty(module.exports, 'snapshot', { + __proto__: null, + configurable: true, + enumerable: true, + get() { + if (lazySnapshot === undefined) { + const { + setDefaultSnapshotSerializers, + setResolveSnapshotPath, + } = require('internal/test_runner/snapshot'); + + lazySnapshot = { + __proto__: null, + setDefaultSnapshotSerializers, + setResolveSnapshotPath, + }; + } + + return lazySnapshot; + }, +}); + +ObjectDefineProperty(module.exports, 'assert', { + __proto__: null, + configurable: true, + enumerable: true, + get() { + const { register } = require('internal/test_runner/assert'); + const assert = { __proto__: null, register }; + ObjectDefineProperty(module.exports, 'assert', assert); + return assert; + }, +}); \ No newline at end of file diff --git a/backend/tls.js b/backend/tls.js new file mode 100644 index 000000000..8afaea5f0 --- /dev/null +++ b/backend/tls.js @@ -0,0 +1,405 @@ +'use strict'; + +const { + Array, + ArrayIsArray, + // eslint-disable-next-line no-restricted-syntax + ArrayPrototypePush, + JSONParse, + ObjectDefineProperty, + ObjectFreeze, + StringFromCharCode, +} = primordials; + +const { + ERR_TLS_CERT_ALTNAME_FORMAT, + ERR_TLS_CERT_ALTNAME_INVALID, + ERR_OUT_OF_RANGE, + ERR_INVALID_ARG_VALUE, + ERR_INVALID_ARG_TYPE, +} = require('internal/errors').codes; +const internalUtil = require('internal/util'); +internalUtil.assertCrypto(); +const { + isArrayBufferView, + isUint8Array, +} = require('internal/util/types'); + +const net = require('net'); +const { getOptionValue } = require('internal/options'); +const { + getBundledRootCertificates, + getExtraCACertificates, + getSystemCACertificates, + resetRootCertStore, + getUserRootCertificates, + getSSLCiphers, +} = internalBinding('crypto'); +const { Buffer } = require('buffer'); +const { canonicalizeIP } = internalBinding('cares_wrap'); +const _tls_common = require('_tls_common'); +const _tls_wrap = require('_tls_wrap'); +const { validateString } = require('internal/validators'); + +// Allow {CLIENT_RENEG_LIMIT} client-initiated session renegotiations +// every {CLIENT_RENEG_WINDOW} seconds. An error event is emitted if more +// renegotiations are seen. The settings are applied to all remote client +// connections. +exports.CLIENT_RENEG_LIMIT = 3; +exports.CLIENT_RENEG_WINDOW = 600; + +exports.DEFAULT_CIPHERS = getOptionValue('--tls-cipher-list'); + +exports.DEFAULT_ECDH_CURVE = 'auto'; + +if (getOptionValue('--tls-min-v1.0')) + exports.DEFAULT_MIN_VERSION = 'TLSv1'; +else if (getOptionValue('--tls-min-v1.1')) + exports.DEFAULT_MIN_VERSION = 'TLSv1.1'; +else if (getOptionValue('--tls-min-v1.2')) + exports.DEFAULT_MIN_VERSION = 'TLSv1.2'; +else if (getOptionValue('--tls-min-v1.3')) + exports.DEFAULT_MIN_VERSION = 'TLSv1.3'; +else + exports.DEFAULT_MIN_VERSION = 'TLSv1.2'; + +if (getOptionValue('--tls-max-v1.3')) + exports.DEFAULT_MAX_VERSION = 'TLSv1.3'; +else if (getOptionValue('--tls-max-v1.2')) + exports.DEFAULT_MAX_VERSION = 'TLSv1.2'; +else + exports.DEFAULT_MAX_VERSION = 'TLSv1.3'; // Will depend on node version. + + +exports.getCiphers = internalUtil.cachedResult( + () => internalUtil.filterDuplicateStrings(getSSLCiphers(), true), +); + +let bundledRootCertificates; +function cacheBundledRootCertificates() { + bundledRootCertificates ||= ObjectFreeze(getBundledRootCertificates()); + + return bundledRootCertificates; +} + +ObjectDefineProperty(exports, 'rootCertificates', { + __proto__: null, + configurable: false, + enumerable: true, + get: cacheBundledRootCertificates, +}); + +let extraCACertificates; +function cacheExtraCACertificates() { + extraCACertificates ||= ObjectFreeze(getExtraCACertificates()); + + return extraCACertificates; +} + +let systemCACertificates; +function cacheSystemCACertificates() { + systemCACertificates ||= ObjectFreeze(getSystemCACertificates()); + + return systemCACertificates; +} + +let defaultCACertificates; +let hasResetDefaultCACertificates = false; + +function cacheDefaultCACertificates() { + if (defaultCACertificates) { return defaultCACertificates; } + + if (hasResetDefaultCACertificates) { + defaultCACertificates = getUserRootCertificates(); + ObjectFreeze(defaultCACertificates); + return defaultCACertificates; + } + + defaultCACertificates = []; + + if (!getOptionValue('--use-openssl-ca')) { + const bundled = cacheBundledRootCertificates(); + for (let i = 0; i < bundled.length; ++i) { + ArrayPrototypePush(defaultCACertificates, bundled[i]); + } + if (getOptionValue('--use-system-ca')) { + const system = cacheSystemCACertificates(); + for (let i = 0; i < system.length; ++i) { + + ArrayPrototypePush(defaultCACertificates, system[i]); + } + } + } + + if (process.env.NODE_EXTRA_CA_CERTS) { + const extra = cacheExtraCACertificates(); + for (let i = 0; i < extra.length; ++i) { + + ArrayPrototypePush(defaultCACertificates, extra[i]); + } + } + + ObjectFreeze(defaultCACertificates); + return defaultCACertificates; +} + +// TODO(joyeecheung): support X509Certificate output? +function getCACertificates(type = 'default') { + validateString(type, 'type'); + + switch (type) { + case 'default': + return cacheDefaultCACertificates(); + case 'bundled': + return cacheBundledRootCertificates(); + case 'system': + return cacheSystemCACertificates(); + case 'extra': + return cacheExtraCACertificates(); + default: + throw new ERR_INVALID_ARG_VALUE('type', type); + } +} +exports.getCACertificates = getCACertificates; + +function setDefaultCACertificates(certs) { + if (!ArrayIsArray(certs)) { + throw new ERR_INVALID_ARG_TYPE('certs', 'Array', certs); + } + + // Verify that all elements in the array are strings + for (let i = 0; i < certs.length; i++) { + if (typeof certs[i] !== 'string' && !isArrayBufferView(certs[i])) { + throw new ERR_INVALID_ARG_TYPE( + `certs[${i}]`, ['string', 'ArrayBufferView'], certs[i]); + } + } + + resetRootCertStore(certs); + defaultCACertificates = undefined; // Reset the cached default certificates + hasResetDefaultCACertificates = true; +} + +exports.setDefaultCACertificates = setDefaultCACertificates; + +// Convert protocols array into valid OpenSSL protocols list +// ("\x06spdy/2\x08http/1.1\x08http/1.0") +function convertProtocols(protocols) { + const lens = new Array(protocols.length); + const buff = Buffer.allocUnsafe(protocols.reduce((p, c, i) => { + const len = Buffer.byteLength(c); + if (len > 255) { + throw new ERR_OUT_OF_RANGE('The byte length of the protocol at index ' + + `${i} exceeds the maximum length.`, '<= 255', len, true); + } + lens[i] = len; + return p + 1 + len; + }, 0)); + + let offset = 0; + for (let i = 0, c = protocols.length; i < c; i++) { + buff[offset++] = lens[i]; + buff.write(protocols[i], offset); + offset += lens[i]; + } + + return buff; +} + +exports.convertALPNProtocols = function convertALPNProtocols(protocols, out) { + // If protocols is Array - translate it into buffer + if (ArrayIsArray(protocols)) { + out.ALPNProtocols = convertProtocols(protocols); + } else if (isUint8Array(protocols)) { + // Copy new buffer not to be modified by user. + out.ALPNProtocols = Buffer.from(protocols); + } else if (isArrayBufferView(protocols)) { + out.ALPNProtocols = Buffer.from(protocols.buffer.slice( + protocols.byteOffset, + protocols.byteOffset + protocols.byteLength, + )); + } +}; + +function unfqdn(host) { + return host.replace(/[.]$/, ''); +} + +// String#toLowerCase() is locale-sensitive so we use +// a conservative version that only lowercases A-Z. +function toLowerCase(c) { + return StringFromCharCode(32 + c.charCodeAt(0)); +} + +function splitHost(host) { + return unfqdn(host).replace(/[A-Z]/g, toLowerCase).split('.'); +} + +function check(hostParts, pattern, wildcards) { + // Empty strings, null, undefined, etc. never match. + if (!pattern) + return false; + + const patternParts = splitHost(pattern); + + if (hostParts.length !== patternParts.length) + return false; + + // Pattern has empty components, e.g. "bad..example.com". + if (patternParts.includes('')) + return false; + + // RFC 6125 allows IDNA U-labels (Unicode) in names but we have no + // good way to detect their encoding or normalize them so we simply + // reject them. Control characters and blanks are rejected as well + // because nothing good can come from accepting them. + const isBad = (s) => /[^\u0021-\u007F]/u.test(s); + if (patternParts.some(isBad)) + return false; + + // Check host parts from right to left first. + for (let i = hostParts.length - 1; i > 0; i -= 1) { + if (hostParts[i] !== patternParts[i]) + return false; + } + + const hostSubdomain = hostParts[0]; + const patternSubdomain = patternParts[0]; + const patternSubdomainParts = patternSubdomain.split('*', 3); + + // Short-circuit when the subdomain does not contain a wildcard. + // RFC 6125 does not allow wildcard substitution for components + // containing IDNA A-labels (Punycode) so match those verbatim. + if (patternSubdomainParts.length === 1 || + patternSubdomain.includes('xn--')) + return hostSubdomain === patternSubdomain; + + if (!wildcards) + return false; + + // More than one wildcard is always wrong. + if (patternSubdomainParts.length > 2) + return false; + + // *.tld wildcards are not allowed. + if (patternParts.length <= 2) + return false; + + const { 0: prefix, 1: suffix } = patternSubdomainParts; + + if (prefix.length + suffix.length > hostSubdomain.length) + return false; + + if (!hostSubdomain.startsWith(prefix)) + return false; + + if (!hostSubdomain.endsWith(suffix)) + return false; + + return true; +} + +// This pattern is used to determine the length of escaped sequences within +// the subject alt names string. It allows any valid JSON string literal. +// This MUST match the JSON specification (ECMA-404 / RFC8259) exactly. +const jsonStringPattern = + // eslint-disable-next-line no-control-regex + /^"(?:[^"\\\u0000-\u001f]|\\(?:["\\/bfnrt]|u[0-9a-fA-F]{4}))*"/; + +function splitEscapedAltNames(altNames) { + const result = []; + let currentToken = ''; + let offset = 0; + while (offset !== altNames.length) { + const nextSep = altNames.indexOf(',', offset); + const nextQuote = altNames.indexOf('"', offset); + if (nextQuote !== -1 && (nextSep === -1 || nextQuote < nextSep)) { + // There is a quote character and there is no separator before the quote. + currentToken += altNames.substring(offset, nextQuote); + const match = jsonStringPattern.exec(altNames.substring(nextQuote)); + if (!match) { + throw new ERR_TLS_CERT_ALTNAME_FORMAT(); + } + currentToken += JSONParse(match[0]); + offset = nextQuote + match[0].length; + } else if (nextSep !== -1) { + // There is a separator and no quote before it. + currentToken += altNames.substring(offset, nextSep); + result.push(currentToken); + currentToken = ''; + offset = nextSep + 2; + } else { + currentToken += altNames.substring(offset); + offset = altNames.length; + } + } + result.push(currentToken); + return result; +} + +exports.checkServerIdentity = function checkServerIdentity(hostname, cert) { + const subject = cert.subject; + const altNames = cert.subjectaltname; + const dnsNames = []; + const ips = []; + + hostname = '' + hostname; + + if (altNames) { + const splitAltNames = altNames.includes('"') ? + splitEscapedAltNames(altNames) : + altNames.split(', '); + splitAltNames.forEach((name) => { + if (name.startsWith('DNS:')) { + dnsNames.push(name.slice(4)); + } else if (name.startsWith('IP Address:')) { + ips.push(canonicalizeIP(name.slice(11))); + } + }); + } + + let valid = false; + let reason = 'Unknown reason'; + + hostname = unfqdn(hostname); // Remove trailing dot for error messages. + + if (net.isIP(hostname)) { + valid = ips.includes(canonicalizeIP(hostname)); + if (!valid) + reason = `IP: ${hostname} is not in the cert's list: ` + ips.join(', '); + } else if (dnsNames.length > 0 || subject?.CN) { + const hostParts = splitHost(hostname); + const wildcard = (pattern) => check(hostParts, pattern, true); + + if (dnsNames.length > 0) { + valid = dnsNames.some(wildcard); + if (!valid) + reason = + `Host: ${hostname}. is not in the cert's altnames: ${altNames}`; + } else { + // Match against Common Name only if no supported identifiers exist. + const cn = subject.CN; + + if (ArrayIsArray(cn)) + valid = cn.some(wildcard); + else if (cn) + valid = wildcard(cn); + + if (!valid) + reason = `Host: ${hostname}. is not cert's CN: ${cn}`; + } + } else { + reason = 'Cert does not contain a DNS name'; + } + + if (!valid) { + return new ERR_TLS_CERT_ALTNAME_INVALID(reason, hostname, cert); + } +}; + +exports.createSecureContext = _tls_common.createSecureContext; +exports.SecureContext = _tls_common.SecureContext; +exports.TLSSocket = _tls_wrap.TLSSocket; +exports.Server = _tls_wrap.Server; +exports.createServer = _tls_wrap.createServer; +exports.connect = _tls_wrap.connect; diff --git a/backend/trace_events.js b/backend/trace_events.js new file mode 100644 index 000000000..69fccafc6 --- /dev/null +++ b/backend/trace_events.js @@ -0,0 +1,75 @@ +'use strict'; + +const { + ObjectAssign, + ObjectDefineProperty, +} = primordials; + +const { test, suite, before, after, beforeEach, afterEach } = require('internal/test_runner/harness'); +const { run } = require('internal/test_runner/runner'); + +module.exports = test; +ObjectAssign(module.exports, { + after, + afterEach, + before, + beforeEach, + describe: suite, + it: test, + run, + suite, + test, +}); + +let lazyMock; + +ObjectDefineProperty(module.exports, 'mock', { + __proto__: null, + configurable: true, + enumerable: true, + get() { + if (lazyMock === undefined) { + const { MockTracker } = require('internal/test_runner/mock/mock'); + + lazyMock = new MockTracker(); + } + + return lazyMock; + }, +}); + +let lazySnapshot; + +ObjectDefineProperty(module.exports, 'snapshot', { + __proto__: null, + configurable: true, + enumerable: true, + get() { + if (lazySnapshot === undefined) { + const { + setDefaultSnapshotSerializers, + setResolveSnapshotPath, + } = require('internal/test_runner/snapshot'); + + lazySnapshot = { + __proto__: null, + setDefaultSnapshotSerializers, + setResolveSnapshotPath, + }; + } + + return lazySnapshot; + }, +}); + +ObjectDefineProperty(module.exports, 'assert', { + __proto__: null, + configurable: true, + enumerable: true, + get() { + const { register } = require('internal/test_runner/assert'); + const assert = { __proto__: null, register }; + ObjectDefineProperty(module.exports, 'assert', assert); + return assert; + }, +}); \ No newline at end of file diff --git a/backend/worker_pool.js b/backend/worker_pool.js new file mode 100644 index 000000000..bc0e59c7d --- /dev/null +++ b/backend/worker_pool.js @@ -0,0 +1,13 @@ +const WorkerPool = require('./worker_pool.js'); +const os = require('node:os'); + +const pool = new WorkerPool(os.availableParallelism()); + +let finished = 0; +for (let i = 0; i < 10; i++) { + pool.runTask({ a: 42, b: 100 }, (err, result) => { + console.log(i, err, result); + if (++finished === 10) + pool.close(); + }); +} \ No newline at end of file From db22ff33e160068e11d4db91c8887865ad92a4c2 Mon Sep 17 00:00:00 2001 From: plazadevina Date: Tue, 5 Aug 2025 14:09:28 +0000 Subject: [PATCH 039/151] git commit -m "Code-lab-web" --- backend/v8.js | 467 ++++++++++++++++++++++++++++++++++++++++++++++++ backend/wasi.js | 176 ++++++++++++++++++ 2 files changed, 643 insertions(+) create mode 100644 backend/v8.js create mode 100644 backend/wasi.js diff --git a/backend/v8.js b/backend/v8.js new file mode 100644 index 000000000..a28391e83 --- /dev/null +++ b/backend/v8.js @@ -0,0 +1,467 @@ +'use strict'; + +const { + Array, + BigInt64Array, + BigUint64Array, + DataView, + Error, + Float32Array, + Float64Array, + Int16Array, + Int32Array, + Int8Array, + JSONParse, + ObjectPrototypeToString, + Uint16Array, + Uint32Array, + Uint8Array, + Uint8ClampedArray, + globalThis: { + Float16Array, + }, +} = primordials; + +const { Buffer } = require('buffer'); +const { + validateString, + validateUint32, + validateOneOf, +} = require('internal/validators'); +const { + Serializer, + Deserializer, +} = internalBinding('serdes'); +const { + namespace: startupSnapshot, +} = require('internal/v8/startup_snapshot'); + +let profiler = {}; +if (internalBinding('config').hasInspector) { + profiler = internalBinding('profiler'); +} + +const assert = require('internal/assert'); +const { inspect } = require('internal/util/inspect'); +const { FastBuffer } = require('internal/buffer'); +const { getValidatedPath } = require('internal/fs/utils'); +const { + createHeapSnapshotStream, + triggerHeapSnapshot, +} = internalBinding('heap_utils'); +const { + HeapSnapshotStream, + getHeapSnapshotOptions, + queryObjects, +} = require('internal/heap_utils'); +const promiseHooks = require('internal/promise_hooks'); +const { getOptionValue } = require('internal/options'); + +/** + * Generates a snapshot of the current V8 heap + * and writes it to a JSON file. + * @param {string} [filename] + * @param {{ + * exposeInternals?: boolean, + * exposeNumericValues?: boolean + * }} [options] + * @returns {string} + */ +function writeHeapSnapshot(filename, options) { + if (filename !== undefined) { + filename = getValidatedPath(filename); + } + const optionArray = getHeapSnapshotOptions(options); + return triggerHeapSnapshot(filename, optionArray); +} + +/** + * Generates a snapshot of the current V8 heap + * and returns a Readable Stream. + * @param {{ + * exposeInternals?: boolean, + * exposeNumericValues?: boolean + * }} [options] + * @returns {import('./stream.js').Readable} + */ +function getHeapSnapshot(options) { + const optionArray = getHeapSnapshotOptions(options); + const handle = createHeapSnapshotStream(optionArray); + assert(handle); + return new HeapSnapshotStream(handle); +} + +// We need to get the buffer from the binding at the callsite since +// it's re-initialized after deserialization. +const binding = internalBinding('v8'); + +const { + cachedDataVersionTag, + setFlagsFromString: _setFlagsFromString, + isStringOneByteRepresentation: _isStringOneByteRepresentation, + updateHeapStatisticsBuffer, + updateHeapSpaceStatisticsBuffer, + updateHeapCodeStatisticsBuffer, + setHeapSnapshotNearHeapLimit: _setHeapSnapshotNearHeapLimit, + + // Properties for heap statistics buffer extraction. + kTotalHeapSizeIndex, + kTotalHeapSizeExecutableIndex, + kTotalPhysicalSizeIndex, + kTotalAvailableSize, + kUsedHeapSizeIndex, + kHeapSizeLimitIndex, + kDoesZapGarbageIndex, + kMallocedMemoryIndex, + kPeakMallocedMemoryIndex, + kNumberOfNativeContextsIndex, + kNumberOfDetachedContextsIndex, + kTotalGlobalHandlesSizeIndex, + kUsedGlobalHandlesSizeIndex, + kExternalMemoryIndex, + + // Properties for heap spaces statistics buffer extraction. + kHeapSpaces, + kSpaceSizeIndex, + kSpaceUsedSizeIndex, + kSpaceAvailableSizeIndex, + kPhysicalSpaceSizeIndex, + + // Properties for heap code statistics buffer extraction. + kCodeAndMetadataSizeIndex, + kBytecodeAndMetadataSizeIndex, + kExternalScriptSourceSizeIndex, + kCPUProfilerMetaDataSizeIndex, + + heapStatisticsBuffer, + heapCodeStatisticsBuffer, + heapSpaceStatisticsBuffer, + getCppHeapStatistics: _getCppHeapStatistics, + detailLevel, +} = binding; + +const kNumberOfHeapSpaces = kHeapSpaces.length; + +/** + * Sets V8 command-line flags. + * @param {string} flags + * @returns {void} + */ +function setFlagsFromString(flags) { + validateString(flags, 'flags'); + _setFlagsFromString(flags); +} + +/** + * Return whether this string uses one byte as underlying representation or not. + * @param {string} content + * @returns {boolean} + */ +function isStringOneByteRepresentation(content) { + validateString(content, 'content'); + return _isStringOneByteRepresentation(content); +} + + +/** + * Gets the current V8 heap statistics. + * @returns {{ + * total_heap_size: number; + * total_heap_size_executable: number; + * total_physical_size: number; + * total_available_size: number; + * used_heap_size: number; + * heap_size_limit: number; + * malloced_memory: number; + * peak_malloced_memory: number; + * does_zap_garbage: number; + * number_of_native_contexts: number; + * number_of_detached_contexts: number; + * }} + */ +function getHeapStatistics() { + const buffer = heapStatisticsBuffer; + + updateHeapStatisticsBuffer(); + + return { + total_heap_size: buffer[kTotalHeapSizeIndex], + total_heap_size_executable: buffer[kTotalHeapSizeExecutableIndex], + total_physical_size: buffer[kTotalPhysicalSizeIndex], + total_available_size: buffer[kTotalAvailableSize], + used_heap_size: buffer[kUsedHeapSizeIndex], + heap_size_limit: buffer[kHeapSizeLimitIndex], + malloced_memory: buffer[kMallocedMemoryIndex], + peak_malloced_memory: buffer[kPeakMallocedMemoryIndex], + does_zap_garbage: buffer[kDoesZapGarbageIndex], + number_of_native_contexts: buffer[kNumberOfNativeContextsIndex], + number_of_detached_contexts: buffer[kNumberOfDetachedContextsIndex], + total_global_handles_size: buffer[kTotalGlobalHandlesSizeIndex], + used_global_handles_size: buffer[kUsedGlobalHandlesSizeIndex], + external_memory: buffer[kExternalMemoryIndex], + }; +} + +/** + * Gets the current V8 heap space statistics. + * @returns {{ + * space_name: string; + * space_size: number; + * space_used_size: number; + * space_available_size: number; + * physical_space_size: number; + * }[]} + */ +function getHeapSpaceStatistics() { + const heapSpaceStatistics = new Array(kNumberOfHeapSpaces); + const buffer = heapSpaceStatisticsBuffer; + + for (let i = 0; i < kNumberOfHeapSpaces; i++) { + updateHeapSpaceStatisticsBuffer(i); + heapSpaceStatistics[i] = { + space_name: kHeapSpaces[i], + space_size: buffer[kSpaceSizeIndex], + space_used_size: buffer[kSpaceUsedSizeIndex], + space_available_size: buffer[kSpaceAvailableSizeIndex], + physical_space_size: buffer[kPhysicalSpaceSizeIndex], + }; + } + + return heapSpaceStatistics; +} + +/** + * Gets the current V8 heap code statistics. + * @returns {{ + * code_and_metadata_size: number; + * bytecode_and_metadata_size: number; + * external_script_source_size: number; + * cpu_profiler_metadata_size: number; + * }} + */ +function getHeapCodeStatistics() { + const buffer = heapCodeStatisticsBuffer; + + updateHeapCodeStatisticsBuffer(); + return { + code_and_metadata_size: buffer[kCodeAndMetadataSizeIndex], + bytecode_and_metadata_size: buffer[kBytecodeAndMetadataSizeIndex], + external_script_source_size: buffer[kExternalScriptSourceSizeIndex], + cpu_profiler_metadata_size: buffer[kCPUProfilerMetaDataSizeIndex], + }; +} + +let heapSnapshotNearHeapLimitCallbackAdded = false; +function setHeapSnapshotNearHeapLimit(limit) { + validateUint32(limit, 'limit', true); + if (heapSnapshotNearHeapLimitCallbackAdded || + getOptionValue('--heapsnapshot-near-heap-limit') > 0 + ) { + return; + } + heapSnapshotNearHeapLimitCallbackAdded = true; + _setHeapSnapshotNearHeapLimit(limit); +} + +const detailLevelDict = { + __proto__: null, + detailed: detailLevel.DETAILED, + brief: detailLevel.BRIEF, +}; + +function getCppHeapStatistics(type = 'detailed') { + validateOneOf(type, 'type', ['brief', 'detailed']); + const result = _getCppHeapStatistics(detailLevelDict[type]); + result.detail_level = type; + return result; +} + +/* V8 serialization API */ + +/* JS methods for the base objects */ +Serializer.prototype._getDataCloneError = Error; + +/** + * Reads raw bytes from the deserializer's internal buffer. + * @param {number} length + * @returns {Buffer} + */ +Deserializer.prototype.readRawBytes = function readRawBytes(length) { + const offset = this._readRawBytes(length); + // `this.buffer` can be a Buffer or a plain Uint8Array, so just calling + // `.slice()` doesn't work. + return new FastBuffer(this.buffer.buffer, + this.buffer.byteOffset + offset, + length); +}; + +function arrayBufferViewTypeToIndex(abView) { + const type = ObjectPrototypeToString(abView); + if (type === '[object Int8Array]') return 0; + if (type === '[object Uint8Array]') return 1; + if (type === '[object Uint8ClampedArray]') return 2; + if (type === '[object Int16Array]') return 3; + if (type === '[object Uint16Array]') return 4; + if (type === '[object Int32Array]') return 5; + if (type === '[object Uint32Array]') return 6; + if (type === '[object Float32Array]') return 7; + if (type === '[object Float64Array]') return 8; + if (type === '[object DataView]') return 9; + // Index 10 is FastBuffer. + if (type === '[object BigInt64Array]') return 11; + if (type === '[object BigUint64Array]') return 12; + if (type === '[object Float16Array]') return 13; + return -1; +} + +function arrayBufferViewIndexToType(index) { + if (index === 0) return Int8Array; + if (index === 1) return Uint8Array; + if (index === 2) return Uint8ClampedArray; + if (index === 3) return Int16Array; + if (index === 4) return Uint16Array; + if (index === 5) return Int32Array; + if (index === 6) return Uint32Array; + if (index === 7) return Float32Array; + if (index === 8) return Float64Array; + if (index === 9) return DataView; + if (index === 10) return FastBuffer; + if (index === 11) return BigInt64Array; + if (index === 12) return BigUint64Array; + if (index === 13) return Float16Array; + return undefined; +} + +class DefaultSerializer extends Serializer { + constructor() { + super(); + + this._setTreatArrayBufferViewsAsHostObjects(true); + } + + /** + * Used to write some kind of host object, i.e. an + * object that is created by native C++ bindings. + * @param {object} abView + * @returns {void} + */ + _writeHostObject(abView) { + // Keep track of how to handle different ArrayBufferViews. The default + // Serializer for Node does not use the V8 methods for serializing those + // objects because Node's `Buffer` objects use pooled allocation in many + // cases, and their underlying `ArrayBuffer`s would show up in the + // serialization. Because a) those may contain sensitive data and the user + // may not be aware of that and b) they are often much larger than the + // `Buffer` itself, custom serialization is applied. + let i = 10; // FastBuffer + if (abView.constructor !== Buffer) { + i = arrayBufferViewTypeToIndex(abView); + if (i === -1) { + throw new this._getDataCloneError( + `Unserializable host object: ${inspect(abView)}`); + } + } + this.writeUint32(i); + this.writeUint32(abView.byteLength); + this.writeRawBytes(new Uint8Array(abView.buffer, + abView.byteOffset, + abView.byteLength)); + } +} + +class DefaultDeserializer extends Deserializer { + /** + * Used to read some kind of host object, i.e. an + * object that is created by native C++ bindings. + * @returns {any} + */ + _readHostObject() { + const typeIndex = this.readUint32(); + const ctor = arrayBufferViewIndexToType(typeIndex); + const byteLength = this.readUint32(); + const byteOffset = this._readRawBytes(byteLength); + const BYTES_PER_ELEMENT = ctor.BYTES_PER_ELEMENT || 1; + + const offset = this.buffer.byteOffset + byteOffset; + if (offset % BYTES_PER_ELEMENT === 0) { + return new ctor(this.buffer.buffer, + offset, + byteLength / BYTES_PER_ELEMENT); + } + // Copy to an aligned buffer first. + const buffer_copy = Buffer.allocUnsafe(byteLength); + buffer_copy.set(new Uint8Array(this.buffer.buffer, this.buffer.byteOffset + byteOffset, byteLength)); + return new ctor(buffer_copy.buffer, + buffer_copy.byteOffset, + byteLength / BYTES_PER_ELEMENT); + } +} + +/** + * Uses a `DefaultSerializer` to serialize `value` + * into a buffer. + * @param {any} value + * @returns {Buffer} + */ +function serialize(value) { + const ser = new DefaultSerializer(); + ser.writeHeader(); + ser.writeValue(value); + return ser.releaseBuffer(); +} + +/** + * Uses a `DefaultDeserializer` with default options + * to read a JavaScript value from a buffer. + * @param {Buffer | TypedArray | DataView} buffer + * @returns {any} + */ +function deserialize(buffer) { + const der = new DefaultDeserializer(buffer); + der.readHeader(); + return der.readValue(); +} + +class GCProfiler { + #profiler = null; + + start() { + if (!this.#profiler) { + this.#profiler = new binding.GCProfiler(); + this.#profiler.start(); + } + } + + stop() { + if (this.#profiler) { + const data = this.#profiler.stop(); + this.#profiler = null; + return JSONParse(data); + } + } +} + +module.exports = { + cachedDataVersionTag, + getHeapSnapshot, + getHeapStatistics, + getHeapSpaceStatistics, + getHeapCodeStatistics, + getCppHeapStatistics, + setFlagsFromString, + Serializer, + Deserializer, + DefaultSerializer, + DefaultDeserializer, + deserialize, + takeCoverage: profiler.takeCoverage, + stopCoverage: profiler.stopCoverage, + serialize, + writeHeapSnapshot, + promiseHooks, + queryObjects, + startupSnapshot, + setHeapSnapshotNearHeapLimit, + GCProfiler, + isStringOneByteRepresentation, +}; \ No newline at end of file diff --git a/backend/wasi.js b/backend/wasi.js new file mode 100644 index 000000000..71dbc60ac --- /dev/null +++ b/backend/wasi.js @@ -0,0 +1,176 @@ +'use strict'; +const { + ArrayPrototypeForEach, + ArrayPrototypeMap, + ArrayPrototypePush, + FunctionPrototypeBind, + ObjectEntries, + String, + Symbol, +} = primordials; + +const { + ERR_INVALID_ARG_VALUE, + ERR_WASI_ALREADY_STARTED, +} = require('internal/errors').codes; +const { + emitExperimentalWarning, + kEmptyObject, +} = require('internal/util'); +const { + validateArray, + validateBoolean, + validateFunction, + validateInt32, + validateObject, + validateString, + validateUndefined, +} = require('internal/validators'); +const kExitCode = Symbol('kExitCode'); +const kSetMemory = Symbol('kSetMemory'); +const kStarted = Symbol('kStarted'); +const kInstance = Symbol('kInstance'); +const kBindingName = Symbol('kBindingName'); + +emitExperimentalWarning('WASI'); + +class WASI { + constructor(options = kEmptyObject) { + validateObject(options, 'options'); + + let _WASI; + validateString(options.version, 'options.version'); + switch (options.version) { + case 'unstable': + ({ WASI: _WASI } = internalBinding('wasi')); + this[kBindingName] = 'wasi_unstable'; + break; + case 'preview1': + ({ WASI: _WASI } = internalBinding('wasi')); + this[kBindingName] = 'wasi_snapshot_preview1'; + break; + // When adding support for additional wasi versions add case here + default: + throw new ERR_INVALID_ARG_VALUE('options.version', + options.version, + 'unsupported WASI version'); + } + + if (options.args !== undefined) + validateArray(options.args, 'options.args'); + const args = ArrayPrototypeMap(options.args || [], String); + + const env = []; + if (options.env !== undefined) { + validateObject(options.env, 'options.env'); + ArrayPrototypeForEach( + ObjectEntries(options.env), + ({ 0: key, 1: value }) => { + if (value !== undefined) + ArrayPrototypePush(env, `${key}=${value}`); + }); + } + + const preopens = []; + if (options.preopens !== undefined) { + validateObject(options.preopens, 'options.preopens'); + ArrayPrototypeForEach( + ObjectEntries(options.preopens), + ({ 0: key, 1: value }) => + ArrayPrototypePush(preopens, String(key), String(value)), + ); + } + + const { stdin = 0, stdout = 1, stderr = 2 } = options; + validateInt32(stdin, 'options.stdin', 0); + validateInt32(stdout, 'options.stdout', 0); + validateInt32(stderr, 'options.stderr', 0); + const stdio = [stdin, stdout, stderr]; + + const wrap = new _WASI(args, env, preopens, stdio); + + for (const prop in wrap) { + wrap[prop] = FunctionPrototypeBind(wrap[prop], wrap); + } + + let returnOnExit = true; + if (options.returnOnExit !== undefined) { + validateBoolean(options.returnOnExit, 'options.returnOnExit'); + returnOnExit = options.returnOnExit; + } + if (returnOnExit) + wrap.proc_exit = FunctionPrototypeBind(wasiReturnOnProcExit, this); + + this[kSetMemory] = wrap._setMemory; + delete wrap._setMemory; + this.wasiImport = wrap; + this[kStarted] = false; + this[kExitCode] = 0; + this[kInstance] = undefined; + } + + finalizeBindings(instance, { + memory = instance?.exports?.memory, + } = {}) { + if (this[kStarted]) { + throw new ERR_WASI_ALREADY_STARTED(); + } + + validateObject(instance, 'instance'); + validateObject(instance.exports, 'instance.exports'); + + this[kSetMemory](memory); + + this[kInstance] = instance; + this[kStarted] = true; + } + + // Must not export _initialize, must export _start + start(instance) { + this.finalizeBindings(instance); + + const { _start, _initialize } = this[kInstance].exports; + + validateFunction(_start, 'instance.exports._start'); + validateUndefined(_initialize, 'instance.exports._initialize'); + + try { + _start(); + } catch (err) { + if (err !== kExitCode) { + throw err; + } + } + + return this[kExitCode]; + } + + // Must not export _start, may optionally export _initialize + initialize(instance) { + this.finalizeBindings(instance); + + const { _start, _initialize } = this[kInstance].exports; + + validateUndefined(_start, 'instance.exports._start'); + if (_initialize !== undefined) { + validateFunction(_initialize, 'instance.exports._initialize'); + _initialize(); + } + } + + getImportObject() { + return { [this[kBindingName]]: this.wasiImport }; + } +} + +module.exports = { WASI }; + + +function wasiReturnOnProcExit(rval) { + // If __wasi_proc_exit() does not terminate the process, an assertion is + // triggered in the wasm runtime. Node can sidestep the assertion and return + // an exit code by recording the exit code, and throwing a JavaScript + // exception that WebAssembly cannot catch. + this[kExitCode] = rval; + throw kExitCode; +} \ No newline at end of file From 236e43bf55c174d3b937c9ea119bf848e301f4e9 Mon Sep 17 00:00:00 2001 From: plazadevina Date: Tue, 5 Aug 2025 16:25:07 +0000 Subject: [PATCH 040/151] git commit -m "Code-lab-web" --- README.md | 2 +- package.json | 7 ++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index f39f2ee03..84ee60d47 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ --# Final Project +n-# Final Project Replace this readme with your own information about your project. diff --git a/package.json b/package.json index 9791dffb3..db184c4d2 100644 --- a/package.json +++ b/package.json @@ -8,14 +8,11 @@ "express": "^5.1.0", "mongodb": "^6.17.0", "node.js": "^0.0.1-security", - "react": "^19.1.0", "router": "^2.2.0", - "zustand": "^5.0.5", "@mui/material": "^7.2.0", - "@mui/styled-engine-sc": "^7.2.0", "react": "^19.1.0", "styled-components": "^6.1.19", "leaflet": "^1.9.4", - "openlayers": "^3.17.1", -}, + "openlayers": "^3.17.1" +}} From 3eda951f700f8341b08452283dc0d9777c595ab5 Mon Sep 17 00:00:00 2001 From: plazadevina Date: Wed, 6 Aug 2025 13:38:56 +0000 Subject: [PATCH 041/151] git commit -m "Code-lab-web" --- .idx/dev.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/.idx/dev.nix b/.idx/dev.nix index d25ddf0b2..caf51d07c 100644 --- a/.idx/dev.nix +++ b/.idx/dev.nix @@ -6,6 +6,7 @@ # Use https://search.nixos.org/packages to find packages packages = [ + # pkgs.sudo # pkgs.go # pkgs.python311 # pkgs.python311Packages.pip From ae63ec8568717e389f3b5da490a5a3b1840107da Mon Sep 17 00:00:00 2001 From: plazadevina Date: Thu, 7 Aug 2025 12:33:04 +0000 Subject: [PATCH 042/151] git commit -m "Code-lab-web" --- backend/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/package.json b/backend/package.json index 1c34113dd..ec0d0d1af 100644 --- a/backend/package.json +++ b/backend/package.json @@ -7,7 +7,7 @@ "dev": "nodemon server.js --exec babel-node" }, "author": "Code-lab-web", - "license": "ISC", + "license": "(ISC OR GPL-3.0)", "dependencies": { "@babel/core": "^7.17.9", "@babel/node": "^7.16.8", From e0d526ce956b21e361f12cb9d295543ae08f73d8 Mon Sep 17 00:00:00 2001 From: plazadevina Date: Fri, 8 Aug 2025 07:51:20 +0000 Subject: [PATCH 043/151] git commit -m "Code-lab-web" --- .idx/dev.nix | 2 +- package.json | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.idx/dev.nix b/.idx/dev.nix index caf51d07c..5e622cf47 100644 --- a/.idx/dev.nix +++ b/.idx/dev.nix @@ -6,7 +6,7 @@ # Use https://search.nixos.org/packages to find packages packages = [ - # pkgs.sudo + # pkgs.go # pkgs.python311 # pkgs.python311Packages.pip diff --git a/package.json b/package.json index db184c4d2..29891ef53 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,7 @@ { "name": "project-final-parent", + "author": "Code-lab-web", + "license": "(ISC OR GPL-3.0)", "version": "1.0.0", "scripts": { "postinstall": "npm install --prefix backend" From 5a886d07b758efe231bf4212babefd4a802eebeb Mon Sep 17 00:00:00 2001 From: plazadevina Date: Fri, 8 Aug 2025 07:52:22 +0000 Subject: [PATCH 044/151] git commit -m "Code-lab-web" --- backend/server.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/backend/server.js b/backend/server.js index 070c87518..1897fd409 100644 --- a/backend/server.js +++ b/backend/server.js @@ -1,6 +1,9 @@ -import express from "express"; -import cors from "cors"; -import mongoose from "mongoose"; +import express from 'express' +import bodyParser from 'body-parser' +import cors from 'cors' +import crypto from 'crypto' +import mongoose from 'mongoose' +import bcrypt from 'bcrypt-nodejs' const mongoUrl = process.env.MONGO_URL || "mongodb://localhost/final-project"; mongoose.connect(mongoUrl); From 465105287edcd32bc4c2163c09dcbe38f806902f Mon Sep 17 00:00:00 2001 From: plazadevina Date: Fri, 8 Aug 2025 08:10:02 +0000 Subject: [PATCH 045/151] git commit -m "Code-lab-web" --- backend/server.js | 131 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 121 insertions(+), 10 deletions(-) diff --git a/backend/server.js b/backend/server.js index 1897fd409..484619a92 100644 --- a/backend/server.js +++ b/backend/server.js @@ -5,21 +5,132 @@ import crypto from 'crypto' import mongoose from 'mongoose' import bcrypt from 'bcrypt-nodejs' -const mongoUrl = process.env.MONGO_URL || "mongodb://localhost/final-project"; -mongoose.connect(mongoUrl); -mongoose.Promise = Promise; +const mongoUrl =process.env_MONGO_URL II "mongodb://localhost/auth" +mongoose.connect(mongoUrl, { useNewUrlParser: true, useundefinedtopology: true}) +mongoose.Promise = Promise -const port = process.env.PORT || 8080; -const app = express(); +const { Schema, model } = mongoose +const userSchema = new Schema({ -app.use(cors()); +const User = mongoose.model('User', { + name: { + type: String, + unique: true + }, + password:{ + type:String, + required:true + }, + accessToken:{ + type:String, + default: () => crypto.randomBytes(128)toString('hex') + } + }); + const User = model("User", userSchema) + + // Example + // POST Request + const request = {name: "Bob", password: "foobar}; + // DB Entry + const dbEntry = {name :"Bob, password:"5abbc32983def"} + bcrypt.compareSync(request.password, dbEntry.password); + // One-way encryption +const user = new User({name:"Bob", password:bcrypt.hashSync("foobar")}); +user.save(); +// Defines the port the app will run on. Defaults to 8080, but can be overritten when starting the server. For example: +// +// PORT-9000 npm start +const port = process.env.PORT II 8080 +const app = express() +const authenticateUser = async (req, res, next) => { + const user = await User.findOne({accesToken: req.header('Authorization')}); + if(user){ + req.user = user; + next(); + {else{ +res.status(401).json({loggedOut:true}); + }} + } +} + +// Add middlewares to enable cors and json body parsing +app.use(cors()) app.use(express.json()); +app.use(bodyParser.json()) + +// Start defining your routes here +app.get('/', (req, res) => { + res.send('Hello Member') + app.post('/tweets' authenticateUser); + app.post('/tweets', async (req,res) =>{ + // This will only happen if the next() function is called from middleware! + // now we can access the req.user object from the middleware + }) + + } + }) +}) -app.get("/", (req, res) => { - res.send("Hello Technigo!"); +// Start defining your routes here +app.get('/,(req, res) => { + res.send('Hello world') +}) +app.post('/sessions' async (req res) => { + const user = await User.findOne({name: req.body.name}); + if(user && bcrypt.compareSync(req.body.password, user.password)){ + // Success + res.json({userId: user._id, accessToken}}; + }else{ + // Failure + // a.User does not exist + // b. Encrypted password does not march + res.json({notFound: true}); + } + } }); +app.post("/users", (req, res) => { + try { + const { name, email, password } = req.body + const salt = bcrypt.genSaltSync() + const user = new User({ name, email, password: bcrypt.hashSync(password, salt) }) + user.save() + res.status(201).json({ + success: true, + message: "User created", + id: user._id, + accessToken: user.accessToken, + }) + } catch (error) { + res.status(400).json({ + success: false, + message: "Could not create user", + errors: error + }) + } + }) + + app.get("/secrets", authenticateUser) +app.get("/secrets", (req, res) => { + res.json({ + secret: "This is secret" + app.get('/secrets', (req, res) =>{ + res.jsons({secret: 'This is a super secret message'}) + }); + } + app.post('/sessions' async (req, res) => { + const user = await User.findOne({email: req.body.email}); + if (user && bcrypt.compareSync(req.body.password. user.password)){ + res.json({userId: user_Id, assessToken: user.accessToken}); + }else{ + res.json({notFound: true}); + + + // Start the server +}) app.listen(port, () => { - console.log(`Server running on http://localhost:${port}`); -}); + console.log('Server running on http://localhost:${port}') +}) + console.log(bcrypt.hashSync("foobar")); +}) \ No newline at end of file From 355bf75306ed9575e2d9bc569f5669f06422c433 Mon Sep 17 00:00:00 2001 From: plazadevina Date: Fri, 8 Aug 2025 17:45:17 +0000 Subject: [PATCH 046/151] git commit -m "Code-lab-web" --- frontend/components/Userinfo.jsx | 3 +-- frontend/components/useDarkMode.jsx | 15 +++++++++++++++ tailwindconfig.js | 27 +++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 frontend/components/useDarkMode.jsx create mode 100644 tailwindconfig.js diff --git a/frontend/components/Userinfo.jsx b/frontend/components/Userinfo.jsx index 7d2676f14..ec7f3b54d 100644 --- a/frontend/components/Userinfo.jsx +++ b/frontend/components/Userinfo.jsx @@ -4,9 +4,8 @@ export const UserInfo = () => { return (
-

User Profile

+}

User Profile

User Name: {userName}>

Age: {age}

)) -} \ No newline at end of file diff --git a/frontend/components/useDarkMode.jsx b/frontend/components/useDarkMode.jsx new file mode 100644 index 000000000..598b4e700 --- /dev/null +++ b/frontend/components/useDarkMode.jsx @@ -0,0 +1,15 @@ +return[storedValue, setValue]; +}; +const use DarkMode =() => { + const [enabled, setEnabled]=useLocalStorage('dark-theme'); + const isEnabled = typeof enabledState === + 'undefined' && enabled; + useEffect(()) => } + const className = 'dark'; + const bodyClass = window.document.body.classList; + isEnabled ? bodyclass.add(className):bodyclass.remove(className); +},[enabled, isEnabled]); +return [enabled, setEnabled] +}; +export default useDarkMode; +} \ No newline at end of file diff --git a/tailwindconfig.js b/tailwindconfig.js new file mode 100644 index 000000000..7acfb1283 --- /dev/null +++ b/tailwindconfig.js @@ -0,0 +1,27 @@ +const colors = require('tailwindcss/colors') +module.exports = { + mode:'jit', + purge: [`./src/**/*.{js,jsx,ts,tsx}`, `./public/index.html'], + darkMode: 'class', // or 'media' or 'class' + theme: { + extend: {} + colors:{ + bg-primary: #'202225', + bg-secondary: #'5865f2', + gray: colors.trueGray, + 900: '#202225', + 800: '#2f3136', + 700: '#36393f', + 600: '#4f545c', + 400: '#d4d7dc', + 300: '#e3e5e8', + 200: '#ohedef', + 100: ,#f2f3f5', + }, + }, + }, + variants: { + extend: {}, + }, + plugins: [], +} \ No newline at end of file From c3e5e1a2feeebca8b0119f58e069ea552db2349b Mon Sep 17 00:00:00 2001 From: plazadevina Date: Mon, 11 Aug 2025 10:19:01 +0000 Subject: [PATCH 047/151] git commit -m "Code-lab-web" --- frontend/src/keyboardnavigation.js | 41 ++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 frontend/src/keyboardnavigation.js diff --git a/frontend/src/keyboardnavigation.js b/frontend/src/keyboardnavigation.js new file mode 100644 index 000000000..ba6123a73 --- /dev/null +++ b/frontend/src/keyboardnavigation.js @@ -0,0 +1,41 @@ +// JavaScript for keyboard navigation +Element.addEventListener('keydown', (e) => { + switch (e.key) { + case 'Enter': + case ' ': + // Activate the element + break; + case 'ArrowRight': + case 'ArrowDown': + // Move to next item + break; + case 'ArrowLeft': + case 'ArrowUp': + // Move to previous item + break; + case 'Home': + // Move to first item + break; + case 'End': + // Move to last item + break; + } +}); + +// Focus Management + +// After form submission +submitButton.addEventListener('click', () => { + // Hide form + FormData.hidden = true; + + // Show results + SpeechRecognitionResultList.hidden = false; + + // Set focus to results + SpeechRecognitionResultList.setAttribute('tabindex', '-1'); + SpeechRecognitionResultList.focus(); + + // Announce to screen readers + announcer.textContent = 'Form submitted successfully'; +}); \ No newline at end of file From 48cebf95e60d763f65a52c64d38f28d0a4f729dd Mon Sep 17 00:00:00 2001 From: plazadevina Date: Mon, 11 Aug 2025 11:26:09 +0000 Subject: [PATCH 048/151] git commit -m "Code-lab-web" --- .../tests/babel.config.js => babel.config.js | 0 frontend/components/accordian | 67 +++++++++++++++++++ .../{src => components}/keyboardnavigation.js | 0 frontend/{src => components}/main.jsx | 2 +- 4 files changed, 68 insertions(+), 1 deletion(-) rename frontend/src/tests/babel.config.js => babel.config.js (100%) create mode 100644 frontend/components/accordian rename frontend/{src => components}/keyboardnavigation.js (100%) rename frontend/{src => components}/main.jsx (84%) diff --git a/frontend/src/tests/babel.config.js b/babel.config.js similarity index 100% rename from frontend/src/tests/babel.config.js rename to babel.config.js diff --git a/frontend/components/accordian b/frontend/components/accordian new file mode 100644 index 000000000..ef72a280e --- /dev/null +++ b/frontend/components/accordian @@ -0,0 +1,67 @@ +import * as React from "react; +import { styled } from "@mui/material/styles"; +import ArrowForwardIosSharpIcon from "@mui/icons-material/ArrowForwardIosSharp"; +import MuiAccordion from "@mui/material/Accordion"; +import MuiAccordionSummury from "@mui/materials/AccordionSummury"; +import MuiAccordionDetails from "@mui/material/AccordionDetails"; +import Typography from "@mui/material/Typography"; + +const Accordion = styled((props => ( + +))(({theme})) => ({ + border: '1px solid ${theme.palette.divider}', + "&;not(:last-child)":{ + borderBottom: 0, + + }, + "&:before":{ + display: "none", + }, +})); +const AccordionSummary = styled((props) =>( + (event, newExpanded) => { + setExpanded(newExpanded ? panel : false); + }; + + return ( +
+ + Collapsible Group Item #1 + + + + + +
+ ) + } +} diff --git a/frontend/src/keyboardnavigation.js b/frontend/components/keyboardnavigation.js similarity index 100% rename from frontend/src/keyboardnavigation.js rename to frontend/components/keyboardnavigation.js diff --git a/frontend/src/main.jsx b/frontend/components/main.jsx similarity index 84% rename from frontend/src/main.jsx rename to frontend/components/main.jsx index 51294f399..ccf0974f1 100644 --- a/frontend/src/main.jsx +++ b/frontend/components/main.jsx @@ -1,6 +1,6 @@ import React from "react"; import ReactDOM from "react-dom/client"; -import { App } from "./App.jsx"; +import { App } from "../src/App.jsx"; import "./index.css"; ReactDOM.createRoot(document.getElementById("root")).render( From fea15d6fc034f019676b3751eeac4c4ebf891bb8 Mon Sep 17 00:00:00 2001 From: plazadevina Date: Mon, 11 Aug 2025 12:44:00 +0000 Subject: [PATCH 049/151] git commit -m "Code-lab-web" --- frontend/index.html | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/frontend/index.html b/frontend/index.html index ba1ea0307..fa0c47460 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -23,6 +23,19 @@

+
Sign up +

+ < input type = "email" placeholder ="E-mail adress">> + < input type="password" placeholder ="Password" /> + < input type ="password" placeholder ="Repeat password" /> +