From d10b274fe0bb4750b4eb44e91d2a02d5a9109506 Mon Sep 17 00:00:00 2001 From: rxf Date: Fri, 24 Mar 2023 13:49:54 +0100 Subject: [PATCH] First running version --- app.js | 5 +- package-lock.json | 1053 ++++++++++++++----------- package.json | 5 +- public/javascripts/chart_dayavg.js | 134 ++++ public/javascripts/chart_daynight.js | 160 ++++ public/javascripts/chart_houravg.js | 129 +++ public/javascripts/chart_lden.js | 112 +++ public/javascripts/chart_live.js | 99 +-- public/javascripts/chart_utilities.js | 74 +- public/javascripts/global.js | 35 +- public/javascripts/map.js | 102 +-- public/stylesheets/style.css | 12 +- public/stylesheets/style.css.map | 2 +- public/stylesheets/style.sass | 10 +- routes/api.js | 37 + routes/index.js | 25 +- views/index.pug | 25 +- views/layout.pug | 3 +- 18 files changed, 1377 insertions(+), 645 deletions(-) create mode 100644 public/javascripts/chart_dayavg.js create mode 100644 public/javascripts/chart_daynight.js create mode 100644 public/javascripts/chart_houravg.js create mode 100644 public/javascripts/chart_lden.js create mode 100644 routes/api.js diff --git a/app.js b/app.js index 63546bd..afaa3b4 100644 --- a/app.js +++ b/app.js @@ -6,11 +6,14 @@ import path from 'path' import { fileURLToPath } from 'url'; const app = express() +export let url2call const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); import indexRouter from './routes/index.js' +import apiRouter from './routes/api.js' + // import getdataRouter from './routes/getdata.js' // import putdataRouter from './routes/putdata.js' @@ -24,6 +27,7 @@ app.use(express.urlencoded({ extended: false })); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); +app.use('/api', apiRouter) app.use('/', indexRouter); // app.use('/users', usersRouter); @@ -43,5 +47,4 @@ app.use(function(err, req, res, next) { res.render('error'); }); - export default app diff --git a/package-lock.json b/package-lock.json index c25d25d..ff073ad 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,37 +1,65 @@ { "name": "laerm-web-sensorapi", - "version": "0.0.0", + "version": "3.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "laerm-web-sensorapi", - "version": "0.0.0", + "version": "3.0.0", "dependencies": { + "axios": "^1.3.4", "cookie-parser": "~1.4.4", "cors": "^2.8.5", "debug": "~2.6.9", - "express": "~4.16.1", + "express": "^4.18.2", "http-errors": "~1.6.3", "morgan": "~1.9.1", - "pug": "2.0.0-beta11", + "pug": "^3.0.2", "sass": "^1.58.3" }, "bin": { "www": "bin/www.js" } }, - "node_modules/@types/babel-types": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/babel-types/-/babel-types-7.0.11.tgz", - "integrity": "sha512-pkPtJUUY+Vwv6B1inAz55rQvivClHJxc9aVEPPmaq2cbyeMLCiDpbKpcKyX4LAwpNGi+SHBv0tHv6+0gXv0P2A==" + "node_modules/@babel/helper-string-parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "engines": { + "node": ">=6.9.0" + } }, - "node_modules/@types/babylon": { - "version": "6.16.6", - "resolved": "https://registry.npmjs.org/@types/babylon/-/babylon-6.16.6.tgz", - "integrity": "sha512-G4yqdVlhr6YhzLXFKy5F7HtRBU8Y23+iWy7UKthMq/OSQnL1hbsoeXESQ2LY8zEDlknipDG3nRGhUC9tkwvy/w==", + "node_modules/@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.3.tgz", + "integrity": "sha512-lobG0d7aOfQRXh8AyklEAgZGvA4FShxo6xQbUrrT/cNBPUdIDojlokwJsQyCC/eKia7ifqM0yP+2DRZ4WKw2RQ==", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.3.tgz", + "integrity": "sha512-sBGdETxC+/M4o/zKC0sl6sjWv62WFR/uzxrJ6uYyMLZOUlPnwzw0tKgVHOXxaAd5l2g8pEDM5RZ495GPQI77kg==", "dependencies": { - "@types/babel-types": "*" + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/accepts": { @@ -47,9 +75,9 @@ } }, "node_modules/acorn": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", - "integrity": "sha512-fu2ygVGuMmlzG8ZeRJ0bvR41nsAkxxhbyk8bZ1SS521Z7vmgJFTQQlfz/Mp/nJexGBz+v8sC9bM6+lNgskt4Ug==", + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "bin": { "acorn": "bin/acorn" }, @@ -57,35 +85,6 @@ "node": ">=0.4.0" } }, - "node_modules/acorn-globals": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-3.1.0.tgz", - "integrity": "sha512-uWttZCk96+7itPxK8xCzY86PnxKTMrReKDqrHzv42VQY0K30PUO8WY13WMOuI+cOdX4EIdzdvQ8k6jkuGRFMYw==", - "dependencies": { - "acorn": "^4.0.4" - } - }, - "node_modules/align-text": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", - "integrity": "sha512-GrTZLRpmp6wIC2ztrWW9MjjTgSKccffgFagbNDOX95/dcjEcYZibYTeaOntySQLcdw1ztBoFkviiUvTMbb9MYg==", - "dependencies": { - "kind-of": "^3.0.2", - "longest": "^1.0.1", - "repeat-string": "^1.5.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==", - "engines": { - "node": ">=0.4.2" - } - }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -108,32 +107,35 @@ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" }, - "node_modules/babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==", + "node_modules/assert-never": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.2.1.tgz", + "integrity": "sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/axios": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.3.4.tgz", + "integrity": "sha512-toYm+Bsyl6VC5wSkfkbbNB6ROv7KY93PEBBL6xyDczaIHasAiv4wPqQ/c4RjoQzipxRD2W5g21cOqQulZ7rHwQ==", "dependencies": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" } }, - "node_modules/babel-types": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha512-zhe3V/26rCWsEZK8kZN+HaQj5yQ1CilTObixFzKW1UWjqG7618Twz6YEsCnjfg5gBcJh02DrpCkS9h98ZqDY+g==", + "node_modules/babel-walk": { + "version": "3.0.0-canary-5", + "resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz", + "integrity": "sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==", "dependencies": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" - } - }, - "node_modules/babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", - "bin": { - "babylon": "bin/babylon.js" + "@babel/types": "^7.9.6" + }, + "engines": { + "node": ">= 10.0.0" } }, "node_modules/basic-auth": { @@ -156,21 +158,76 @@ } }, "node_modules/body-parser": { - "version": "1.18.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", - "integrity": "sha512-YQyoqQG3sO8iCmf8+hyVpgHHOv0/hCEFiS4zTGUwTA1HjAFX66wRcNQrVCeJq9pgESMRvUAOvSil5MJlmccuKQ==", + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", "dependencies": { - "bytes": "3.0.0", + "bytes": "3.1.2", "content-type": "~1.0.4", "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "~1.6.3", - "iconv-lite": "0.4.23", - "on-finished": "~2.3.0", - "qs": "6.5.2", - "raw-body": "2.3.3", - "type-is": "~1.6.16" + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/body-parser/node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/body-parser/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "engines": { "node": ">= 0.8" } @@ -187,9 +244,9 @@ } }, "node_modules/bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "engines": { "node": ">= 0.8" } @@ -206,26 +263,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/camelcase": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", - "integrity": "sha512-wzLkDa4K/mzI1OSITC+DUyjgIl/ETNHE9QvYgy6J6Jvqyyz4C0Xfd+lQhb19sX2jMpZV4IssUn0VDVmglV+s4g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/center-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", - "integrity": "sha512-Baz3aNe2gd2LP2qk5U+sDk/m4oSuwSDcBfayTCTBoWpfIGO5XFxPmjILQII4NGiZjD6DoDI6kf7gKaxkf7s3VQ==", - "dependencies": { - "align-text": "^0.1.3", - "lazy-cache": "^1.0.3" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/character-parser": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz", @@ -260,61 +297,56 @@ "fsevents": "~2.3.2" } }, - "node_modules/clean-css": { - "version": "3.4.28", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-3.4.28.tgz", - "integrity": "sha512-aTWyttSdI2mYi07kWqHi24NUU9YlELFKGOAgFzZjDN1064DMAOy2FBuoyGmkKRlXkbpXd0EVHmiVkbKhKoirTw==", + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dependencies": { - "commander": "2.8.x", - "source-map": "0.4.x" - }, - "bin": { - "cleancss": "bin/cleancss" + "delayed-stream": "~1.0.0" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cliui": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", - "integrity": "sha512-GIOYRizG+TGoc7Wgc1LiOTLare95R3mzKgoln+Q/lE4ceiYH19gUpl0l0Ffq4lJDEf3FxujMe6IBfOCs7pfqNA==", - "dependencies": { - "center-align": "^0.1.1", - "right-align": "^0.1.1", - "wordwrap": "0.0.2" - } - }, - "node_modules/commander": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz", - "integrity": "sha512-+pJLBFVk+9ZZdlAOB5WuIElVPPth47hILFkmGym57aq8kwxsowvByvB0DHs1vQAhyMZzdcpTtF0VDKGkSDR4ZQ==", - "dependencies": { - "graceful-readlink": ">= 1.0.0" - }, - "engines": { - "node": ">= 0.6.x" + "node": ">= 0.8" } }, "node_modules/constantinople": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-3.1.2.tgz", - "integrity": "sha512-yePcBqEFhLOqSBtwYOGGS1exHo/s1xjekXiinh4itpNQGCu4KA1euPh1fg07N2wMITZXQkBz75Ntdt1ctGZouw==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz", + "integrity": "sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==", "dependencies": { - "@types/babel-types": "^7.0.0", - "@types/babylon": "^6.16.2", - "babel-types": "^6.26.0", - "babylon": "^6.18.0" + "@babel/parser": "^7.6.0", + "@babel/types": "^7.6.1" } }, "node_modules/content-disposition": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", - "integrity": "sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==", + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, "engines": { "node": ">= 0.6" } }, + "node_modules/content-disposition/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/content-type": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", @@ -348,13 +380,6 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, - "node_modules/core-js": { - "version": "2.6.12", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", - "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", - "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.", - "hasInstallScript": true - }, "node_modules/cors": { "version": "2.8.5", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", @@ -375,12 +400,12 @@ "ms": "2.0.0" } }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "engines": { - "node": ">=0.10.0" + "node": ">=0.4.0" } }, "node_modules/depd": { @@ -392,9 +417,13 @@ } }, "node_modules/destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha512-3NdhDuEXnfun/z7x9GOElY49LoqVHoGScmOKwmxhsS8N5Y+Z8KyPPDnaSzqWgYt/ji4mqwfTS34Htrk0zPIXVg==" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } }, "node_modules/doctypes": { "version": "1.1.0", @@ -419,14 +448,6 @@ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", @@ -436,38 +457,39 @@ } }, "node_modules/express": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz", - "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==", + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", "dependencies": { - "accepts": "~1.3.5", + "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.18.3", - "content-disposition": "0.5.2", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.3.1", + "cookie": "0.5.0", "cookie-signature": "1.0.6", "debug": "2.6.9", - "depd": "~1.1.2", + "depd": "2.0.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "1.1.1", + "finalhandler": "1.2.0", "fresh": "0.5.2", + "http-errors": "2.0.0", "merge-descriptors": "1.0.1", "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.4", - "qs": "6.5.2", - "range-parser": "~1.2.0", - "safe-buffer": "5.1.2", - "send": "0.16.2", - "serve-static": "1.13.2", - "setprototypeof": "1.1.0", - "statuses": "~1.4.0", - "type-is": "~1.6.16", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" }, @@ -476,13 +498,84 @@ } }, "node_modules/express/node_modules/cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha512-+IJOX0OqlHCszo2mBUq+SrEbCj6w7Kpffqx60zYbPTFaO4+yYgRjHwcZNpWvaTylDHaV7PPmBHzSecZiMhtPgw==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", "engines": { "node": ">= 0.6" } }, + "node_modules/express/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express/node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express/node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/express/node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/express/node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/express/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -495,22 +588,73 @@ } }, "node_modules/finalhandler": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", - "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", "dependencies": { "debug": "2.6.9", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.2", - "statuses": "~1.4.0", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", "unpipe": "~1.0.0" }, "engines": { "node": ">= 0.8" } }, + "node_modules/finalhandler/node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -569,11 +713,6 @@ "node": ">= 6" } }, - "node_modules/graceful-readlink": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", - "integrity": "sha512-8tLu60LgxF6XpdbK8OW3FA+IfTNBn1ZHGHKF4KQbEeSkajYw5PlYJcKluntgegDPTg8UkHjpet1T82vk6TQ68w==" - }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -625,9 +764,9 @@ } }, "node_modules/iconv-lite": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", - "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -664,11 +803,6 @@ "node": ">=8" } }, - "node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, "node_modules/is-core-module": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", @@ -681,12 +815,12 @@ } }, "node_modules/is-expression": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-3.0.0.tgz", - "integrity": "sha512-vyMeQMq+AiH5uUnoBfMTwf18tO3bM6k1QXBE9D6ueAAquEfCZe3AJPtud9g6qS0+4X8xA7ndpZiDyeb2l2qOBw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-4.0.0.tgz", + "integrity": "sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==", "dependencies": { - "acorn": "~4.0.2", - "object-assign": "^4.0.1" + "acorn": "^7.1.1", + "object-assign": "^4.1.1" } }, "node_modules/is-extglob": { @@ -750,38 +884,6 @@ "promise": "^7.0.1" } }, - "node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/lazy-cache": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", - "integrity": "sha512-RE2g0b5VGZsOCFOCgP7omTRYFqydmZkBwl5oNnQ1lDYC57uyO9KqNnNVxT7COSHTxrRCWVcAVOcbjk+tvh/rgQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/longest": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", - "integrity": "sha512-k+yt5n3l48JU4k8ftnKG6V7u32wyH2NfKzeMto9F/QRE0amxy/LayxwlvjjkZEIzqR+19IrtFO8p5kB9QaYUFg==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -804,11 +906,14 @@ } }, "node_modules/mime": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", - "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "bin": { "mime": "cli.js" + }, + "engines": { + "node": ">=4" } }, "node_modules/mime-db": { @@ -874,6 +979,14 @@ "node": ">=0.10.0" } }, + "node_modules/object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", @@ -942,126 +1055,135 @@ "node": ">= 0.10" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/pug": { - "version": "2.0.0-beta11", - "resolved": "https://registry.npmjs.org/pug/-/pug-2.0.0-beta11.tgz", - "integrity": "sha512-iV0ibDCWLJGw8eEtBKAqbJZecOabQa6hpFeH+GCBzsAsCNSvpjo4wuHMPcmqtaZhxoO3ElbMePf8jkrM9TKulw==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.2.tgz", + "integrity": "sha512-bp0I/hiK1D1vChHh6EfDxtndHji55XP/ZJKwsRqrz6lRia6ZC2OZbdAymlxdVFwd1L70ebrVJw4/eZ79skrIaw==", "dependencies": { - "pug-code-gen": "^1.1.1", - "pug-filters": "^2.1.1", - "pug-lexer": "^3.0.0", - "pug-linker": "^2.0.2", - "pug-load": "^2.0.5", - "pug-parser": "^2.0.2", - "pug-runtime": "^2.0.3", - "pug-strip-comments": "^1.0.2" + "pug-code-gen": "^3.0.2", + "pug-filters": "^4.0.0", + "pug-lexer": "^5.0.1", + "pug-linker": "^4.0.0", + "pug-load": "^3.0.0", + "pug-parser": "^6.0.0", + "pug-runtime": "^3.0.1", + "pug-strip-comments": "^2.0.0" } }, "node_modules/pug-attrs": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-2.0.4.tgz", - "integrity": "sha512-TaZ4Z2TWUPDJcV3wjU3RtUXMrd3kM4Wzjbe3EWnSsZPsJ3LDI0F3yCnf2/W7PPFF+edUFQ0HgDL1IoxSz5K8EQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-3.0.0.tgz", + "integrity": "sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==", "dependencies": { - "constantinople": "^3.0.1", - "js-stringify": "^1.0.1", - "pug-runtime": "^2.0.5" + "constantinople": "^4.0.1", + "js-stringify": "^1.0.2", + "pug-runtime": "^3.0.0" } }, "node_modules/pug-code-gen": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-1.1.1.tgz", - "integrity": "sha512-UwZaJVhjhy2kYntLqXjSV1ae+K96ve6bG+N5bLFfA6yyGJTEkguct19MWDyUM9D8CDU3NNxVctUAh5McF19E6w==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.2.tgz", + "integrity": "sha512-nJMhW16MbiGRiyR4miDTQMRWDgKplnHyeLvioEJYbk1RsPI3FuA3saEP8uwnTb2nTJEKBU90NFVWJBk4OU5qyg==", "dependencies": { - "constantinople": "^3.0.1", + "constantinople": "^4.0.1", "doctypes": "^1.1.0", - "js-stringify": "^1.0.1", - "pug-attrs": "^2.0.2", - "pug-error": "^1.3.2", - "pug-runtime": "^2.0.3", - "void-elements": "^2.0.1", - "with": "^5.0.0" + "js-stringify": "^1.0.2", + "pug-attrs": "^3.0.0", + "pug-error": "^2.0.0", + "pug-runtime": "^3.0.0", + "void-elements": "^3.1.0", + "with": "^7.0.0" } }, "node_modules/pug-error": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-1.3.3.tgz", - "integrity": "sha512-qE3YhESP2mRAWMFJgKdtT5D7ckThRScXRwkfo+Erqga7dyJdY3ZquspprMCj/9sJ2ijm5hXFWQE/A3l4poMWiQ==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.0.0.tgz", + "integrity": "sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ==" }, "node_modules/pug-filters": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-2.1.5.tgz", - "integrity": "sha512-xkw71KtrC4sxleKiq+cUlQzsiLn8pM5+vCgkChW2E6oNOzaqTSIBKIQ5cl4oheuDzvJYCTSYzRaVinMUrV4YLQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-4.0.0.tgz", + "integrity": "sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==", "dependencies": { - "clean-css": "^3.3.0", - "constantinople": "^3.0.1", + "constantinople": "^4.0.1", "jstransformer": "1.0.0", - "pug-error": "^1.3.2", - "pug-walk": "^1.1.5", - "resolve": "^1.1.6", - "uglify-js": "^2.6.1" + "pug-error": "^2.0.0", + "pug-walk": "^2.0.0", + "resolve": "^1.15.1" } }, "node_modules/pug-lexer": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-3.1.0.tgz", - "integrity": "sha512-DxXOrmCIDVEwzN2ozZBK1t4QRTR6pLv5YkqM6dLdaSHnm+LJJRBngVn4IDMMBZQR9xUpxrRm9rffmku2OEqkJw==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-5.0.1.tgz", + "integrity": "sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==", "dependencies": { - "character-parser": "^2.1.1", - "is-expression": "^3.0.0", - "pug-error": "^1.3.2" + "character-parser": "^2.2.0", + "is-expression": "^4.0.0", + "pug-error": "^2.0.0" } }, "node_modules/pug-linker": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-2.0.3.tgz", - "integrity": "sha512-ZqKljvFUl1K5L4G5WABJ5FUYWOY0K2AXLmwj2QfM7nPCUcxfsmr05SikjgXGXVoIrygGzM/iWSsXwnkWId4AHw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-4.0.0.tgz", + "integrity": "sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==", "dependencies": { - "pug-error": "^1.3.2", - "pug-walk": "^1.1.2" + "pug-error": "^2.0.0", + "pug-walk": "^2.0.0" } }, "node_modules/pug-load": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-2.0.12.tgz", - "integrity": "sha512-UqpgGpyyXRYgJs/X60sE6SIf8UBsmcHYKNaOccyVLEuT6OPBIMo6xMPhoJnqtB3Q3BbO4Z3Bjz5qDsUWh4rXsg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-3.0.0.tgz", + "integrity": "sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==", "dependencies": { - "object-assign": "^4.1.0", - "pug-walk": "^1.1.8" + "object-assign": "^4.1.1", + "pug-walk": "^2.0.0" } }, "node_modules/pug-parser": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-2.0.2.tgz", - "integrity": "sha512-PW8kKDLN07MbFljR/GaYHPBGW+64YldtFFZUEGltJ67RRzebI/DxZy4njlxacy9JeheosyVprZ9C5DIexG1D/Q==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-6.0.0.tgz", + "integrity": "sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==", "dependencies": { - "pug-error": "^1.3.2", - "token-stream": "0.0.1" + "pug-error": "^2.0.0", + "token-stream": "1.0.0" } }, "node_modules/pug-runtime": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-2.0.5.tgz", - "integrity": "sha512-P+rXKn9un4fQY77wtpcuFyvFaBww7/91f3jHa154qU26qFAnOe6SW1CbIDcxiG5lLK9HazYrMCCuDvNgDQNptw==" + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-3.0.1.tgz", + "integrity": "sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==" }, "node_modules/pug-strip-comments": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-1.0.4.tgz", - "integrity": "sha512-i5j/9CS4yFhSxHp5iKPHwigaig/VV9g+FgReLJWWHEHbvKsbqL0oP/K5ubuLco6Wu3Kan5p7u7qk8A4oLLh6vw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz", + "integrity": "sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==", "dependencies": { - "pug-error": "^1.3.3" + "pug-error": "^2.0.0" } }, "node_modules/pug-walk": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-1.1.8.tgz", - "integrity": "sha512-GMu3M5nUL3fju4/egXwZO0XLi6fW/K3T3VTgFQ14GxNi8btlxgT5qZL//JwZFm/2Fa64J/PNS8AZeys3wiMkVA==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-2.0.0.tgz", + "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==" }, "node_modules/qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dependencies": { + "side-channel": "^1.0.4" + }, "engines": { "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/range-parser": { @@ -1073,19 +1195,60 @@ } }, "node_modules/raw-body": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", - "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", "dependencies": { - "bytes": "3.0.0", - "http-errors": "1.6.3", - "iconv-lite": "0.4.23", + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", "unpipe": "1.0.0" }, "engines": { "node": ">= 0.8" } }, + "node_modules/raw-body/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/raw-body/node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/raw-body/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -1097,19 +1260,6 @@ "node": ">=8.10.0" } }, - "node_modules/regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" - }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", - "engines": { - "node": ">=0.10" - } - }, "node_modules/resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", @@ -1126,17 +1276,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/right-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", - "integrity": "sha512-yqINtL/G7vs2v+dFIZmFUDbnVyFUJFKd6gK22Kgo6R4jfJGFtisKyncWDDULgjfqf4ASQuIQyjJ7XZ+3aWpsAg==", - "dependencies": { - "align-text": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -1164,37 +1303,94 @@ } }, "node_modules/send": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", - "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", "dependencies": { "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", + "depd": "2.0.0", + "destroy": "1.2.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "~1.6.2", - "mime": "1.4.1", - "ms": "2.0.0", - "on-finished": "~2.3.0", - "range-parser": "~1.2.0", - "statuses": "~1.4.0" + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" }, "engines": { "node": ">= 0.8.0" } }, + "node_modules/send/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/send/node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/send/node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/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/send/node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/send/node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/send/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/serve-static": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", - "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", "dependencies": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", - "parseurl": "~1.3.2", - "send": "0.16.2" + "parseurl": "~1.3.3", + "send": "0.18.0" }, "engines": { "node": ">= 0.8.0" @@ -1205,15 +1401,17 @@ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" }, - "node_modules/source-map": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", - "integrity": "sha512-Y8nIfcb1s/7DcobUz1yOO1GSp7gyL+D9zLHDehT7iRESqGSxjJ448Sg7rvfgsRJCnKLdSl11uGf0s9X80cH0/A==", + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", "dependencies": { - "amdefine": ">=0.0.4" + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" }, - "engines": { - "node": ">=0.8.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/source-map-js": { @@ -1244,11 +1442,11 @@ } }, "node_modules/to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha512-lxrWP8ejsq+7E3nNjwYmUBMAgjMTZoTI+sdBOpvNyijeDLa29LUn9QaoXAHv4+Z578hbmHHJKZknzxVtvo77og==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, "node_modules/to-regex-range": { @@ -1262,10 +1460,18 @@ "node": ">=8.0" } }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, "node_modules/token-stream": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-0.0.1.tgz", - "integrity": "sha512-nfjOAu/zAWmX9tgwi5NRp7O7zTDUD1miHiB40klUnAh9qnL1iXdgzcz/i5dMaL5jahcBAaSfmNOBBJBLJW8TEg==" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-1.0.0.tgz", + "integrity": "sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg==" }, "node_modules/type-is": { "version": "1.6.18", @@ -1279,38 +1485,6 @@ "node": ">= 0.6" } }, - "node_modules/uglify-js": { - "version": "2.8.29", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", - "integrity": "sha512-qLq/4y2pjcU3vhlhseXGGJ7VbFO4pBANu0kwl8VCa9KEI0V8VfZIx2Fy3w01iSTA/pGwKZSmu/+I4etLNDdt5w==", - "dependencies": { - "source-map": "~0.5.1", - "yargs": "~3.10.0" - }, - "bin": { - "uglifyjs": "bin/uglifyjs" - }, - "engines": { - "node": ">=0.8.0" - }, - "optionalDependencies": { - "uglify-to-browserify": "~1.0.0" - } - }, - "node_modules/uglify-js/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/uglify-to-browserify": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", - "integrity": "sha512-vb2s1lYx2xBtUgy+ta+b2J/GLVUR+wmpINwHePmPRhOsIVCG2wDzKJ0n14GslH1BifsqVzSOwQhRaCAsZ/nI4Q==", - "optional": true - }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -1336,58 +1510,25 @@ } }, "node_modules/void-elements": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", - "integrity": "sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", + "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==", "engines": { "node": ">=0.10.0" } }, - "node_modules/window-size": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", - "integrity": "sha512-1pTPQDKTdd61ozlKGNCjhNRd+KPmgLSGa3mZTHoOliaGcESD8G1PXhh7c1fgiPjVbNVfgy2Faw4BI8/m0cC8Mg==", - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/with": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/with/-/with-5.1.1.tgz", - "integrity": "sha512-uAnSsFGfSpF6DNhBXStvlZILfHJfJu4eUkfbRGk94kGO1Ta7bg6FwfvoOhhyHAJuFbCw+0xk4uJ3u57jLvlCJg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/with/-/with-7.0.2.tgz", + "integrity": "sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==", "dependencies": { - "acorn": "^3.1.0", - "acorn-globals": "^3.0.0" - } - }, - "node_modules/with/node_modules/acorn": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha512-OLUyIIZ7mF5oaAUT1w0TFqQS81q3saT46x8t7ukpPjMNk+nbs4ZHhs7ToV8EWnLYLepjETXd4XaCE4uxkMeqUw==", - "bin": { - "acorn": "bin/acorn" + "@babel/parser": "^7.9.6", + "@babel/types": "^7.9.6", + "assert-never": "^1.2.1", + "babel-walk": "3.0.0-canary-5" }, "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/wordwrap": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", - "integrity": "sha512-xSBsCeh+g+dinoBv3GAOWM4LcVVO68wLXRanibtBSdUvkGWQRGeE9P7IwU9EmDDi4jA6L44lz15CGMwdw9N5+Q==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/yargs": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", - "integrity": "sha512-QFzUah88GAGy9lyDKGBqZdkYApt63rCXYBGYnEP4xDJPXNqXXnBDACnbrXnViV6jRSqAePwrATi2i8mfYm4L1A==", - "dependencies": { - "camelcase": "^1.0.2", - "cliui": "^2.1.0", - "decamelize": "^1.0.0", - "window-size": "0.1.0" + "node": ">= 10.0.0" } } } diff --git a/package.json b/package.json index 1a97600..708a80b 100644 --- a/package.json +++ b/package.json @@ -11,13 +11,14 @@ "www": "./bin/www.js" }, "dependencies": { + "axios": "^1.3.4", "cookie-parser": "~1.4.4", "cors": "^2.8.5", "debug": "~2.6.9", - "express": "~4.16.1", + "express": "^4.18.2", "http-errors": "~1.6.3", "morgan": "~1.9.1", - "pug": "2.0.0-beta11", + "pug": "^3.0.2", "sass": "^1.58.3" } } diff --git a/public/javascripts/chart_dayavg.js b/public/javascripts/chart_dayavg.js new file mode 100644 index 0000000..e8056a0 --- /dev/null +++ b/public/javascripts/chart_dayavg.js @@ -0,0 +1,134 @@ +// Sh0w the hour average chart +import {logit, logerror} from './logit.js' +import * as utils from './chart_utilities.js' +import {DateTime, Duration} from "./luxon.min.js" + +// ****************************************************************** +// PlotDayAVG_Noise +// ****************************************************************** + + +export const showDayavg = async (params) => { + await PlotDayAVG_Noise(params.sid) +} + + +const PlotDayAVG_Noise = async function (sid) { + + let series1 = [] + let series2 = [] + + // read the data from the server + const url = `${utils.url}/getsensordata?sensorid=${sid}&data=davg` + let ret = await fetch(url) + .catch(e => { + logerror(e) + }) + let data = await ret.json() + if(!data.err) { + // Put values into the serieses + let cnt = 0 + data.values.forEach((x) => { + if(x.n_AVG != -1) { + let dat = new Date(x.datetime).getTime() // retrieve the date + series1.push([dat, x.n_AVG]) + series2.push([dat, x.peakcount]) + } + }) + } else { + utils.showError(data.err) + } + let dlt = DateTime.now() // retrieve the date + dlt = dlt.minus({day:30}) + + // Plot-Options + let options = utils.createGlobObtions() + options.xAxis.plotBands = utils.calcWeekends(data, true) + options.xAxis.tickInterval = 24 * 3600 * 1000 + options.xAxis.title = 'Date' + options.xAxis.labels = { + formatter: function () { + return this.axis.defaultLabelFormatter.call(this); + } + } + + options.chart.type = 'column' + options.yAxis = { + title: { + text: 'dbA', + useHTML: true, + }, + min: utils.noise_ymin, + tickAmount: 10, + gridLineColor: 'lightgray', + } + options.series = [ + { + name: 'Mean value LAeq', + data: series1, + color: utils.colors.eq, + type: 'column', + zIndex: 2, + }, + ] + options.plotOptions.column = { + pointWidth: 20, + groupPadding: 0.1 + } + options.title.text = 'Noise daily mean values' + options.subtitle.text = 'Daily mean values of LAeq for each full day
 ' + options.subtitle.useHTML = true + options.chart.zoomType = 'x' + options.chart.resetZoomButton= { + position: { + align: 'left', +// verticalAlign: 'bottom', + x: 20, + y: 300, + }, + relativeTo: 'chart' + } + options.tooltip.formatter = function () { + let y = Math.round(this.y * 10) / 10 + return '
