diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..d81e62b --- /dev/null +++ b/.env.example @@ -0,0 +1,15 @@ +# Environment configuration for the research application + +# Port for the web server (optional, defaults to 3000) +PORT=3000 + +# External webhook URL for data collection (optional) +# If not set, data will only be stored locally in data/responses.json +# Example: WEBHOOK_URL=https://your-domain.com/webhook/endpoint +WEBHOOK_URL= + +# Docker/Traefik configuration (for production deployment) +YOUR_DOMAIN=your-domain.com +LETSENCRYPT_EMAIL=your-email@example.com +TRAEFIK_BASIC_AUTH_USER=admin +TRAEFIK_BASIC_AUTH_PASSWORD=your-hashed-password diff --git a/README.md b/README.md index 02fcd41..46f7759 100644 --- a/README.md +++ b/README.md @@ -44,12 +44,28 @@ This project is a simple web application designed to collect responses from user ``` npm install ``` -4. Start the server and bind it to all network interfaces (0.0.0.0): +4. Configure environment variables: + ```bash + cp .env.example .env + # Edit .env file to configure your webhook URL and other settings ``` - node server.js --host 0.0.0.0 +5. Start the server: ``` -5. Open your web browser and go to `http://localhost:3000` to access the application. + npm start + ``` +6. Open your web browser and go to `http://localhost:3000` to access the application. -## Contributing +## Configuration -Feel free to submit issues or pull requests for any improvements or bug fixes. \ No newline at end of file +The application can be configured using environment variables: + +- `PORT`: Port for the web server (default: 3000) +- `WEBHOOK_URL`: External webhook URL for data collection (optional) + - If not set, data will only be stored locally in `data/responses.json` + - If set, data will be sent to both the local file and the webhook +- Docker/Traefik variables for production deployment (see `.env.example`) + +## Data Collection + +- **Local Storage**: All responses are always saved to `data/responses.json` +- **External Webhook**: If `WEBHOOK_URL` is configured, responses are also sent to the external endpoint diff --git a/data/responses.json b/data/responses.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/data/responses.json @@ -0,0 +1 @@ +[] diff --git a/package-lock.json b/package-lock.json index a3b44ea..1ba04e3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,43 +1,58 @@ { "name": "simple-web-app", "version": "1.0.0", - "lockfileVersion": 1, + "lockfileVersion": 3, "requires": true, - "dependencies": { - "accepts": { + "packages": { + "": { + "name": "simple-web-app", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "axios": "^1.7.9", + "body-parser": "^1.19.0", + "express": "^4.17.1" + } + }, + "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "requires": { + "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" } }, - "array-flatten": { + "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, - "asynckit": { + "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" }, - "axios": { - "version": "1.7.9", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz", - "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==", - "requires": { + "node_modules/axios": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.11.0.tgz", + "integrity": "sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==", + "license": "MIT", + "dependencies": { "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", + "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, - "body-parser": { + "node_modules/body-parser": { "version": "1.20.3", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", - "requires": { + "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.5", "debug": "2.6.9", @@ -50,138 +65,211 @@ "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" } }, - "bytes": { + "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } }, - "call-bind-apply-helpers": { + "node_modules/call-bind-apply-helpers": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz", "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", - "requires": { + "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" } }, - "call-bound": { + "node_modules/call-bound": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz", "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", - "requires": { + "dependencies": { "call-bind-apply-helpers": "^1.0.1", "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "combined-stream": { + "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { + "license": "MIT", + "dependencies": { "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" } }, - "content-disposition": { + "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "requires": { + "dependencies": { "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" } }, - "content-type": { + "node_modules/content-type": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==" + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } }, - "cookie": { + "node_modules/cookie": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", - "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==" + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "engines": { + "node": ">= 0.6" + } }, - "cookie-signature": { + "node_modules/cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, - "debug": { + "node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { + "dependencies": { "ms": "2.0.0" } }, - "delayed-stream": { + "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } }, - "depd": { + "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } }, - "destroy": { + "node_modules/destroy": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } }, - "dunder-proto": { + "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "requires": { + "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" } }, - "ee-first": { + "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, - "encodeurl": { + "node_modules/encodeurl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==" + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "engines": { + "node": ">= 0.8" + } }, - "es-define-property": { + "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==" + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "engines": { + "node": ">= 0.4" + } }, - "es-errors": { + "node_modules/es-errors": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==" + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } }, - "es-object-atoms": { + "node_modules/es-object-atoms": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "requires": { + "dependencies": { "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" } }, - "escape-html": { + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, - "etag": { + "node_modules/etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } }, - "express": { + "node_modules/express": { "version": "4.21.2", "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", - "requires": { + "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", "body-parser": "1.20.3", @@ -213,13 +301,20 @@ "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "finalhandler": { + "node_modules/finalhandler": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", - "requires": { + "dependencies": { "debug": "2.6.9", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", @@ -227,43 +322,75 @@ "parseurl": "~1.3.3", "statuses": "2.0.1", "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" } }, - "follow-redirects": { + "node_modules/follow-redirects": { "version": "1.15.9", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", - "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==" - }, - "form-data": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", - "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } } }, - "forwarded": { + "node_modules/form-data": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } }, - "fresh": { + "node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } }, - "function-bind": { + "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "get-intrinsic": { + "node_modules/get-intrinsic": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz", "integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==", - "requires": { + "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", @@ -274,189 +401,305 @@ "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "get-proto": { + "node_modules/get-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "requires": { + "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" } }, - "gopd": { + "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==" + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "has-symbols": { + "node_modules/has-symbols": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==" + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "hasown": { + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "requires": { + "dependencies": { "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" } }, - "http-errors": { + "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "requires": { + "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", "statuses": "2.0.1", "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" } }, - "iconv-lite": { + "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { + "dependencies": { "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" } }, - "inherits": { + "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, - "ipaddr.js": { + "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } }, - "math-intrinsics": { + "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==" + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "engines": { + "node": ">= 0.4" + } }, - "media-typer": { + "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } }, - "merge-descriptors": { + "node_modules/merge-descriptors": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", - "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==" + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "methods": { + "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } }, - "mime": { + "node_modules/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } }, - "mime-db": { + "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } }, - "mime-types": { + "node_modules/mime-types": { "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "requires": { + "dependencies": { "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" } }, - "ms": { + "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, - "negotiator": { + "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } }, - "object-inspect": { + "node_modules/object-inspect": { "version": "1.13.3", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", - "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==" + "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "on-finished": { + "node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "requires": { + "dependencies": { "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" } }, - "parseurl": { + "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } }, - "path-to-regexp": { + "node_modules/path-to-regexp": { "version": "0.1.12", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==" }, - "proxy-addr": { + "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "requires": { + "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" } }, - "proxy-from-env": { + "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, - "qs": { + "node_modules/qs": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", - "requires": { + "dependencies": { "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "range-parser": { + "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } }, - "raw-body": { + "node_modules/raw-body": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "requires": { + "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" } }, - "safe-buffer": { + "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, - "safer-buffer": { + "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, - "send": { + "node_modules/send": { "version": "0.19.0", "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", - "requires": { + "dependencies": { "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", @@ -471,112 +714,161 @@ "range-parser": "~1.2.1", "statuses": "2.0.1" }, - "dependencies": { - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - } + "engines": { + "node": ">= 0.8.0" } }, - "serve-static": { + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/serve-static": { "version": "1.16.2", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", - "requires": { + "dependencies": { "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" } }, - "setprototypeof": { + "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" }, - "side-channel": { + "node_modules/side-channel": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", - "requires": { + "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", "side-channel-list": "^1.0.0", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "side-channel-list": { + "node_modules/side-channel-list": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", - "requires": { + "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "side-channel-map": { + "node_modules/side-channel-map": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "requires": { + "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "side-channel-weakmap": { + "node_modules/side-channel-weakmap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "requires": { + "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "statuses": { + "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } }, - "toidentifier": { + "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } }, - "type-is": { + "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "requires": { + "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" } }, - "unpipe": { + "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } }, - "utils-merge": { + "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } }, - "vary": { + "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } } } } diff --git a/src/charts/areachart-original.vl.json b/public/charts/areachart-original.vl.json similarity index 100% rename from src/charts/areachart-original.vl.json rename to public/charts/areachart-original.vl.json diff --git a/src/charts/areachart-ukrainian.vl.json b/public/charts/areachart-ukrainian.vl.json similarity index 100% rename from src/charts/areachart-ukrainian.vl.json rename to public/charts/areachart-ukrainian.vl.json diff --git a/src/charts/barchart-original.vl.json b/public/charts/barchart-original.vl.json similarity index 100% rename from src/charts/barchart-original.vl.json rename to public/charts/barchart-original.vl.json diff --git a/src/charts/barchart-ukrainian.vl.json b/public/charts/barchart-ukrainian.vl.json similarity index 100% rename from src/charts/barchart-ukrainian.vl.json rename to public/charts/barchart-ukrainian.vl.json diff --git a/src/charts/bubblechart-original.vl.json b/public/charts/bubblechart-original.vl.json similarity index 100% rename from src/charts/bubblechart-original.vl.json rename to public/charts/bubblechart-original.vl.json diff --git a/src/charts/bubblechart-ukrainian.vl.json b/public/charts/bubblechart-ukrainian.vl.json similarity index 100% rename from src/charts/bubblechart-ukrainian.vl.json rename to public/charts/bubblechart-ukrainian.vl.json diff --git a/src/charts/choropleth-original.vl.json b/public/charts/choropleth-original.vl.json similarity index 100% rename from src/charts/choropleth-original.vl.json rename to public/charts/choropleth-original.vl.json diff --git a/src/charts/choropleth-ukrainian.vl.json b/public/charts/choropleth-ukrainian.vl.json similarity index 100% rename from src/charts/choropleth-ukrainian.vl.json rename to public/charts/choropleth-ukrainian.vl.json diff --git a/src/charts/histogram-original.vl.json b/public/charts/histogram-original.vl.json similarity index 100% rename from src/charts/histogram-original.vl.json rename to public/charts/histogram-original.vl.json diff --git a/src/charts/histogram-ukrainian.vl.json b/public/charts/histogram-ukrainian.vl.json similarity index 100% rename from src/charts/histogram-ukrainian.vl.json rename to public/charts/histogram-ukrainian.vl.json diff --git a/src/charts/linechart-original.vl.json b/public/charts/linechart-original.vl.json similarity index 100% rename from src/charts/linechart-original.vl.json rename to public/charts/linechart-original.vl.json diff --git a/src/charts/linechart-ukrainian.vl.json b/public/charts/linechart-ukrainian.vl.json similarity index 100% rename from src/charts/linechart-ukrainian.vl.json rename to public/charts/linechart-ukrainian.vl.json diff --git a/src/charts/piechart-original.vl.json b/public/charts/piechart-original.vl.json similarity index 100% rename from src/charts/piechart-original.vl.json rename to public/charts/piechart-original.vl.json diff --git a/src/charts/piechart-ukrainian.vl.json b/public/charts/piechart-ukrainian.vl.json similarity index 100% rename from src/charts/piechart-ukrainian.vl.json rename to public/charts/piechart-ukrainian.vl.json diff --git a/src/charts/scatterplot-original.vl.json b/public/charts/scatterplot-original.vl.json similarity index 100% rename from src/charts/scatterplot-original.vl.json rename to public/charts/scatterplot-original.vl.json diff --git a/src/charts/scatterplot-ukrainian.vl.json b/public/charts/scatterplot-ukrainian.vl.json similarity index 100% rename from src/charts/scatterplot-ukrainian.vl.json rename to public/charts/scatterplot-ukrainian.vl.json diff --git a/src/charts/stacked100-original.vl.json b/public/charts/stacked100-original.vl.json similarity index 100% rename from src/charts/stacked100-original.vl.json rename to public/charts/stacked100-original.vl.json diff --git a/src/charts/stacked100-ukrainian.vl.json b/public/charts/stacked100-ukrainian.vl.json similarity index 100% rename from src/charts/stacked100-ukrainian.vl.json rename to public/charts/stacked100-ukrainian.vl.json diff --git a/src/charts/stackedareachart-original.vl.json b/public/charts/stackedareachart-original.vl.json similarity index 100% rename from src/charts/stackedareachart-original.vl.json rename to public/charts/stackedareachart-original.vl.json diff --git a/src/charts/stackedareachart-ukrainian.vl.json b/public/charts/stackedareachart-ukrainian.vl.json similarity index 100% rename from src/charts/stackedareachart-ukrainian.vl.json rename to public/charts/stackedareachart-ukrainian.vl.json diff --git a/src/charts/stackedbarchart-original.vl.json b/public/charts/stackedbarchart-original.vl.json similarity index 100% rename from src/charts/stackedbarchart-original.vl.json rename to public/charts/stackedbarchart-original.vl.json diff --git a/src/charts/stackedbarchart-ukrainian.vl.json b/public/charts/stackedbarchart-ukrainian.vl.json similarity index 100% rename from src/charts/stackedbarchart-ukrainian.vl.json rename to public/charts/stackedbarchart-ukrainian.vl.json diff --git a/src/charts/treemap-original.vl.json b/public/charts/treemap-original.vl.json similarity index 100% rename from src/charts/treemap-original.vl.json rename to public/charts/treemap-original.vl.json diff --git a/src/charts/treemap-ukrainian.vl.json b/public/charts/treemap-ukrainian.vl.json similarity index 100% rename from src/charts/treemap-ukrainian.vl.json rename to public/charts/treemap-ukrainian.vl.json diff --git a/src/css/styles.css b/public/css/styles.css similarity index 91% rename from src/css/styles.css rename to public/css/styles.css index b5aaa25..711388a 100644 --- a/src/css/styles.css +++ b/public/css/styles.css @@ -170,6 +170,22 @@ form button { margin-bottom: 20px; } +#progress-bar-container { + width: 100%; + background-color: #f3f3f3; + border-radius: 5px; + overflow: hidden; + margin-top: 10px; +} + +#progress-bar { + height: 20px; + width: 0; + background-color: #4caf50; + border-radius: 5px; + transition: width 0.3s; +} + table { width: 100%; border-collapse: collapse; diff --git a/src/data/barchart.csv b/public/data/barchart.csv similarity index 100% rename from src/data/barchart.csv rename to public/data/barchart.csv diff --git a/src/data/bubblechart.csv b/public/data/bubblechart.csv similarity index 100% rename from src/data/bubblechart.csv rename to public/data/bubblechart.csv diff --git a/src/data/choropleth.csv b/public/data/choropleth.csv similarity index 100% rename from src/data/choropleth.csv rename to public/data/choropleth.csv diff --git a/src/data/histogram.csv b/public/data/histogram.csv similarity index 100% rename from src/data/histogram.csv rename to public/data/histogram.csv diff --git a/src/data/linechart.json b/public/data/linechart.json similarity index 100% rename from src/data/linechart.json rename to public/data/linechart.json diff --git a/src/data/piechart.csv b/public/data/piechart.csv similarity index 100% rename from src/data/piechart.csv rename to public/data/piechart.csv diff --git a/src/data/questions.json b/public/data/questions.json similarity index 98% rename from src/data/questions.json rename to public/data/questions.json index 8697918..7602082 100644 --- a/src/data/questions.json +++ b/public/data/questions.json @@ -255,7 +255,7 @@ { "chart": "scatterplot", "chart_uk": "точкова діаграма", - "question": "Існує негативний лінійний зв'язок між зростом та вагою 85 чоловіків.", + "question": "Існує негативний лінійний зв'язок між зростом та вагою 85 осіб.", "options": [ "Правда", "Неправда", @@ -421,7 +421,7 @@ { "chart": "scatterplot", "chart_uk": "точкова діаграма", - "question": "Існує негативний лінійний зв'язок між зростом та вагою 85 чоловіків.", + "question": "Існує негативний лінійний зв'язок між зростом та вагою 85 осіб.", "options": [ "Правда", "Неправда", diff --git a/src/data/scatterplot.csv b/public/data/scatterplot.csv similarity index 100% rename from src/data/scatterplot.csv rename to public/data/scatterplot.csv diff --git a/src/data/stacked100.csv b/public/data/stacked100.csv similarity index 100% rename from src/data/stacked100.csv rename to public/data/stacked100.csv diff --git a/src/data/stackedbarchart.csv b/public/data/stackedbarchart.csv similarity index 100% rename from src/data/stackedbarchart.csv rename to public/data/stackedbarchart.csv diff --git a/src/data/state-coordinates.json b/public/data/state-coordinates.json similarity index 100% rename from src/data/state-coordinates.json rename to public/data/state-coordinates.json diff --git a/src/data/topo-USA.json b/public/data/topo-USA.json similarity index 100% rename from src/data/topo-USA.json rename to public/data/topo-USA.json diff --git a/src/data/treemap-en.png b/public/data/treemap-en.png similarity index 100% rename from src/data/treemap-en.png rename to public/data/treemap-en.png diff --git a/src/data/treemap-uk.png b/public/data/treemap-uk.png similarity index 100% rename from src/data/treemap-uk.png rename to public/data/treemap-uk.png diff --git a/src/images/areachart-original.svg b/public/images/areachart-original.svg similarity index 100% rename from src/images/areachart-original.svg rename to public/images/areachart-original.svg diff --git a/src/images/areachart-ukrainian.svg b/public/images/areachart-translated.svg similarity index 100% rename from src/images/areachart-ukrainian.svg rename to public/images/areachart-translated.svg diff --git a/public/images/areachart-ukrainian.svg b/public/images/areachart-ukrainian.svg new file mode 100644 index 0000000..eb5604e --- /dev/null +++ b/public/images/areachart-ukrainian.svg @@ -0,0 +1 @@ +кві 2018лип 2018жов 2018січ 2019кві 2019лип 2019жов 20190.500.550.600.650.700.750.800.85Ціна кави ($/фунт)Ціна кави Робуста \ No newline at end of file diff --git a/src/images/barchart-original.svg b/public/images/barchart-original.svg similarity index 100% rename from src/images/barchart-original.svg rename to public/images/barchart-original.svg diff --git a/src/images/barchart-ukrainian.svg b/public/images/barchart-translated.svg similarity index 100% rename from src/images/barchart-ukrainian.svg rename to public/images/barchart-translated.svg diff --git a/public/images/barchart-ukrainian.svg b/public/images/barchart-ukrainian.svg new file mode 100644 index 0000000..c28a196 --- /dev/null +++ b/public/images/barchart-ukrainian.svg @@ -0,0 +1 @@ +АвстраліяКитайГонконгІндіяІндонезіяЯпоніяМалайзіяНова ЗеландіяСінгапурПівденна КореяШрі-ЛанкаТайваньТаїландВ'єтнам0102030405060708090100Швидкість інтернету (МБіт/с)Світова швидкість інтернету (МБіт/с) \ No newline at end of file diff --git a/src/images/bubblechart-original.svg b/public/images/bubblechart-original.svg similarity index 100% rename from src/images/bubblechart-original.svg rename to public/images/bubblechart-original.svg diff --git a/src/images/bubblechart-ukrainian.svg b/public/images/bubblechart-translated.svg similarity index 100% rename from src/images/bubblechart-ukrainian.svg rename to public/images/bubblechart-translated.svg diff --git a/public/images/bubblechart-ukrainian.svg b/public/images/bubblechart-ukrainian.svg new file mode 100644 index 0000000..1159fbe --- /dev/null +++ b/public/images/bubblechart-ukrainian.svg @@ -0,0 +1 @@ +150200250300350400450500550600650700750800Кількість станцій150200250300350400450500Загальна довжина системи (км)ДеліГуанчжоуТокіоМехікоЛондонСеулПарижПекінШанхайНью-Йорк234Пасажиропотік (млрд на рік)Системи метро світу \ No newline at end of file diff --git a/src/images/choropleth-original.svg b/public/images/choropleth-original.svg similarity index 100% rename from src/images/choropleth-original.svg rename to public/images/choropleth-original.svg diff --git a/public/images/choropleth-translated.svg b/public/images/choropleth-translated.svg new file mode 100644 index 0000000..4e8f0a1 --- /dev/null +++ b/public/images/choropleth-translated.svg @@ -0,0 +1 @@ +NESDUTNDIAIDMEVTWYALKSMTARMOOKMNSCVAWIGAKYNHMDINCONCTNORTXFLAKDEAZCTDCMSOHLAWVNMWAMAPNRIILNJMINYCAHINV681012Рівень безробіття (%)Рівень безробіття в США в 2020 \ No newline at end of file diff --git a/src/images/choropleth-ukrainian.svg b/public/images/choropleth-ukrainian.svg similarity index 100% rename from src/images/choropleth-ukrainian.svg rename to public/images/choropleth-ukrainian.svg diff --git a/src/images/histogram-original.svg b/public/images/histogram-original.svg similarity index 100% rename from src/images/histogram-original.svg rename to public/images/histogram-original.svg diff --git a/src/images/histogram-ukrainian.svg b/public/images/histogram-translated.svg similarity index 100% rename from src/images/histogram-ukrainian.svg rename to public/images/histogram-translated.svg diff --git a/public/images/histogram-ukrainian.svg b/public/images/histogram-ukrainian.svg new file mode 100644 index 0000000..52b8b48 --- /dev/null +++ b/public/images/histogram-ukrainian.svg @@ -0,0 +1 @@ +0102030405060708090100110Відстань (км)020406080100120140160180200220240260Кількість клієнтівВідстань поїздки та клієнти \ No newline at end of file diff --git a/src/images/linechart-original.svg b/public/images/linechart-original.svg similarity index 100% rename from src/images/linechart-original.svg rename to public/images/linechart-original.svg diff --git a/src/images/linechart-ukrainian.svg b/public/images/linechart-translated.svg similarity index 100% rename from src/images/linechart-ukrainian.svg rename to public/images/linechart-translated.svg diff --git a/public/images/linechart-ukrainian.svg b/public/images/linechart-ukrainian.svg new file mode 100644 index 0000000..e67c511 --- /dev/null +++ b/public/images/linechart-ukrainian.svg @@ -0,0 +1 @@ +лют 2020бер 2020кві 2020тра 2020чер 2020лип 2020сер 2020вер 2020жов 2020лис 2020гру 2020Місяць051015202530354045505560Ціна за барель нафти ($)Ціни на нафту \ No newline at end of file diff --git a/src/images/piechart-original.svg b/public/images/piechart-original.svg similarity index 100% rename from src/images/piechart-original.svg rename to public/images/piechart-original.svg diff --git a/src/images/piechart-ukrainian.svg b/public/images/piechart-translated.svg similarity index 100% rename from src/images/piechart-ukrainian.svg rename to public/images/piechart-translated.svg diff --git a/public/images/piechart-ukrainian.svg b/public/images/piechart-ukrainian.svg new file mode 100644 index 0000000..06c5f69 --- /dev/null +++ b/public/images/piechart-ukrainian.svg @@ -0,0 +1 @@ +SamsungXiaomiAppleOppoVivoІншіРозподіл світового ринку смартфонів у 2021 році \ No newline at end of file diff --git a/src/images/scatterplot-original.svg b/public/images/scatterplot-original.svg similarity index 100% rename from src/images/scatterplot-original.svg rename to public/images/scatterplot-original.svg diff --git a/src/images/scatterplot-ukrainian.svg b/public/images/scatterplot-translated.svg similarity index 100% rename from src/images/scatterplot-ukrainian.svg rename to public/images/scatterplot-translated.svg diff --git a/public/images/scatterplot-ukrainian.svg b/public/images/scatterplot-ukrainian.svg new file mode 100644 index 0000000..5d2a309 --- /dev/null +++ b/public/images/scatterplot-ukrainian.svg @@ -0,0 +1 @@ +156158160162164166168170172174176178180182184186188190Зріст (см)4045505560657075Вага (кг)Вага та зріст 85 осіб \ No newline at end of file diff --git a/src/images/stacked100-original.svg b/public/images/stacked100-original.svg similarity index 100% rename from src/images/stacked100-original.svg rename to public/images/stacked100-original.svg diff --git a/src/images/stacked100-ukrainian.svg b/public/images/stacked100-translated.svg similarity index 100% rename from src/images/stacked100-ukrainian.svg rename to public/images/stacked100-translated.svg diff --git a/public/images/stacked100-ukrainian.svg b/public/images/stacked100-ukrainian.svg new file mode 100644 index 0000000..5697d41 --- /dev/null +++ b/public/images/stacked100-ukrainian.svg @@ -0,0 +1 @@ +АвстраліяВелика БританіяСШАЯпонія0%10%20%30%40%50%60%70%80%90%100%ВідсотокЗолотоСріблоБронзаМедаліРозподіл олімпійських медалей за країною \ No newline at end of file diff --git a/src/images/stackedareachart-original.svg b/public/images/stackedareachart-original.svg similarity index 100% rename from src/images/stackedareachart-original.svg rename to public/images/stackedareachart-original.svg diff --git a/public/images/stackedareachart-translated.svg b/public/images/stackedareachart-translated.svg new file mode 100644 index 0000000..20493d5 --- /dev/null +++ b/public/images/stackedareachart-translated.svg @@ -0,0 +1 @@ +200920102011201220132014Year02,0004,0006,0008,00010,00012,00014,00016,000Кількість дівчатAmeliaIslaOliviaПопулярні імена для дівчаток в Великій Британії \ No newline at end of file diff --git a/src/images/stackedareachart-ukrainian.svg b/public/images/stackedareachart-ukrainian.svg similarity index 100% rename from src/images/stackedareachart-ukrainian.svg rename to public/images/stackedareachart-ukrainian.svg diff --git a/src/images/stackedbarchart-original.svg b/public/images/stackedbarchart-original.svg similarity index 100% rename from src/images/stackedbarchart-original.svg rename to public/images/stackedbarchart-original.svg diff --git a/src/images/stackedbarchart-ukrainian.svg b/public/images/stackedbarchart-translated.svg similarity index 100% rename from src/images/stackedbarchart-ukrainian.svg rename to public/images/stackedbarchart-translated.svg diff --git a/public/images/stackedbarchart-ukrainian.svg b/public/images/stackedbarchart-ukrainian.svg new file mode 100644 index 0000000..d8a5b9b --- /dev/null +++ b/public/images/stackedbarchart-ukrainian.svg @@ -0,0 +1 @@ +ГельсінкіКопенгагенНью-ЙоркОслоПарижСеулСтокгольмСінгапурТоронтоЦюрихМісто0510152025303540455055606570Ціна ($)ГорілкаГазована водаАрахісВодаСендвічЦіни на обслуговування в номері \ No newline at end of file diff --git a/src/images/treemap-original.png b/public/images/treemap-original.png similarity index 100% rename from src/images/treemap-original.png rename to public/images/treemap-original.png diff --git a/src/images/treemap-ukrainian.png b/public/images/treemap-translated.png similarity index 100% rename from src/images/treemap-ukrainian.png rename to public/images/treemap-translated.png diff --git a/public/images/treemap-ukrainian.png b/public/images/treemap-ukrainian.png new file mode 100644 index 0000000..9aab54f Binary files /dev/null and b/public/images/treemap-ukrainian.png differ diff --git a/public/index.html b/public/index.html index ba89676..54da5dc 100644 --- a/public/index.html +++ b/public/index.html @@ -15,13 +15,24 @@ Запрошуємо взяти участь в дослідженні з адаптації інструменту оцінки грамотності в візуалізації даних, яке проводять викладачі та студенти Київської школи економіки.