' + + DateTime.fromMillis(this.x, {zone: 'utc'}).toFormat("dd.LL") + '
' + + '● ' + + this.series.name + ':  ' + y + '
' + } + + + // Do PLOT 1 + let ch = Highcharts.chart('dday', options, function (chart) { + utils.addSensorID2chart(chart, {sid: data.sid, indoor: data.indoor}, document.getElementById('dday').offsetWidth) + }) +/* + // Do PLOT 2 + options.series[0] = { + name: 'Peaks', + data: series2, + color: utils.colors.peaks, + type: 'column' + } + options.title.text = 'Peaks more than ' + data.peak + ' dbA' + options.subtitle.text = 'Number of exceedances per hour
 ' + options.yAxis = { + title: { + text: 'Counts', + useHTML: true, + }, + tickAmount: 10, + allowDecimals: false, + gridLineColor: 'lightgray', + } + options.tooltip.formatter = function () { + let y = Math.round(this.y) + return '
' + + DateTime.fromMillis(this.x, {zone: 'utc'}).toFormat("dd.LL - HH'h'") + '
' + + '● ' + + this.series.name + ':  ' + y + '
' + } + + let ch1 = Highcharts.chart('dpeak', options) +*/ +} + diff --git a/public/javascripts/chart_daynight.js b/public/javascripts/chart_daynight.js new file mode 100644 index 0000000..03c9861 --- /dev/null +++ b/public/javascripts/chart_daynight.js @@ -0,0 +1,160 @@ +// Sh0w the hour average chart +import {logit, logerror} from './logit.js' +import * as utils from './chart_utilities.js' +import {DateTime, Duration} from "./luxon.min.js" + +// ****************************************************************** +// PlotDayNightAVG_Noise +// ****************************************************************** + + +export const showDaynight = async (params) => { + await PlotDayNight_Noise(params.sid) +} + + +const PlotDayNight_Noise = async function (sid) { + + let series1 = [] + let series2 = [] + + // read the data from the server + const url = `${utils.url}/getsensordata?sensorid=${sid}&data=daynight` + let ret = await fetch(url) + .catch(e => { + logerror(e) + }) + let data = await ret.json() + + if(!data.err) { + // Put values into the serieses + let cnt = 0 + data.values.forEach((x) => { + if(x.n_AVG != -1) { + let dat = new Date(x.datetime).getTime() // retrieve the date + series1.push([dat, x.n_dayAVG]) + series2.push([dat, x.n_nightAVG]) + } + }) + } else { + utils.showError(data.err) + } + let dlt = DateTime.now() // retrieve the date + dlt = dlt.minus({day:30}) + + // Plot-Options + let options = utils.createGlobObtions() + options.xAxis.plotBands = utils.calcWeekends(data, true) + options.xAxis.tickInterval = 24 * 3600 * 1000 + options.xAxis.title = 'Date' + options.xAxis.labels = { + formatter: function () { + return this.axis.defaultLabelFormatter.call(this); + } + } + + options.chart.type = 'column' + options.yAxis = { + title: { + text: 'dbA', + useHTML: true, + }, + min: utils.noise_ymin, + tickAmount: 10, + gridLineColor: 'lightgray', + } + options.series = [ + { + name: 'Day', + data: series1, + color: utils.colors.eq, + type: 'column', + zIndex: 2, + }, + { + name: 'Night', + data: series2, + color: utils.colors.max, + type: 'column', + zIndex: 2, + }, + ] + options.plotOptions.series = { + animation: false + } + options.plotOptions.column = { + pointWidth: 20, + groupPadding: 0.3 + } + options.title.text = 'Noise Average values during the day and night hours' + options.subtitle.text = 'Daily mean values of LAeq from 6h00 to 22h00
Nightly mean values of LAeq from 22h00 to 6h00' + options.subtitle.useHTML = true + options.chart.zoomType = 'x' + options.chart.resetZoomButton= { + position: { + align: 'left', +// verticalAlign: 'bottom', + x: 20, + y: 300, + }, + relativeTo: 'chart' + } + options.tooltip.formatter = function () { + let n = this.series.name.startsWith('Night') + let d = DateTime.fromMillis(this.x, {zone: 'utc'}) + let d1 = d.plus({days: 1}) + let txt = n ? d.toFormat('dd') + '/' + d1.toFormat('dd.LL') : + d.toFormat('dd.LL') + return '
' + + '  ' + txt + '
' + + '● ' + + this.series.name + ':  ' + + Highcharts.numberFormat(this.y, 1) + + '
'; + } + +/* + formatter = function () { + let y = Math.round(this.y * 10) / 10 + return '
' + + DateTime.fromMillis(this.x, {zone: 'utc'}).toFormat("dd.LL") + '
' + + '● ' + + this.series.name + ':  ' + y + '
' + } +*/ + + // Do PLOT 1 + let ch = Highcharts.chart('ddaynight', options, function (chart) { + utils.addSensorID2chart(chart, {sid: data.sid, indoor: data.indoor}, document.getElementById('ddaynight').offsetWidth) + }) +/* + // Do PLOT 2 + options.series[0] = { + name: 'Peaks', + data: series2, + color: utils.colors.peaks, + type: 'column' + } + options.title.text = 'Peaks more than ' + data.peak + ' dbA' + options.subtitle.text = 'Number of exceedances per hour
 ' + options.yAxis = { + title: { + text: 'Counts', + useHTML: true, + }, + tickAmount: 10, + allowDecimals: false, + gridLineColor: 'lightgray', + } + options.tooltip.formatter = function () { + let y = Math.round(this.y) + return '