- Мета дослідження полягає в адаптації інструменту, який вимірює, наскільки вдало люди можуть розуміти, інтерпретувати та використовувати дані, що містяться в візуалізаціях (графіки, діаграми тощо), для вирішення повсякденних проблем. + Мета дослідження – адаптація інструменту, який вимірює, наскільки вдало люди можуть розуміти, інтерпретувати та використовувати дані, що містяться в графіках, діаграмах тощо.

- Вам буде запропоновано 12 різних типів візуалізацій даних. Кожен з них буде супроводжений запитанням, відповідь на яке потрібно дати, засновуючись на інформації що отримана із візуалізації. Мова опитування буде обрана випадковим чином із двох: українська або англійська. Оберіть відповідь, яку вважаєте найточнішою. Якщо ви не впевнені, оберіть “пропустити” замість того щоб вгадувати. На кожне запитання ви маєте 25 секунд для відповіді. Якщо ви не встигли відповісти, тест автоматично перейде до наступного запитання. + Вам буде запропоновано 12 різних типів візуалізацій даних. Кожен з них буде супроводжений запитанням, відповідь на яке потрібно дати, засновуючись на інформації що отримана із візуалізації. Мова опитування буде обрана випадковим чином із двох: українська або англійська. Оберіть відповідь, яку вважаєте найточнішою. Якщо ви не впевнені, оберіть “пропустити” аби не вгадувати. На кожне запитання ви маєте 25 секунд для відповіді. Якщо ви не встигли відповісти, тест автоматично перейде до наступного запитання.