' + + DateTime.fromMillis(this.x, {zone: 'utc'}).toFormat("dd.LL - HH'h'") + '
' + + '● ' + + this.series.name + ':  ' + y + '
' + } + + let ch1 = Highcharts.chart('dpeak', options) +*/ +} + diff --git a/public/javascripts/chart_houravg.js b/public/javascripts/chart_houravg.js new file mode 100644 index 0000000..b1a48cb --- /dev/null +++ b/public/javascripts/chart_houravg.js @@ -0,0 +1,129 @@ +// Sh0w the hour average chart +import {logit, logerror} from './logit.js' +import * as utils from './chart_utilities.js' +import {DateTime, Duration} from "./luxon.min.js" + +// ****************************************************************** +// PlotHourAVG_Noise +// ****************************************************************** + + +export const showHouravg = async (params) => { + await PlotHourAVG_Noise(params.sid) +} + + +const PlotHourAVG_Noise = async function (sid) { + + let series1 = [] + let series2 = [] + + // read the data from the server + const url = `${utils.url}/getsensordata?sensorid=${sid}&data=havg` + let ret = await fetch(url) + .catch(e => { + logerror(e) + }) + let data = await ret.json() + + if(!data.err) { + + // Put values into the serieses + let cnt = 0 + data.values.forEach((x) => { + if (x.n_AVG != -1) { + let dat = new Date(x.datetime).getTime() // retrieve the date + series1.push([dat, x.n_AVG]) + series2.push([dat, x.peakcount]) + } + }) + } else { + utils.showError(data.err) + } + let dlt = DateTime.now() // retrieve the date + dlt = dlt.minus({day:1}) + + // Plot-Options + let options = utils.createGlobObtions() + options.xAxis.tickInterval = 6 * 3600 * 1000 + options.xAxis.plotBands = utils.calcWeekends(data, true) + options.xAxis.minTickInterval = 3600 * 1000 + + options.yAxis = { + title: { + text: 'dbA', + useHTML: true, + }, + min: utils.noise_ymin, + tickAmount: 10, + gridLineColor: 'lightgray', + } + options.series = [ + { + name: 'Mean value LAeq', + data: series1, + color: utils.colors.eq, + type: 'column', + zIndex: 2, + }, + ] + options.plotOptions.column = { + pointWidth: 8, + groupPadding: 0.5 + } + options.title.text = 'Noise hourly mean values' + options.subtitle.text = 'Hourly mean values of LAeq for each full hour
 ' + options.subtitle.useHTML = true + options.chart.zoomType = 'x' + options.chart.height = 350 + options.chart.resetZoomButton= { + position: { + align: 'left', +// verticalAlign: 'bottom', + x: 20, + y: 300, + }, + relativeTo: 'chart' + } + options.tooltip.formatter = function () { + let y = Math.round(this.y * 10) / 10 + return '
' + + DateTime.fromMillis(this.x, {zone: 'utc'}).toFormat("dd.LL - HH'h'") + '
' + + '● ' + + this.series.name + ':  ' + y + '
' + } + + + // Do PLOT 1 + let ch = Highcharts.chart('dhour', options, function (chart) { + utils.addSensorID2chart(chart, {sid: data.sid, indoor: data.indoor}, document.getElementById('dhour').offsetWidth) + }) + // Do PLOT 2 + options.series[0] = { + name: 'Peaks', + data: series2, + color: utils.colors.peaks, + type: 'column' + } + options.title.text = 'Peaks more than ' + data.peak + ' dbA' + options.subtitle.text = 'Number of exceedances per hour
 ' + options.yAxis = { + title: { + text: 'Counts', + useHTML: true, + }, + tickAmount: 10, + allowDecimals: false, + gridLineColor: 'lightgray', + } + options.tooltip.formatter = function () { + let y = Math.round(this.y) + return '
' + + DateTime.fromMillis(this.x, {zone: 'utc'}).toFormat("dd.LL - HH'h'") + '
' + + '● ' + + this.series.name + ':  ' + y + '
' + } + + let ch1 = Highcharts.chart('dpeak', options) +} + diff --git a/public/javascripts/chart_lden.js b/public/javascripts/chart_lden.js new file mode 100644 index 0000000..38c60d3 --- /dev/null +++ b/public/javascripts/chart_lden.js @@ -0,0 +1,112 @@ +// Sh0w the hour average chart +import {logit, logerror} from './logit.js' +import * as utils from './chart_utilities.js' +import {DateTime, Duration} from "./luxon.min.js" + +// ****************************************************************** +// PlotLDEN_Noise +// ****************************************************************** + + +export const showLden = async (params) => { + await PlotLDEN_Noise(params.sid) +} + + +const PlotLDEN_Noise = async function (sid) { + + let series1 = [] + + // read the data from the server + const url = `${utils.url}/getsensordata?sensorid=${sid}&data=lden` + let ret = await fetch(url) + .catch(e => { + logerror(e) + }) + let data = await ret.json() + + if (!data.err) { + // Put values into the serieses + let cnt = 0 + data.values.forEach((x) => { + if(x.n_AVG != -1) { + let dat = new Date(x.datetime).getTime() // retrieve the date + series1.push([dat, x.lden]) + } + }) + } else { + utils.showError(data.err) + } + let dlt = DateTime.now() // retrieve the date + dlt = dlt.minus({day:30}) + + // Plot-Options + let options = utils.createGlobObtions() + + options.xAxis.plotBands = utils.calcWeekends(data, true) + options.xAxis.tickInterval = 24 * 3600 * 1000 + options.xAxis.title = 'Date' + options.xAxis.labels = { + formatter: function () { + let lbl = this.axis.defaultLabelFormatter.call(this); + this.value += 86400000; + let lbl1 = this.axis.defaultLabelFormatter.call(this); + return parseInt(lbl) + '/' + lbl1; + } + } + options.chart.type = 'column' + options.yAxis = { + title: { + text: 'dbA', + useHTML: true, + }, + min: utils.noise_ymin, + tickAmount: 10, + gridLineColor: 'lightgray', + } + options.series = [ + { + name: 'lden', + data: series1, + color: utils.colors.eq, + type: 'column', + zIndex: 2, + } + ] + options.plotOptions.series = { + animation: false + } + options.plotOptions.column = { + pointWidth: 20, + groupPadding: 0.1 + } + options.title.text = 'Noise LDEN-Index' + options.subtitle.text = 'Daily mean values of LDEN\-Index' + options.subtitle.useHTML = true + options.chart.zoomType = 'x' + options.chart.resetZoomButton= { + position: { + align: 'left', +// verticalAlign: 'bottom', + x: 20, + y: 300, + }, + relativeTo: 'chart' + } + options.tooltip.formatter = function () { + let d = DateTime.fromMillis(this.x, {zone: 'utc'}) + let d1 = d.plus({days: 1}) + let txt = d.toFormat('dd') + '/' + d1.toFormat('dd.LL') + return '
' + + '  ' + txt + '
' + + '● ' + + this.series.name + ':  ' + + Highcharts.numberFormat(this.y, 1) + + '
'; + } + + let ch = Highcharts.chart('dlden', options, function (chart) { + utils.addSensorID2chart(chart, {sid: data.sid, indoor: data.indoor}, document.getElementById('dlden').offsetWidth) + }) +} + diff --git a/public/javascripts/chart_live.js b/public/javascripts/chart_live.js index 7c4456c..74c2611 100644 --- a/public/javascripts/chart_live.js +++ b/public/javascripts/chart_live.js @@ -1,22 +1,18 @@ // Show the live data chart import {logit, logerror} from './logit.js' import * as utils from './chart_utilities.js' +import {DateTime} from "./luxon.min.js"; // ****************************************************************** // PlotDayLive_Noise // ****************************************************************** -let noise_ymin = 30; // lowest value on y-axis for noise -let noise_ymax = 120; // highest value on y-axis for noise -let activeTab = 0; // active TAB number -let peaklim = 70; // threshold for peak count - -export const showLive = (params) => { - PlotDayLive_Noise(37833) +export const showLive = async (params) => { + await PlotDayLive_Noise(params.sid) } -export const PlotDayLive_Noise = async (sid) => { +const PlotDayLive_Noise = async (sid) => { let series1 = [] let series2 = [] @@ -26,49 +22,54 @@ export const PlotDayLive_Noise = async (sid) => { let aktVal = {} // read the data from the server - const url = `http://localhost:3004/getsensordata?type=noise&sensorid=${sid}` + const url = `/api/getsensordata?&sensorid=${sid}` let ret = await fetch(url) .catch(e => { logerror(e) }); - let sensors = await ret.json() - let lastidx = sensors.count-1 - // Put values into the arrays - let cnt = 0 - sensors.values.forEach((x) => { - let dat = new Date(x.datetime).getTime() - series1.push([dat, x.noise_LAeq]) - series2.push([dat, x.noise_LA_max]) - series3.push([dat, x.noise_LA_min]) // put data and value into series array - }) + let data = await ret.json() - if (sensors.values.length != 0) { - // Aktuelle Werte speichern - aktVal['LAeq'] = sensors.values[lastidx].noise_LAeq - aktVal['LAMax'] = sensors.values[lastidx].noise_LA_max - aktVal['LAMin'] = sensors.values[lastidx].noise_LA_min + if(!data.err) { + let lastidx = data.count - 1 + // Put values into the arrays + let cnt = 0 + data.values.forEach((x) => { + let dat = new Date(x.datetime).getTime() + series1.push([dat, x.noise_LAeq]) + series2.push([dat, x.noise_LA_max]) + series3.push([dat, x.noise_LA_min]) // put data and value into series array + }) - // InfoTafel füllen - let infoTafel = - '' + - '' + - '' + - '' - infoTafel += - '' + - '' - infoTafel += - '' + - '' - infoTafel += - '
Aktuelle Werte
LAeq' + (aktVal.LAeq).toFixed(1) + 'dbA
LAmin' + (aktVal.LAMin).toFixed(0) + 'dbA
LAmax' + (aktVal.LAMax).toFixed(0) + 'dbA
' + - '' + if (data.values.length != 0) { + // Aktuelle Werte speichern + aktVal['LAeq'] = data.values[lastidx].noise_LAeq + aktVal['LAMax'] = data.values[lastidx].noise_LA_max + aktVal['LAMin'] = data.values[lastidx].noise_LA_min + + // InfoTafel füllen + let infoTafel = + '' + + '' + + '' + + '' + infoTafel += + '' + + '' + infoTafel += + '' + + '' + infoTafel += + '
Aktuelle Werte
LAeq' + (aktVal.LAeq).toFixed(1) + 'dbA
LAmin' + (aktVal.LAMin).toFixed(0) + 'dbA
LAmax' + (aktVal.LAMax).toFixed(0) + 'dbA
' + + '' + } + let txtMeldung = false + } else { + utils.showError(data.err) } - let txtMeldung = false // Plot-Options - let options = utils.createGlobObtions() + let options = utils.createGlobObtions('dd.LL HH:mm:ss') let series_LAeq = { name: 'LAeq', @@ -138,10 +139,11 @@ export const PlotDayLive_Noise = async (sid) => { color: 'black' } }, - max: noise_ymax, - min: noise_ymin, + max: utils.noise_ymax, +// min: utils.noise_ymin, + min: 20, // opposite: true, - tickAmount: 10, + tickAmount: 11, useHTML: true, } @@ -167,6 +169,13 @@ export const PlotDayLive_Noise = async (sid) => { }, relativeTo: 'chart' } + options.tooltip.formatter = function () { + let y = Math.round(this.y * 100) / 100 + return '
' + + DateTime.fromMillis(this.x, {zone: 'utc'}).toFormat("dd.LL - HH:mm:ss") + '
' + + '● ' + + this.series.name + ':  ' + y + '
' + } let noDataTafel = '
' + @@ -180,7 +189,7 @@ export const PlotDayLive_Noise = async (sid) => { let navtime = [-24, -12, 0, 12, 24] let chr = Highcharts.chart('dlive', options, function (chart) { - utils.addSensorID2chart(chart, sensors.props, document.getElementById('dlive').offsetWidth) + utils.addSensorID2chart(chart, {sid: data.sid, indoor: data.indoor}, document.getElementById('dlive').offsetWidth) // let breit = $(window).width() // let navx = breit-350 // chart.renderer.label( diff --git a/public/javascripts/chart_utilities.js b/public/javascripts/chart_utilities.js index 31cc58f..3879a15 100644 --- a/public/javascripts/chart_utilities.js +++ b/public/javascripts/chart_utilities.js @@ -13,15 +13,19 @@ let nbrofdaysforavg = 8; // Stundenmittel Anzahl Tagte (default = let nbrofdaysfordaynight = 30; // use 30 days or day/night graphic let stucols = 1; // Anzeige nur Balken (StundenMittel) +export const noise_ymin = 30; // lowest value on y-axis for noise +export const noise_ymax = 120; // highest value on y-axis for noise +let activeTab = 0; // active TAB number +export let peaklim = 70; // threshold for peak count + +export const url = '/api' export function createGlobObtions() { - var globObject = {}; - // Options, die für alle Plots identisch sind - globObject = { + let globObject = { chart: { height: 600, -// width: 1000; +// width: 1000, spacingRight: 20, spacingLeft: 20, spacingTop: 25, @@ -51,7 +55,7 @@ export function createGlobObtions() { useHTML: true, }, subtitle: { - text: 'Gemessene Werte und ' + avgTime + 'min-gleitende Mittelwerte', +// text: 'Gemessene Werte und ' + avgTime + 'min-gleitende Mittelwerte', align: 'left', }, tooltip: { @@ -60,14 +64,6 @@ export function createGlobObtions() { borderWidth: 0, borderRadius: 0, useHTML: true, - formatter: function () { - return '
' + - DateTime.fromMillis(this.x, {zone: 'utc'}).toFormat('dd.LL HH:mm:ss') + '
' + - '● ' + - this.series.name + ':  ' + - Highcharts.numberFormat(this.y, 1) + - '
'; - } }, xAxis: { type: 'datetime', @@ -106,16 +102,16 @@ export function createGlobObtions() { return globObject; } -function calcWeekends(data, isyear) { - var weekend = []; - var oldDay = 8; - for (var i = 0; i < data.length; i++) { - var mom = moment(data[i].date); +export function calcWeekends(data, isyear) { + let weekend = []; + let oldDay = 8; + for (let i = 0; i < data.length; i++) { + let mom = moment(data[i].date); if (isyear) { mom = moment(data[i]._id) } - var day = mom.day(); - var st = mom.startOf('day'); + let day = mom.day(); + let st = mom.startOf('day'); if (day != oldDay) { if (day == 6) { weekend.push({ @@ -138,21 +134,21 @@ function calcWeekends(data, isyear) { return weekend; } -function calcDays(data, isyear) { - var days = []; +export function calcDays(data, isyear) { + let days = []; if (data.length == 0) { return days } - var oldday = moment(data[0].date).day(); + let oldday = moment(data[0].date).day(); if (isyear) { oldday = moment(data[0]._id).day(); } - for (var i = 0; i < data.length; i++) { - var m = moment(data[i].date); + for (let i = 0; i < data.length; i++) { + let m = moment(data[i].date); if (isyear) { m = moment(data[i]._id); } - var tag = m.day() + let tag = m.day() if (tag != oldday) { m.startOf('day'); days.push({color: 'lightgray', value: m.valueOf(), width: 1, zIndex: 2}); @@ -162,26 +158,12 @@ function calcDays(data, isyear) { return days; }; -function getIndoor(sensor) { - let p = new Promise(function (resolve, reject) { - let url = '/api/getdata?data=props&sensorid=' + sensor; - $.get(url, (data, err) => { - if (err != 'success') { - resolve(false) - } else { - resolve(data.values[0].indoor == 1) - } - }) - }) - return p -} - -export async function addSensorID2chart(chart, props, width) { +export async function addSensorID2chart(chart, sensor, width) { console.log('widht: ',width); - let indoor = props.location[0].indoor + let indoor =sensor.indoor console.log('indoor: ',indoor) let sens = chart.renderer.label( - `Sensor: ${props._id} ${indoor ? ' (indoor)' : ''}`, + `Sensor: ${sensor.sid} ${indoor ? ' (indoor)' : ''}`, width / 2 - 100, 65, 'text', 0, 0, true) .css({ @@ -192,3 +174,9 @@ export async function addSensorID2chart(chart, props, width) { zIndex: 5, }).add(); } + +export const showError = (err) => { + document.querySelector('.modal-body').setHTML(err) + let myModal = new bootstrap.Modal(document.getElementById('dialogError')) + myModal.show() +} \ No newline at end of file diff --git a/public/javascripts/global.js b/public/javascripts/global.js index b519791..c8c675f 100644 --- a/public/javascripts/global.js +++ b/public/javascripts/global.js @@ -5,6 +5,10 @@ import * as map from './map.js' import * as dt from './datetime.js' import {logit} from './logit.js' import * as chart_live from './chart_live.js' +import * as chart_houravg from './chart_houravg.js' +import * as chart_dayavg from './chart_dayavg.js' +import * as chart_daynight from './chart_daynight.js' +import * as chart_lden from './chart_lden.js' (async () => { @@ -28,14 +32,21 @@ import * as chart_live from './chart_live.js' } // END global variables -const tabtable = [ - {id: 'kartentab', func: map.showMap}, - {id: 'livetab', func: chart_live.showLive}, - // {id: 'houravgtab', func: chart_houravg.showHouravg}, - // {id: 'dayavgtab', func: chart_dayavg.showDayavg}, - // {id: 'daynighttab', func: chart_daynight.showDaynight}, - // {id: 'ldentab', func: chart_lden.showLden}, -] + const tabtable = [ + {id: 'kartentab', func: map.showMap}, + {id: 'livetab', func: chart_live.showLive}, + {id: 'houravgtab', func: chart_houravg.showHouravg}, + {id: 'dayavgtab', func: chart_dayavg.showDayavg}, + {id: 'daynighttab', func: chart_daynight.showDaynight}, + {id: 'ldentab', func: chart_lden.showLden}, + ] + + const removeTabs = () => { + document.querySelector('#navi').style.display = 'none' + } + const showTabs = () => { + document.querySelector('#navi').style.display = 'block' + } async function main() { // initialise tabs @@ -78,7 +89,15 @@ const tabtable = [ // show version and version-date document.querySelector('#versn').setHTML(`Version: ${sysparams.version} vom ${sysparams.date.slice(0,10)}`) + const csid = parseInt(sysparams.csid) + if(csid !== -1) { + let triggerEl = document.querySelector('#livetab') + bootstrap.Tab.getInstance(triggerEl).show() // Select tab by name + params.sid = csid + await chart_live.showLive(params) + } // show the map + removeTabs() map.showMap(params) } main().catch(console.error) diff --git a/public/javascripts/map.js b/public/javascripts/map.js index 953ae70..f8cbab9 100644 --- a/public/javascripts/map.js +++ b/public/javascripts/map.js @@ -1,15 +1,18 @@ // all function related to the map import * as dt from './datetime.js' +import * as chart_live from "./chart_live.js"; -let map +let map = null let bounds let popuptext = '' +let clickedSensor = 0 const colorscale = ['#d53e4f', '#fc8d59', '#fee08b', '#e6f598', '#99d594', '#3288bd', '#808080']; const dba = [100, 80, 60, 40, 20, 0, -999]; export const showMap = async (params) => { + if (map) return map = L.map('map',{ scrollWheelZoom: false}).setView(params.center, parseInt(params.zoom)) L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 19, @@ -37,8 +40,21 @@ export const showMap = async (params) => { return div }; legend.addTo(map) + let lastdate = await buildMarkers() showLastDate(lastdate); + + map.on('popupopen', function () { + document.querySelector('.speciallink').addEventListener('click', async function (x) { + console.log(`Event clicked: ${clickedSensor}`) + document.querySelector('#navi').style.display = 'block' + params.sid = clickedSensor + let triggerEl = document.querySelector('#livetab') + bootstrap.Tab.getInstance(triggerEl).show() // Select tab by name + await chart_live.showLive(params) + }) + }) + } @@ -59,81 +75,7 @@ function calcPolygon(bounds) { }); ; } -/* -async function plotMap(cid, poly) { - // if sensor nbr is give, find coordinates, else use Stuttgart center - debug_log('plotMap()'); - let myLatLng; - if (cid != -1) { - myLatLng = await getSensorKoords(cid); - } else { - let stgt = await getCoords('Stuttgart'); - myLatLng = {lat: parseFloat(stgt.lat), lng: parseFloat(stgt.lon)}; - } - // generate map centered on Stuttgart - map = L.map('map').setView(myLatLng, firstZoom); - - L.tileLayer('https://{s}.tile.openstreetmap.de/{z}/{x}/{y}.png', { - maxZoom: 17, - attribution: '© OpenStreetMap contributors' - }).addTo(map); - - bounds = map.getBounds(); - - map.scrollWheelZoom.disable(); - - map.on('moveend', async function () { - bounds = map.getBounds(); - await buildMarkers(bounds) - }); - - - let legend = L.control({position: 'bottomright'}); - legend.onAdd = function (map) { - let div = L.DomUtil.create('div', 'info legend'); - let div_color = L.DomUtil.create('div', 'info legend inner', div); - div_color.innerHTML += 'dbA
'; - // loop through our density intervals and generate a label with a colored square for each interval - for (let i = 0; i < dba.length - 1; i++) { - div_color.innerHTML += - '' + - '  ' + dba[i] + (i == 0 ? '+' : '') + '
'; - } - div_color.innerHTML += '  offline'; - return div; - }; - legend.addTo(map); - - let infobutton = L.control({position: 'topright'}); - infobutton.onAdd = function (map) { - let div = L.DomUtil.create('div'); - div.innerHTML = ''; - div.onclick = function () { - dialogCenter.dialog('open'); - console.log('Clicked on Zentrieren'); - } - return div; - } - infobutton.addTo(map); - - if (useStgtBorder) { - fetchStuttgartBounds(); - } - - if (myLatLng.error != undefined) { - showError(3, "Kein Lärmsensor", cid); - } else { - await buildMarkers(bounds); - map.on('popupopen', function () { - $('.speciallink').click(function (x) { - showGrafik(clickedSensor); - }); - }); - } - -} -*/ // With all Markers in cluster (markers) calculate the median // of the values. With this median fetch the color and return it. @@ -212,7 +154,7 @@ export async function buildMarkers() { west: bounds.getWest(), south: bounds.getSouth(), east: bounds.getEast(), north: bounds.getNorth() } - const url = `http://localhost:3004/getmapdata?type=noise&box=${bounds.toBBoxString()}` + const url = `/api/getmapdata?type=noise&box=${bounds.toBBoxString()}` let ret = await fetch(url) .catch(e => { @@ -235,6 +177,9 @@ export async function buildMarkers() { }); for (let x of sensors.values) { + if (x.value <= -4) { + continue + } let marker = L.marker([x.location[1], x.location[0]], { icon: new L.Icon({ iconUrl: buildIcon(getColor(parseInt(x.value)),0,x.indoor), @@ -256,7 +201,7 @@ export async function buildMarkers() { async function onMarkerClick(e, click) { let item = e.target.options; - let clickedSensor = item.name; + clickedSensor = item.name; let offlinetext = ` offline @@ -283,6 +228,7 @@ async function onMarkerClick(e, click) { if (click == true) { // if we clicked e.target.closePopup(); // show the popup } + } async function getCoords(city) { @@ -328,7 +274,7 @@ async function showLastDate(ld) { // console.log(e) // } // fetch all sensors - const url = `http://localhost:3004/getmapdata?type=noise` + const url = `/api/getmapdata?type=noise` let ret = await fetch(url) .catch(e => { console.log(e) diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css index 51977e6..fa9a046 100644 --- a/public/stylesheets/style.css +++ b/public/stylesheets/style.css @@ -154,10 +154,18 @@ footer #author #versn { margin-top: 44px; } -#dlive, #dhour, #dday, #ddaynight, #dlden { - width: 98vw; +#dlive, #dhour, #dday, #ddaynight, #dlden, #dpeak { + width: 100%; height: 100%; margin: auto; } +#dialogError { + color: red; +} + +.modal-content { + border: red solid 2px; +} + /*# sourceMappingURL=style.css.map */ diff --git a/public/stylesheets/style.css.map b/public/stylesheets/style.css.map index fd0c87b..1a6d5ea 100644 --- a/public/stylesheets/style.css.map +++ b/public/stylesheets/style.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["style.sass"],"names":[],"mappings":"AAWA;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAEF;EACE;EACA;EACA;EAEA;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE,kBA7BoB;;AA+BpB;EACE;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;;AAEF;EACE;EACA;;;AAEJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEF;EACE;EACA;;AACA;EACE;;;AAEN;EACE;EAEA;EACA;EACA,eA3Ec;EA4Ed;EACA;EACA;;AAEA;EACE;EACA;EACA;;AACF;EACE;EACA;;;AAEJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AACF;EACE;EACA;;;AAEJ;EACE,kBA/FoB;;AAiGpB;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEF;EACE;;;AAGN;EACE;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA","file":"style.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["style.sass"],"names":[],"mappings":"AAWA;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAEF;EACE;EACA;EACA;EAEA;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE,kBA7BoB;;AA+BpB;EACE;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;;AAEF;EACE;EACA;;;AAEJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEF;EACE;EACA;;AACA;EACE;;;AAEN;EACE;EAEA;EACA;EACA,eA3Ec;EA4Ed;EACA;EACA;;AAEA;EACE;EACA;EACA;;AACF;EACE;EACA;;;AAEJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AACF;EACE;EACA;;;AAEJ;EACE,kBA/FoB;;AAiGpB;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEF;EACE;;;AAGN;EACE;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE","file":"style.css"} \ No newline at end of file diff --git a/public/stylesheets/style.sass b/public/stylesheets/style.sass index fe98585..1416737 100644 --- a/public/stylesheets/style.sass +++ b/public/stylesheets/style.sass @@ -150,7 +150,13 @@ footer .tab-pane margin-top: 44px -#dlive, #dhour, #dday, #ddaynight, #dlden - width: 98vw +#dlive, #dhour, #dday, #ddaynight, #dlden, #dpeak + width: 100% height: 100% margin: auto + +#dialogError + color: red + +.modal-content + border: red solid 2px \ No newline at end of file diff --git a/routes/api.js b/routes/api.js new file mode 100644 index 0000000..4c8895a --- /dev/null +++ b/routes/api.js @@ -0,0 +1,37 @@ +import express from 'express' +import pkg from '../package.json' assert { type: "json" } +import axios from 'axios' + +const router = express.Router() +const { name, version, date } = pkg + +let APIHOST = process.env.APIHOST || 'http://localhost:3004' + +/* GET home page. */ +router.get('/:cmd', async function(req, res, next) { + const cmd = req.params.cmd + let url = APIHOST + if(isNaN(cmd)) { + url += req.originalUrl + } else { + // cmd is a number ==> sid + url += `getsensordata?sid=${cmd}` + } + try { + const response = await axios(encodeURI(url)); + if (response.status !== 200) { + res.json({err: `Error from servercall: status = ${response.status}`}) + } + res.json(response.data) + } catch (e) { + res.json({err: `Error from servercall: ${e}`}) + } +}) + +export default router + + + +// ToDo +// Hier : getsensordata und getmapdata unterbringen und damit den externen Server aufrufen + diff --git a/routes/index.js b/routes/index.js index f248a0c..0003c94 100644 --- a/routes/index.js +++ b/routes/index.js @@ -1,16 +1,39 @@ import express from 'express' import pkg from '../package.json' assert { type: "json" } +import axios from "axios"; const router = express.Router() const { name, version, date } = pkg +let APIHOST = process.env.APIHOST || 'http://localhost:3004' + /* GET home page. */ router.get('/', function(req, res, next) { res.render('index', { title: name, version: version, - date: date + date: date, + csensor: -1 }) }) + +router.get('/:sid', async function(req, res, next) { + const sid = req.params.sid + if(!isNaN(sid)) { + res.render('index', { + title: name, + version: version, + date: date, + csensor: sid + }) + } +}) + export default router + + + +// ToDo +// Hier : getsensordata und getmapdata unterbringen und damit den externen Server aufrufen + diff --git a/views/index.pug b/views/index.pug index 469a76f..751cba8 100644 --- a/views/index.pug +++ b/views/index.pug @@ -18,9 +18,9 @@ block content li.nav-item(role='presentation') button.nav-link#dayavgtab(data-bs-toggle="tab" data-bs-target="#t_dayavg" type="button" role="tab" aria-controls="dayavg" aria-selected="true") Day_AVG li.nav-item(role='presentation') - button.nav-link#daynightab(data-bs-toggle="tab" data-bs-target="#t_daynight" type="button" role="tab" aria-controls="daynight" aria-selected="true") Day_Night + button.nav-link#daynighttab(data-bs-toggle="tab" data-bs-target="#t_daynight" type="button" role="tab" aria-controls="daynight" aria-selected="true") Day_Night li.nav-item(role='presentation') - button.nav-link#ldenab(data-bs-toggle="tab" data-bs-target="#t_lden" type="button" role="tab" aria-controls="lden" aria-selected="true") LDEN-Index + button.nav-link#ldentab(data-bs-toggle="tab" data-bs-target="#t_lden" type="button" role="tab" aria-controls="lden" aria-selected="true") LDEN-Index #buttonsRight button.btn.btn-primary#btnSet(value='set') Settings button.btn.btn-primary#btnHelp(value='help') Info @@ -32,12 +32,27 @@ block content #actsensors #mapdate .tab-pane.fade#t_live(role="tabpanel" aria-labelledby="live-tab") - #dlive LiveTAB + #dlive .tab-pane.fade#t_houravg(role="tabpanel" aria-labelledby="map-tab") - #dhour HourTAB + #dhour + #dpeak .tab-pane.fade#t_dayavg(role="tabpanel" aria-labelledby="map-tab") - #dday DayTAB + #dday .tab-pane.fade#t_daynight(role="tabpanel" aria-labelledby="map-tab") #ddaynight DayNightTAB .tab-pane.fade#t_lden(role="tabpanel" aria-labelledby="map-tab") #dlden LdenTAB + + + // Error-Dialog + .modal.fade#dialogError(tabindex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle" aria-hidden="true") + .modal-dialog.modal-dialog-centered(role="document") + .modal-content + .modal-header + h5.modal-title.dialogErrorTitle Error + button(type="button" class="close" data-bs-dismiss="modal" aria-label="Close") + span(aria-hidden="true") × + .modal-body + .modal-footer + //button(type="button" class="btn btn-secondary" data-bs-dismiss="modal") Close + // button(type="button" class="btn btn-primary") Save changes diff --git a/views/layout.pug b/views/layout.pug index 4c7e8d4..4fe7c8f 100644 --- a/views/layout.pug +++ b/views/layout.pug @@ -15,7 +15,8 @@ html script. let sysparams = { version: '#{version}', - date: '#{date}' + date: '#{date}', + csid: '#{csensor}' } let urlParams = { // drawlines: '#{drawlines}' === 'true',