- Після надання відповідей ми попросимо вас також заповнити коротку демографічну анкету. Дані, що ми зберемо протягом опитування, є анонімними та не зможуть бути використані для ідентифікації вашої особи. Вони будуть використані в поточному та подальших дослідженнях грамотності в сфері візуалізації даних. Ці дані можуть бути передані іншим дослідникам/цям, що проводять дослідження в цій або суміжних сферах. Також вони будуть опубліковані в репозиторіях для ширшого доступу наукової спільноти. + Орієнтовний час проходження опитування - 8-10 хвилин. +

+

+ Просимо за можливості проходити опитування на комп’ютері або планшеті, а не на мобільному телефоні. +

+

+ Після надання відповідей ми попросимо вас також заповнити коротку демографічну анкету. +

+

+ Дані, що ми зберемо протягом опитування, є анонімними та не можуть бути використані для того щоб ідентифікувати вашу особистість. Вони будуть використані лише для наукових цілей та публікацій. + Ми використаємо дані, які ми отримуємо в цьому опитванні, для поточних та подальших досліджень. + Ці дослідження можуть надати додаткову інформацію, яка буде корисною для розробки кращих інструментів візуальної комунікації українською мовою. Ми можемо також поділитись результатами дослідження з іншими науковцями та публікувати їх у наукових журналах.

Якщо ви маєте будь-які питання щодо змісту та деталей дослідження, звʼяжіться з Олегом Омельченком o_omelchenko@kse.org.ua. @@ -31,6 +42,18 @@

+ \ No newline at end of file diff --git a/src/js/app.js b/public/js/app.js similarity index 97% rename from src/js/app.js rename to public/js/app.js index 3b8aebb..b1e0079 100644 --- a/src/js/app.js +++ b/public/js/app.js @@ -42,7 +42,7 @@ function initResultsPage() { } function loadQuestions(version) { - fetch('../data/questions.json') + fetch('data/questions.json') .then(response => response.json()) .then(data => { const questions = data.quizzes[version]; diff --git a/src/js/consent.js b/public/js/consent.js similarity index 100% rename from src/js/consent.js rename to public/js/consent.js diff --git a/src/js/questionnaire.js b/public/js/questionnaire.js similarity index 77% rename from src/js/questionnaire.js rename to public/js/questionnaire.js index c2e9450..c8d623b 100644 --- a/src/js/questionnaire.js +++ b/public/js/questionnaire.js @@ -1,5 +1,9 @@ // This file handles the logic for the questionnaire, including collecting additional participant information after the quiz. +// Configure webhook URL via environment variable on server side +// Fallback to local API endpoint if no external webhook configured +const WEBHOOK_URL = '/api/responses'; + document.addEventListener('DOMContentLoaded', function() { const questionnaireForm = document.getElementById('questionnaire-form'); @@ -39,35 +43,30 @@ document.addEventListener('DOMContentLoaded', function() { const quizId = 'quiz'; if (allQuizzes[quizId]) { allQuizzes[quizId].participantData = participantData; - allQuizzes[quizId].iterationVersion = 'v1.0.0'; // Add semantic versioning + allQuizzes[quizId].iterationVersion = 'v2.0.0'; // Add semantic versioning localStorage.setItem('allQuizzes', JSON.stringify(allQuizzes)); } - // Send data to the backend - fetch('/api/responses', { + // Combine quiz results and questionnaire data + const combinedData = { + allQuizzes: allQuizzes + }; + + // Send combined data to webhook + fetch(WEBHOOK_URL, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(allQuizzes) }) - .then(response => { - if (!response.ok) { - throw new Error('Network response was not ok'); - } - return response.json(); - }) - .then(data => { - if (data.success) { - console.log('Success:', data); - window.location.href = 'results.html'; - } else { - throw new Error(data.message || 'Failed to submit the form'); - } + .then(() => { + alert('Анкету надіслано успішно'); + window.location.href = 'results.html'; }) .catch((error) => { - console.error('Error:', error); - showError('Failed to submit the form. Please try again.'); + console.error('Error sending data:', error); + alert('Сталася помилка при надсиланні анкети'); submitButton.disabled = false; }); }); diff --git a/src/js/quiz.js b/public/js/quiz.js similarity index 90% rename from src/js/quiz.js rename to public/js/quiz.js index c5bd760..aa964c2 100644 --- a/src/js/quiz.js +++ b/public/js/quiz.js @@ -14,7 +14,8 @@ document.addEventListener('DOMContentLoaded', function () { const initialTimeLeft = 25000; // 25 seconds in milliseconds let timeLeft = initialTimeLeft; let timer; - let startTime = new Date().toISOString(); + let startTime = new Date().getTime(); // Change to getTime for milliseconds precision + const progressBar = document.getElementById('progress-bar'); // Set timer label based on version if (version === 'ukrainian') { @@ -85,7 +86,7 @@ document.addEventListener('DOMContentLoaded', function () { timerDisplay.textContent = Math.ceil(timeLeft / 1000); // Display in whole seconds const question = questions[currentQuestionIndex]; - const imageVersion = version === 'translated' ? 'original' : version; + const imageVersion = version; const imagePath = `/images/${question.chart}-${imageVersion}.${question.image}`; document.getElementById('chart').innerHTML = `${question.chart_uk}`; @@ -102,6 +103,9 @@ document.addEventListener('DOMContentLoaded', function () { document.querySelectorAll('.option-button').forEach(button => { button.addEventListener('click', () => submitAnswer(button.dataset.value)); }); + + startTime = new Date().getTime(); // Reset start time for each question + updateProgressBar(); } function stopTimer() { @@ -125,7 +129,7 @@ document.addEventListener('DOMContentLoaded', function () { if (timeLeft <= 0) { stopTimer(); alert("Time's up! Moving to the next question."); - submitAnswer(true); + submitAnswer('timeout'); // Pass 'timeout' as the selected answer } }, 100); } @@ -165,6 +169,9 @@ document.addEventListener('DOMContentLoaded', function () { score++; } + const endTime = new Date().getTime(); // Capture end time + const timeSpent = endTime - startTime; // Calculate time spent in milliseconds + // Store the question result quizResults.push({ question: currentQuestion.question, @@ -174,7 +181,7 @@ document.addEventListener('DOMContentLoaded', function () { questionIndex: currentQuestionIndex, ordinalNumber: currentQuestionIndex + 1, // Store the ordinal number of the question timestamp: new Date().toISOString(), - timeSpent: 25000 - timeLeft, // Time spent in milliseconds + timeSpent: timeSpent, // Use the calculated time spent chartType: currentQuestion.chart, chartTypeUk: currentQuestion.chart_uk // Include chart_uk type }); @@ -183,6 +190,7 @@ document.addEventListener('DOMContentLoaded', function () { storeQuizProgress(); currentQuestionIndex++; + updateProgressBar(); // Reset timer state before showing next question timeLeft = initialTimeLeft; // Reset to initial time displayQuestion(); @@ -198,4 +206,9 @@ document.addEventListener('DOMContentLoaded', function () { // Redirect to the questionnaire page window.location.href = 'questionnaire.html'; } + + function updateProgressBar() { + const progress = (currentQuestionIndex / questions.length) * 100; + progressBar.style.width = `${progress}%`; + } }); \ No newline at end of file diff --git a/src/js/results.js b/public/js/results.js similarity index 100% rename from src/js/results.js rename to public/js/results.js diff --git a/public/questionnaire.html b/public/questionnaire.html index f6bafeb..e9b906e 100644 --- a/public/questionnaire.html +++ b/public/questionnaire.html @@ -51,10 +51,10 @@ diff --git a/public/quiz.html b/public/quiz.html index fa8eb19..401e1ad 100644 --- a/public/quiz.html +++ b/public/quiz.html @@ -13,15 +13,17 @@
-
- Time remaining: 25s -
- +
+ Time remaining: 25s +
+
+
+
diff --git a/server.js b/server.js index 31455f5..f3e19d4 100644 --- a/server.js +++ b/server.js @@ -23,6 +23,7 @@ app.post('/api/responses', (req, res) => { // Redirect payload to webhook if (WEBHOOK_URL) { + console.log("sending to ", WEBHOOK_URL); axios.post(WEBHOOK_URL, JSON.stringify(response), { headers: { 'Content-Type': 'application/json' diff --git a/src/images-big/areachart-original.svg b/src/images-big/areachart-original.svg deleted file mode 100644 index 8f3c7e8..0000000 --- a/src/images-big/areachart-original.svg +++ /dev/null @@ -1 +0,0 @@ -Apr 2018Jul 2018Oct 2018Jan 2019Apr 2019Jul 2019Oct 20190.500.550.600.650.700.750.800.85Coffee Price ($/lb)Robusta Coffee Price \ No newline at end of file diff --git a/src/images-big/areachart-ukrainian.svg b/src/images-big/areachart-ukrainian.svg deleted file mode 100644 index eed09ef..0000000 --- a/src/images-big/areachart-ukrainian.svg +++ /dev/null @@ -1 +0,0 @@ -кві 2018лип 2018жов 2018січ 2019кві 2019лип 2019жов 20190.500.550.600.650.700.750.800.85Ціна кави ($/фунт)Ціна кави Робуста \ No newline at end of file diff --git a/src/images-big/barchart-original.svg b/src/images-big/barchart-original.svg deleted file mode 100644 index 4b6820f..0000000 --- a/src/images-big/barchart-original.svg +++ /dev/null @@ -1 +0,0 @@ -AustraliaChinaHong KongIndiaIndonesiaJapanMalaysiaNew ZealandSingaporeSouth KoreaSri LankaTaiwanThailandVietnam0102030405060708090100Internet Speed (Mbps)Global Internet Speed (Mbps) \ No newline at end of file diff --git a/src/images-big/barchart-ukrainian.svg b/src/images-big/barchart-ukrainian.svg deleted file mode 100644 index 5347e7b..0000000 --- a/src/images-big/barchart-ukrainian.svg +++ /dev/null @@ -1 +0,0 @@ -ІндонезіяІндіяАвстраліяВ'єтнамГонконгКитайМалайзіяНова ЗеландіяПівденна КореяСінгапурТайваньТаїландШрі-ЛанкаЯпонія0102030405060708090100Швидкість інтернету (МБіт/с)Світова швидкість інтернету (МБіт/с) \ No newline at end of file diff --git a/src/images-big/bubblechart-original.svg b/src/images-big/bubblechart-original.svg deleted file mode 100644 index d794225..0000000 --- a/src/images-big/bubblechart-original.svg +++ /dev/null @@ -1 +0,0 @@ -150200250300350400450500550600650700750800Number of Stations150200250300350400450500Total System Length (Km)DelhiGuangzhowTokyoMexico CityLondonSeoulParisBeijingShanghaiN.Y.C.234Ridership (bn per year)Metro Systems of the World \ No newline at end of file diff --git a/src/images-big/bubblechart-ukrainian.svg b/src/images-big/bubblechart-ukrainian.svg deleted file mode 100644 index 8ae3b03..0000000 --- a/src/images-big/bubblechart-ukrainian.svg +++ /dev/null @@ -1 +0,0 @@ -150200250300350400450500550600650700750800Кількість станцій150200250300350400450500Загальна довжина системи (км)ДеліГуанчжоуТокіоМехікоЛондонСеулПарижПекінШанхайНью-Йорк234Пасажиропотік (млрд на рік)Системи метро світу \ No newline at end of file diff --git a/src/images-big/choropleth-original.svg b/src/images-big/choropleth-original.svg deleted file mode 100644 index f59062e..0000000 --- a/src/images-big/choropleth-original.svg +++ /dev/null @@ -1 +0,0 @@ -NESDUTNDIAIDMEVTWYALKSMTARMOOKMNSCVAWIGAKYNHMDINCONCTNORTXFLAKDEAZCTDCMSOHLAWVNMWAMAPNRIILNJMINYCAHINV681012Unemployment Rate (%)Unemployment Rates for States in 2020 \ No newline at end of file diff --git a/src/images-big/choropleth-ukrainian.svg b/src/images-big/choropleth-ukrainian.svg deleted file mode 100644 index de7ba3c..0000000 --- a/src/images-big/choropleth-ukrainian.svg +++ /dev/null @@ -1 +0,0 @@ -ЛьвІвФТерм.КВолРівЗакЧнцК.оХарЧркДніСумПолЗапХерВінЖитХмеОдеКірСевЧнгДонМикЛугАРК02,0004,0006,0008,000Кількість шлюбів в першому півріччі 2024 р. \ No newline at end of file diff --git a/src/images-big/histogram-original.svg b/src/images-big/histogram-original.svg deleted file mode 100644 index 53ec354..0000000 --- a/src/images-big/histogram-original.svg +++ /dev/null @@ -1 +0,0 @@ -0102030405060708090100110Distance (in Km)020406080100120140160180200220240260Number of CustomersTrip Distance and Customers \ No newline at end of file diff --git a/src/images-big/histogram-ukrainian.svg b/src/images-big/histogram-ukrainian.svg deleted file mode 100644 index af074cf..0000000 --- a/src/images-big/histogram-ukrainian.svg +++ /dev/null @@ -1 +0,0 @@ -0102030405060708090100110Відстань (км)020406080100120140160180200220240260Кількість клієнтівВідстань поїздки та клієнти \ No newline at end of file diff --git a/src/images-big/linechart-original.svg b/src/images-big/linechart-original.svg deleted file mode 100644 index 4057559..0000000 --- a/src/images-big/linechart-original.svg +++ /dev/null @@ -1 +0,0 @@ -Feb 2020Mar 2020Apr 2020May 2020Jun 2020Jul 2020Aug 2020Sep 2020Oct 2020Nov 2020Dec 2020Month051015202530354045505560Oil Price (USD)Oil Prices \ No newline at end of file diff --git a/src/images-big/linechart-ukrainian.svg b/src/images-big/linechart-ukrainian.svg deleted file mode 100644 index 39863ec..0000000 --- a/src/images-big/linechart-ukrainian.svg +++ /dev/null @@ -1 +0,0 @@ -лют 2020бер 2020кві 2020тра 2020чер 2020лип 2020сер 2020вер 2020жов 2020лис 2020гру 2020Місяць051015202530354045505560Ціна за барель нафти ($)Ціни на нафту \ No newline at end of file diff --git a/src/images-big/piechart-original.svg b/src/images-big/piechart-original.svg deleted file mode 100644 index 722d48a..0000000 --- a/src/images-big/piechart-original.svg +++ /dev/null @@ -1 +0,0 @@ -SamsungXiaomiAppleOppoVivoOthersGlobal Smartphone Market Share in 2021 \ No newline at end of file diff --git a/src/images-big/piechart-ukrainian.svg b/src/images-big/piechart-ukrainian.svg deleted file mode 100644 index 73418a2..0000000 --- a/src/images-big/piechart-ukrainian.svg +++ /dev/null @@ -1 +0,0 @@ -SamsungXiaomiAppleOppoVivoІншіРозподіл світового ринку смартфонів у 2021 році \ No newline at end of file diff --git a/src/images-big/scatterplot-original.svg b/src/images-big/scatterplot-original.svg deleted file mode 100644 index aa5904d..0000000 --- a/src/images-big/scatterplot-original.svg +++ /dev/null @@ -1 +0,0 @@ -156158160162164166168170172174176178180182184186188190Height (cm)4045505560657075Weight (kg)Weight and Height of 85 Individuals \ No newline at end of file diff --git a/src/images-big/scatterplot-ukrainian.svg b/src/images-big/scatterplot-ukrainian.svg deleted file mode 100644 index 3738bc1..0000000 --- a/src/images-big/scatterplot-ukrainian.svg +++ /dev/null @@ -1 +0,0 @@ -156158160162164166168170172174176178180182184186188190Зріст (см)4045505560657075Вага (кг)Вага та зріст 85 осіб \ No newline at end of file diff --git a/src/images-big/stacked100-original.svg b/src/images-big/stacked100-original.svg deleted file mode 100644 index 5aecdbe..0000000 --- a/src/images-big/stacked100-original.svg +++ /dev/null @@ -1 +0,0 @@ -AustraliaGreat BritainJapanU.S.A.0%10%20%30%40%50%60%70%80%90%100%PercentageGoldSilverBronzeMedalsOlympic Medal Distribution by Country \ No newline at end of file diff --git a/src/images-big/stacked100-ukrainian.svg b/src/images-big/stacked100-ukrainian.svg deleted file mode 100644 index 4bd01aa..0000000 --- a/src/images-big/stacked100-ukrainian.svg +++ /dev/null @@ -1 +0,0 @@ -АвстраліяВелика БританіяСШАЯпонія0%10%20%30%40%50%60%70%80%90%100%ВідсотокЗолотоСріблоБронзаМедаліРозподіл олімпійських медалей за країною \ No newline at end of file diff --git a/src/images-big/stackedareachart-original.svg b/src/images-big/stackedareachart-original.svg deleted file mode 100644 index 0528dd5..0000000 --- a/src/images-big/stackedareachart-original.svg +++ /dev/null @@ -1 +0,0 @@ -200920102011201220132014Year02,0004,0006,0008,00010,00012,00014,00016,000Number of GirlsAmeliaIslaOliviaPopular Girls' names in the UK \ No newline at end of file diff --git a/src/images-big/stackedareachart-ukrainian.svg b/src/images-big/stackedareachart-ukrainian.svg deleted file mode 100644 index 4a3ca3b..0000000 --- a/src/images-big/stackedareachart-ukrainian.svg +++ /dev/null @@ -1 +0,0 @@ -2,009.02,009.22,009.42,009.62,009.82,010.02,010.22,010.42,010.62,010.82,011.02,011.22,011.42,011.62,011.82,012.02,012.22,012.42,012.62,012.82,013.02,013.22,013.42,013.62,013.82,014.0Рік02,0004,0006,0008,00010,00012,00014,00016,000Кількість тоннЛиповийГречанийАкацієвийПопулярність виробництва сортів меду \ No newline at end of file diff --git a/src/images-big/stackedbarchart-original.svg b/src/images-big/stackedbarchart-original.svg deleted file mode 100644 index 7b87c44..0000000 --- a/src/images-big/stackedbarchart-original.svg +++ /dev/null @@ -1 +0,0 @@ -CopenhagenHelsinkiN.Y.C.OsloParisSeoulSingaporeStockholmTorontoZurichCities0510152025303540455055606570Cost ($)VodkaSodaPeanutWaterSandwichRoom Service Prices \ No newline at end of file diff --git a/src/images-big/stackedbarchart-ukrainian.svg b/src/images-big/stackedbarchart-ukrainian.svg deleted file mode 100644 index c50ead8..0000000 --- a/src/images-big/stackedbarchart-ukrainian.svg +++ /dev/null @@ -1 +0,0 @@ -ГельсінкіКопенгагенНью-ЙоркОслоПарижСеулСтокгольмСінгапурТоронтоЦюрихМісто0510152025303540455055606570Ціна ($)ГорілкаГазована водаАрахісВодаСендвічЦіни на обслуговування в номері \ No newline at end of file diff --git a/src/images-big/treemap-original.svg b/src/images-big/treemap-original.svg deleted file mode 100644 index 51c03ad..0000000 --- a/src/images-big/treemap-original.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/images-big/treemap-ukrainian.png b/src/images-big/treemap-ukrainian.png deleted file mode 100644 index a6110ae..0000000 Binary files a/src/images-big/treemap-ukrainian.png and /dev/null differ diff --git a/src/images-big/treemap-ukrainian.svg b/src/images-big/treemap-ukrainian.svg deleted file mode 100644 index d335a7f..0000000 --- a/src/images-big/treemap-ukrainian.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file