diff --git a/package-lock.json b/package-lock.json index 17ff223d5..35c22876d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -59,8 +59,12 @@ "webpack-cli": "^4.9.1" }, "devDependencies": { + "dotenv": "^16.3.1", "husky": "^8.0.3", - "node-html-parser": "^6.1.1" + "jsdom": "^22.1.0", + "mockdate": "^3.0.5", + "node-html-parser": "^6.1.1", + "nodemon": "^3.0.1" }, "engines": { "node": ">=16" @@ -4252,6 +4256,12 @@ "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz", "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==" }, + "node_modules/abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "dev": true + }, "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -4374,7 +4384,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "optional": true, + "devOptional": true, "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -4496,6 +4506,12 @@ "node": "*" } }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, "node_modules/available-typed-arrays": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", @@ -4592,7 +4608,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "optional": true, + "devOptional": true, "engines": { "node": ">=8" } @@ -4813,13 +4829,13 @@ "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "devOptional": true, "funding": [ { "type": "individual", "url": "https://paulmillr.com/funding/" } ], - "optional": true, "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -4920,6 +4936,18 @@ "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==" }, + "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==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/commander": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", @@ -5053,6 +5081,18 @@ "resolved": "https://registry.npmjs.org/csscolorparser/-/csscolorparser-1.0.3.tgz", "integrity": "sha512-umPSgYwZkdFoUrH5hIq5kf0wPSXiro51nPw0j2K/c83KflkPSTBGMz6NJvMB+07VlL0y7VPo6QJcDjcgKTTm3w==" }, + "node_modules/cssstyle": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-3.0.0.tgz", + "integrity": "sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg==", + "dev": true, + "dependencies": { + "rrweb-cssom": "^0.6.0" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/d3": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/d3/-/d3-7.8.1.tgz", @@ -5449,6 +5489,20 @@ "node": ">=12" } }, + "node_modules/data-urls": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-4.0.0.tgz", + "integrity": "sha512-/mMTei/JXPqvFqQtfyTowxmJVwr2PVAeCcDxyFf6LhoOu/09TX2OX3kb2wzi4DMXcfj4OItwDOnhl5oziPnT6g==", + "dev": true, + "dependencies": { + "abab": "^2.0.6", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^12.0.0" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/datatables.net": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/datatables.net/-/datatables.net-1.13.1.tgz", @@ -5532,6 +5586,12 @@ "node": ">=0.10.0" } }, + "node_modules/decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", + "dev": true + }, "node_modules/deep-equal": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", @@ -5554,9 +5614,9 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" }, "node_modules/define-properties": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", + "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", "dependencies": { "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" @@ -5581,6 +5641,15 @@ "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.1.tgz", "integrity": "sha512-ndEIpszUHiG4HtDsQLeIuMvRsDnn8c8rYStabochtUeCvfuvNptb5TUbVD68LRAILPX7p9nqQGh4xJgn3EHS/g==" }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", @@ -5663,6 +5732,18 @@ } ] }, + "node_modules/domexception": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", + "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", + "dev": true, + "dependencies": { + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/domhandler": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", @@ -5692,6 +5773,18 @@ "url": "https://github.com/fb55/domutils?sponsor=1" } }, + "node_modules/dotenv": { + "version": "16.3.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", + "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/motdotla/dotenv?sponsor=1" + } + }, "node_modules/duplexify": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", @@ -6817,6 +6910,20 @@ "is-callable": "^1.1.3" } }, + "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==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fs-minipass": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", @@ -6842,12 +6949,12 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, "hasInstallScript": true, "optional": true, "os": [ "darwin" ], - "peer": true, "engines": { "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } @@ -6990,12 +7097,13 @@ } }, "node_modules/get-intrinsic": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", - "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", + "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", "dependencies": { "function-bind": "^1.1.1", "has": "^1.0.3", + "has-proto": "^1.0.1", "has-symbols": "^1.0.3" }, "funding": { @@ -7349,6 +7457,18 @@ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, + "node_modules/html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "dev": true, + "dependencies": { + "whatwg-encoding": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/http-cache-semantics": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", @@ -7440,6 +7560,12 @@ "node": ">= 4" } }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true + }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -7583,12 +7709,12 @@ } }, "node_modules/is-array-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.1.tgz", - "integrity": "sha512-ASfLknmY8Xa2XtB4wmbz13Wu202baeA18cJBCeCy0wXUHZF0IPyVEXqKEcd+t2fNSLLL1vC6k7lxZEojNbISXQ==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", + "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", "dependencies": { "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", + "get-intrinsic": "^1.2.0", "is-typed-array": "^1.1.10" }, "funding": { @@ -7615,7 +7741,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "optional": true, + "devOptional": true, "dependencies": { "binary-extensions": "^2.0.0" }, @@ -7787,6 +7913,12 @@ "node": ">=0.10.0" } }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true + }, "node_modules/is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", @@ -7940,6 +8072,71 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsdom": { + "version": "22.1.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-22.1.0.tgz", + "integrity": "sha512-/9AVW7xNbsBv6GfWho4TTNjEo9fe6Zhf9O7s0Fhhr3u+awPwAJMKwAMXnkk5vBxflqLW9hTHX/0cs+P3gW+cQw==", + "dev": true, + "dependencies": { + "abab": "^2.0.6", + "cssstyle": "^3.0.0", + "data-urls": "^4.0.0", + "decimal.js": "^10.4.3", + "domexception": "^4.0.0", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.1", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.4", + "parse5": "^7.1.2", + "rrweb-cssom": "^0.6.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.1.2", + "w3c-xmlserializer": "^4.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^2.0.0", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^12.0.1", + "ws": "^8.13.0", + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsdom/node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/jsdom/node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dev": true, + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -8485,6 +8682,12 @@ "node": ">=12" } }, + "node_modules/mockdate": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/mockdate/-/mockdate-3.0.5.tgz", + "integrity": "sha512-iniQP4rj1FhBdBYS/+eQv7j1tadJ9lJtdzgOpvsOHng/GbcDh2Fhdeq+ZRldrPYdXvCyfFUmFeEwEGXZB5I/AQ==", + "dev": true + }, "node_modules/moment": { "version": "2.29.4", "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", @@ -9020,6 +9223,97 @@ "node": ">=6" } }, + "node_modules/nodemon": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.0.1.tgz", + "integrity": "sha512-g9AZ7HmkhQkqXkRc20w+ZfQ73cHLbE8hnPbtaFbFtCumZsjyMhKk9LajQ07U5Ux28lvFjZ5X7HvWR1xzU8jHVw==", + "dev": true, + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^3.2.7", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^7.5.3", + "simple-update-notifier": "^2.0.0", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/nodemon/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/nodemon/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/nodemon/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/nodemon/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/nodemon/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/nodemon/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/nopt": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", @@ -9082,7 +9376,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "optional": true, + "devOptional": true, "engines": { "node": ">=0.10.0" } @@ -9131,6 +9425,12 @@ "node": ">= 6" } }, + "node_modules/nwsapi": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz", + "integrity": "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==", + "dev": true + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -9384,6 +9684,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dev": true, + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -9655,6 +9967,18 @@ "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz", "integrity": "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==" }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true + }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true + }, "node_modules/pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -9675,13 +9999,19 @@ } }, "node_modules/punycode": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.2.0.tgz", - "integrity": "sha512-LN6QV1IJ9ZhxWTNdktaPClrNfp8xdSAYS0Zk2ddX7XsXZAxckMHPCBcHRo0cTcEIgYPRiGEkmji3Idkh2yFtYw==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", "engines": { "node": ">=6" } }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -9822,7 +10152,7 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "optional": true, + "devOptional": true, "dependencies": { "picomatch": "^2.2.1" }, @@ -9907,13 +10237,13 @@ } }, "node_modules/regexp.prototype.flags": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", - "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", + "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==", "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "functions-have-names": "^1.2.2" + "define-properties": "^1.2.0", + "functions-have-names": "^1.2.3" }, "engines": { "node": ">= 0.4" @@ -9989,6 +10319,12 @@ "node": ">=0.10.0" } }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, "node_modules/resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", @@ -10076,6 +10412,12 @@ "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-2.0.4.tgz", "integrity": "sha512-l4NwboJM74Ilm4VKfbAtFeGq7aEjWL+5kVFcmgFA2MrdnQWx9iE/tUGvxY5HyMI7o/WpSIUFLbC5fbeaHgSCYg==" }, + "node_modules/rrweb-cssom": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", + "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==", + "dev": true + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -10157,6 +10499,18 @@ "node": ">=12" } }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, "node_modules/schema-utils": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", @@ -10257,6 +10611,51 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, + "node_modules/simple-update-notifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/simple-update-notifier/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/simple-update-notifier/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/simple-update-notifier/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/sinon": { "version": "12.0.1", "resolved": "https://registry.npmjs.org/sinon/-/sinon-12.0.1.tgz", @@ -10930,6 +11329,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, "node_modules/table": { "version": "6.8.1", "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", @@ -11151,6 +11556,60 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, + "node_modules/touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, + "dependencies": { + "nopt": "~1.0.10" + }, + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, + "node_modules/touch/node_modules/nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", + "dev": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tough-cookie": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", + "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", + "dev": true, + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tr46": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", + "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", + "dev": true, + "dependencies": { + "punycode": "^2.3.0" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/trim-newlines": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", @@ -11259,6 +11718,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true + }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", @@ -11311,6 +11776,15 @@ "imurmurhash": "^0.1.4" } }, + "node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/update-browserslist-db": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", @@ -11344,6 +11818,16 @@ "punycode": "^2.1.0" } }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "node_modules/util": { "version": "0.12.5", "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", @@ -11383,6 +11867,18 @@ "spdx-expression-parse": "^3.0.0" } }, + "node_modules/w3c-xmlserializer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", + "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==", + "dev": true, + "dependencies": { + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/watchpack": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", @@ -11400,6 +11896,15 @@ "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz", "integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==" }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true, + "engines": { + "node": ">=12" + } + }, "node_modules/webpack": { "version": "5.88.1", "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.1.tgz", @@ -11556,6 +12061,40 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "dev": true, + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-mimetype": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-url": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-12.0.1.tgz", + "integrity": "sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ==", + "dev": true, + "dependencies": { + "tr46": "^4.1.1", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -11686,12 +12225,42 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, + "node_modules/ws": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", + "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/xdg-basedir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", "engines": { - "node": ">=8" + "node": ">=8" + } + }, + "node_modules/xml-name-validator": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", + "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", + "dev": true, + "engines": { + "node": ">=12" } }, "node_modules/xml-utils": { @@ -11699,6 +12268,12 @@ "resolved": "https://registry.npmjs.org/xml-utils/-/xml-utils-1.3.0.tgz", "integrity": "sha512-i4PIrX33Wd66dvwo4syicwlwmnr6wuvvn4f2ku9hA67C2Uk62Xubczuhct+Evnd12/DV71qKNeDdJwES8HX1RA==" }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -14980,6 +15555,12 @@ "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz", "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==" }, + "abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "dev": true + }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -15070,7 +15651,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "optional": true, + "devOptional": true, "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -15159,6 +15740,12 @@ "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz", "integrity": "sha512-VUeSMD8nEGBWaZK4lizI1sf3yEC7pnAQ/mrI7pC2fBz2s/tq5jWWEngTwaf0Gruu/OoXRGLGg1XFqpYBiGTYJA==" }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, "available-typed-arrays": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", @@ -15226,7 +15813,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "optional": true + "devOptional": true }, "body-scroll-lock": { "version": "3.1.5", @@ -15383,7 +15970,7 @@ "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "optional": true, + "devOptional": true, "requires": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -15458,6 +16045,15 @@ "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==" }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, "commander": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", @@ -15569,6 +16165,15 @@ "resolved": "https://registry.npmjs.org/csscolorparser/-/csscolorparser-1.0.3.tgz", "integrity": "sha512-umPSgYwZkdFoUrH5hIq5kf0wPSXiro51nPw0j2K/c83KflkPSTBGMz6NJvMB+07VlL0y7VPo6QJcDjcgKTTm3w==" }, + "cssstyle": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-3.0.0.tgz", + "integrity": "sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg==", + "dev": true, + "requires": { + "rrweb-cssom": "^0.6.0" + } + }, "d3": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/d3/-/d3-7.8.1.tgz", @@ -15861,6 +16466,17 @@ "d3-transition": "2 - 3" } }, + "data-urls": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-4.0.0.tgz", + "integrity": "sha512-/mMTei/JXPqvFqQtfyTowxmJVwr2PVAeCcDxyFf6LhoOu/09TX2OX3kb2wzi4DMXcfj4OItwDOnhl5oziPnT6g==", + "dev": true, + "requires": { + "abab": "^2.0.6", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^12.0.0" + } + }, "datatables.net": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/datatables.net/-/datatables.net-1.13.1.tgz", @@ -15926,6 +16542,12 @@ } } }, + "decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", + "dev": true + }, "deep-equal": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", @@ -15945,9 +16567,9 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" }, "define-properties": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", + "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", "requires": { "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" @@ -15968,6 +16590,12 @@ } } }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true + }, "delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", @@ -16026,6 +16654,15 @@ "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", "dev": true }, + "domexception": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", + "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", + "dev": true, + "requires": { + "webidl-conversions": "^7.0.0" + } + }, "domhandler": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", @@ -16046,6 +16683,12 @@ "domhandler": "^5.0.1" } }, + "dotenv": { + "version": "16.3.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", + "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", + "dev": true + }, "duplexify": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", @@ -16879,6 +17522,17 @@ "is-callable": "^1.1.3" } }, + "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==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, "fs-minipass": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", @@ -16901,8 +17555,8 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "optional": true, - "peer": true + "dev": true, + "optional": true }, "function-bind": { "version": "1.1.1", @@ -17018,12 +17672,13 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, "get-intrinsic": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", - "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", + "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", "requires": { "function-bind": "^1.1.1", "has": "^1.0.3", + "has-proto": "^1.0.1", "has-symbols": "^1.0.3" } }, @@ -17269,6 +17924,15 @@ } } }, + "html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "dev": true, + "requires": { + "whatwg-encoding": "^2.0.0" + } + }, "http-cache-semantics": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", @@ -17325,6 +17989,12 @@ "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" }, + "ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true + }, "import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -17425,12 +18095,12 @@ } }, "is-array-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.1.tgz", - "integrity": "sha512-ASfLknmY8Xa2XtB4wmbz13Wu202baeA18cJBCeCy0wXUHZF0IPyVEXqKEcd+t2fNSLLL1vC6k7lxZEojNbISXQ==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", + "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", "requires": { "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", + "get-intrinsic": "^1.2.0", "is-typed-array": "^1.1.10" } }, @@ -17451,7 +18121,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "optional": true, + "devOptional": true, "requires": { "binary-extensions": "^2.0.0" } @@ -17557,6 +18227,12 @@ "isobject": "^3.0.1" } }, + "is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true + }, "is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", @@ -17671,6 +18347,56 @@ "esprima": "^4.0.0" } }, + "jsdom": { + "version": "22.1.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-22.1.0.tgz", + "integrity": "sha512-/9AVW7xNbsBv6GfWho4TTNjEo9fe6Zhf9O7s0Fhhr3u+awPwAJMKwAMXnkk5vBxflqLW9hTHX/0cs+P3gW+cQw==", + "dev": true, + "requires": { + "abab": "^2.0.6", + "cssstyle": "^3.0.0", + "data-urls": "^4.0.0", + "decimal.js": "^10.4.3", + "domexception": "^4.0.0", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.1", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.4", + "parse5": "^7.1.2", + "rrweb-cssom": "^0.6.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.1.2", + "w3c-xmlserializer": "^4.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^2.0.0", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^12.0.1", + "ws": "^8.13.0", + "xml-name-validator": "^4.0.0" + }, + "dependencies": { + "@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "dev": true + }, + "http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dev": true, + "requires": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + } + } + } + }, "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -18101,6 +18827,12 @@ "pkg-up": "3.x.x" } }, + "mockdate": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/mockdate/-/mockdate-3.0.5.tgz", + "integrity": "sha512-iniQP4rj1FhBdBYS/+eQv7j1tadJ9lJtdzgOpvsOHng/GbcDh2Fhdeq+ZRldrPYdXvCyfFUmFeEwEGXZB5I/AQ==", + "dev": true + }, "moment": { "version": "2.29.4", "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", @@ -18522,6 +19254,74 @@ "sorted-array-functions": "^1.3.0" } }, + "nodemon": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.0.1.tgz", + "integrity": "sha512-g9AZ7HmkhQkqXkRc20w+ZfQ73cHLbE8hnPbtaFbFtCumZsjyMhKk9LajQ07U5Ux28lvFjZ5X7HvWR1xzU8jHVw==", + "dev": true, + "requires": { + "chokidar": "^3.5.2", + "debug": "^3.2.7", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^7.5.3", + "simple-update-notifier": "^2.0.0", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, "nopt": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", @@ -18568,7 +19368,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "optional": true + "devOptional": true }, "nth-check": { "version": "2.1.1", @@ -18596,6 +19396,12 @@ } } }, + "nwsapi": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz", + "integrity": "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==", + "dev": true + }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -18781,6 +19587,15 @@ "lines-and-columns": "^1.1.6" } }, + "parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dev": true, + "requires": { + "entities": "^4.4.0" + } + }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -18989,6 +19804,18 @@ "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz", "integrity": "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==" }, + "psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true + }, + "pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true + }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -19009,9 +19836,15 @@ } }, "punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==" + }, + "querystringify": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.2.0.tgz", - "integrity": "sha512-LN6QV1IJ9ZhxWTNdktaPClrNfp8xdSAYS0Zk2ddX7XsXZAxckMHPCBcHRo0cTcEIgYPRiGEkmji3Idkh2yFtYw==" + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true }, "queue-microtask": { "version": "1.2.3", @@ -19119,7 +19952,7 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "optional": true, + "devOptional": true, "requires": { "picomatch": "^2.2.1" } @@ -19186,13 +20019,13 @@ } }, "regexp.prototype.flags": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", - "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", + "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==", "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "functions-have-names": "^1.2.2" + "define-properties": "^1.2.0", + "functions-have-names": "^1.2.3" } }, "regexpp": { @@ -19243,6 +20076,12 @@ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, "resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", @@ -19304,6 +20143,12 @@ "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-2.0.4.tgz", "integrity": "sha512-l4NwboJM74Ilm4VKfbAtFeGq7aEjWL+5kVFcmgFA2MrdnQWx9iE/tUGvxY5HyMI7o/WpSIUFLbC5fbeaHgSCYg==" }, + "rrweb-cssom": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", + "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==", + "dev": true + }, "run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -19348,6 +20193,15 @@ "yargs": "^17.2.1" } }, + "saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "requires": { + "xmlchars": "^2.2.0" + } + }, "schema-utils": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", @@ -19426,6 +20280,41 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, + "simple-update-notifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "dev": true, + "requires": { + "semver": "^7.5.3" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, "sinon": { "version": "12.0.1", "resolved": "https://registry.npmjs.org/sinon/-/sinon-12.0.1.tgz", @@ -19924,6 +20813,12 @@ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" }, + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, "table": { "version": "6.8.1", "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", @@ -20087,6 +20982,47 @@ } } }, + "touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, + "requires": { + "nopt": "~1.0.10" + }, + "dependencies": { + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", + "dev": true, + "requires": { + "abbrev": "1" + } + } + } + }, + "tough-cookie": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", + "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", + "dev": true, + "requires": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + } + }, + "tr46": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", + "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", + "dev": true, + "requires": { + "punycode": "^2.3.0" + } + }, "trim-newlines": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", @@ -20167,6 +21103,12 @@ "which-boxed-primitive": "^1.0.2" } }, + "undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true + }, "unicode-canonical-property-names-ecmascript": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", @@ -20207,6 +21149,12 @@ "imurmurhash": "^0.1.4" } }, + "universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "dev": true + }, "update-browserslist-db": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", @@ -20224,6 +21172,16 @@ "punycode": "^2.1.0" } }, + "url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "requires": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "util": { "version": "0.12.5", "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", @@ -20260,6 +21218,15 @@ "spdx-expression-parse": "^3.0.0" } }, + "w3c-xmlserializer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", + "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==", + "dev": true, + "requires": { + "xml-name-validator": "^4.0.0" + } + }, "watchpack": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", @@ -20274,6 +21241,12 @@ "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz", "integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==" }, + "webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true + }, "webpack": { "version": "5.88.1", "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.1.tgz", @@ -20368,6 +21341,31 @@ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==" }, + "whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "dev": true, + "requires": { + "iconv-lite": "0.6.3" + } + }, + "whatwg-mimetype": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", + "dev": true + }, + "whatwg-url": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-12.0.1.tgz", + "integrity": "sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ==", + "dev": true, + "requires": { + "tr46": "^4.1.1", + "webidl-conversions": "^7.0.0" + } + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -20467,16 +21465,35 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, + "ws": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", + "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "dev": true, + "requires": {} + }, "xdg-basedir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==" }, + "xml-name-validator": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", + "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", + "dev": true + }, "xml-utils": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/xml-utils/-/xml-utils-1.3.0.tgz", "integrity": "sha512-i4PIrX33Wd66dvwo4syicwlwmnr6wuvvn4f2ku9hA67C2Uk62Xubczuhct+Evnd12/DV71qKNeDdJwES8HX1RA==" }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, "y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/package.json b/package.json index 420e1c5c6..d24d6c278 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ ], "scripts": { "start": "pm2 start config/pm2.json", + "start:local": "nodemon -r dotenv/config index.js", "build:clean": "build/clean-src", "build:cp-assets": "build/cp-assets", "build:js": "build/build-js", @@ -81,7 +82,11 @@ ] }, "devDependencies": { + "dotenv": "^16.3.1", "husky": "^8.0.3", - "node-html-parser": "^6.1.1" + "jsdom": "^22.1.0", + "mockdate": "^3.0.5", + "node-html-parser": "^6.1.1", + "nodemon": "^3.0.1" } } diff --git a/server/src/js/components/bar-chart.js b/server/src/js/components/bar-chart/index.mjs similarity index 74% rename from server/src/js/components/bar-chart.js rename to server/src/js/components/bar-chart/index.mjs index 064386340..b225bef06 100644 --- a/server/src/js/components/bar-chart.js +++ b/server/src/js/components/bar-chart/index.mjs @@ -7,6 +7,8 @@ import { timeFormat } from 'd3-time-format' import { select, pointer } from 'd3-selection' import { max } from 'd3-array' import { timeMinute } from 'd3-time' +import { createResolutionControls, updateResolutionControls } from './resolution-controls.mjs' +import { createPaginationControls, updatePagination } from './pagination-controls.mjs' // const { xhr } = window.flood.utils const { forEach } = window.flood.utils @@ -237,52 +239,6 @@ function BarChart (containerId, stationId, data) { locatorLine.classed('locator__line--visible', false) locatorBackground.classed('locator__background--visible', false) } - - const updateSegmentedControl = () => { - const now = new Date() - const dataDurationDays = (new Date(now.getTime() - dataStart.getTime())) / (1000 * 60 * 60 * 24) - // Check there are at least 2 telemetry arrays - let numBands = 0 - for (let i = 0; i < bands.length; i++) { - numBands += Object.getOwnPropertyDescriptor(dataCache, bands[i].period) ? 1 : 0 - } - // Determine which controls to display - forEach(segmentedControl.querySelectorAll('.defra-chart-segmented-control input'), input => { - const isBand = period === input.getAttribute('data-period') - const band = bands.find(x => x.period === input.getAttribute('data-period')) - input.checked = isBand - input.parentNode.style.display = (band.days <= dataDurationDays) && numBands > 1 ? 'inline-block' : 'none' - input.parentNode.classList.toggle('defra-chart-segmented-control__segment--selected', isBand) - }) - } - - const updatePagination = (start, end, duration, durationHours) => { - // Set paging values and ensure they are within data range - const now = new Date() - let nextStart = new Date(start.getTime() + duration) - let nextEnd = new Date(end.getTime() + duration) - let previousStart = new Date(start.getTime() - duration) - let previousEnd = new Date(end.getTime() - duration) - nextEnd = nextEnd.getTime() <= now.getTime() ? nextEnd.toISOString().replace(/.\d+Z$/g, 'Z') : null - nextStart = nextEnd ? nextStart.toISOString().replace(/.\d+Z$/g, 'Z') : null - previousStart = previousStart.getTime() >= dataStart.getTime() ? previousStart.toISOString().replace(/.\d+Z$/g, 'Z') : null - previousEnd = previousStart ? previousEnd.toISOString().replace(/.\d+Z$/g, 'Z') : null - // Set properties - paginationInner.style.display = (nextStart || previousEnd) ? 'inline-block' : 'none' - pageForward.setAttribute('data-start', nextStart) - pageForward.setAttribute('data-end', nextEnd) - pageBack.setAttribute('data-start', previousStart) - pageBack.setAttribute('data-end', previousEnd) - pageForward.setAttribute('aria-disabled', !(nextStart && nextEnd)) - pageBack.setAttribute('data-journey-click', 'Rainfall:Chart Interaction:Rainfall - Previous 24hrs') - pageForward.setAttribute('data-journey-click', 'Rainfall:Chart Interaction:Rainfall - Next 24hrs') - pageBack.setAttribute('aria-disabled', !(previousStart && previousEnd)) - pageForwardText.innerText = `Next ${durationHours > 1 ? durationHours : duration} ${durationHours > 1 ? 'hours' : 'minutes'}` - pageBackText.innerText = `Previous ${durationHours > 1 ? durationHours : duration} ${durationHours > 1 ? 'hours' : 'minutes'}` - pageForwardDescription.innerText = '' - pageBackDescription.innerText = '' - } - const updateGrid = (colcount, total, hours, days, start, end) => { // Update grid properites grid.attr('aria-rowcount', 1) @@ -344,22 +300,26 @@ function BarChart (containerId, stationId, data) { dataItem = direction === 'forward' ? dataPage[positiveDataItems[positiveDataItems.length - 1]] : dataPage[positiveDataItems[0]] } // Update html control properties - updateSegmentedControl() - updatePagination(pageStart, pageEnd, pageDuration, pageDurationHours) + updateResolutionControls({ bands, dataCache, dataStart, period, resolutionControlGroup }) + updatePagination({ + start: pageStart, + end: pageEnd, + duration: pageDuration, + dataStart, + paginationControlGroup: pagination, + pageForward, + pageForwardText, + pageForwardDescription, + pageBack, + pageBackText, + pageBackDescription + }) const totalPageRainfall = dataPage.reduce((a, b) => { return a + b.value }, 0) const pageValueStart = new Date(new Date(dataPage[dataPage.length - 1].dateTime).getTime() - valueDuration) const pageValueEnd = new Date(dataPage[0].dateTime) updateGrid(positiveDataItems.length, totalPageRainfall, pageDurationHours, pageDurationDays, pageValueStart, pageValueEnd) } - const changePage = (event) => { - const target = event.target - direction = target.getAttribute('data-direction') - pageStart = new Date(target.getAttribute('data-start')) - pageEnd = new Date(target.getAttribute('data-end')) - initChart() - } - const scaleBandInvert = (scale) => { // D3 doesnt currently support inverting of a scaleBand const domain = scale.domain() @@ -410,27 +370,14 @@ function BarChart (containerId, stationId, data) { container.appendChild(controls) // Data resolutions in days, ascending order - const bands = [{ period: 'minutes', label: 'Minutes', days: 1 }, { period: 'hours', label: 'Hours', days: 5 }] + const bands = [ + { period: 'minutes', label: '24 hours', days: 1 }, + { period: 'hours', label: '5 days', days: 5 } + ] // Add time scale buttons - const segmentedControl = document.createElement('div') - segmentedControl.className = 'defra-chart-segmented-control' - for (let i = bands.length - 1; i >= 0; i--) { - const control = document.createElement('div') - control.className = 'defra-chart-segmented-control__segment' - control.style.display = 'none' - let start = new Date() - let end = new Date() - start.setHours(start.getHours() - (bands.find(x => x.period === bands[i].period).days * 24)) - start = start.toISOString().replace(/.\d+Z$/g, 'Z') - end = end.toISOString().replace(/.\d+Z$/g, 'Z') - control.innerHTML = ` - - - ` - segmentedControl.appendChild(control) - } - controls.appendChild(segmentedControl) + const resolutionControlGroup = createResolutionControls({ bands }) + controls.appendChild(resolutionControlGroup) // Create chart container elements const svg = select(`#${containerId}`).append('svg') @@ -463,41 +410,17 @@ function BarChart (containerId, stationId, data) { const tooltipDescription = tooltipText.append('tspan').attr('class', 'tooltip-text__small') // Add paging control - const pagination = document.createElement('div') - pagination.className = 'defra-chart-pagination' - const paginationInner = document.createElement('div') - paginationInner.style.display = 'none' - paginationInner.className = 'defra-chart-pagination_inner' - const pageBack = document.createElement('button') - pageBack.className = 'defra-chart-pagination__button defra-chart-pagination__button--back' - pageBack.setAttribute('data-direction', 'back') - pageBack.setAttribute('aria-controls', 'bar-chart') - pageBack.setAttribute('aria-describedby', 'page-back-description') - const pageBackText = document.createElement('span') - pageBackText.className = 'defra-chart-pagination__text' - pageBack.appendChild(pageBackText) - const pageBackDescription = document.createElement('span') - pageBackDescription.id = 'page-back-description' - pageBackDescription.className = 'govuk-visually-hidden' - pageBackDescription.setAttribute('aria-live', 'polite') - pageBack.appendChild(pageBackDescription) - const pageForward = document.createElement('button') - pageForward.className = 'defra-chart-pagination__button defra-chart-pagination__button--forward' - pageForward.setAttribute('data-direction', 'forward') - pageForward.setAttribute('aria-controls', 'bar-chart') - pageForward.setAttribute('aria-describedby', 'page-forward-description') - const pageForwardText = document.createElement('span') - pageForwardText.className = 'defra-chart-pagination__text' - pageForward.appendChild(pageForwardText) - const pageForwardDescription = document.createElement('span') - pageForwardDescription.id = 'page-forward-description' - pageForwardDescription.className = 'govuk-visually-hidden' - pageForwardDescription.setAttribute('aria-live', 'polite') - pageForward.appendChild(pageForwardDescription) - paginationInner.appendChild(pageBack) - paginationInner.appendChild(pageForward) - pagination.appendChild(paginationInner) - container.appendChild(pagination) + const { + pagination, + pageForward, + pageForwardText, + pageForwardDescription, + pageBack, + pageBackText, + pageBackDescription + } = createPaginationControls() + + controls.appendChild(pagination) // Set defaults let width, height, xScale, yScale, dataStart, dataPage, dataItem, latestDateTime, period, positiveDataItems, direction, interfaceType @@ -542,17 +465,20 @@ function BarChart (containerId, stationId, data) { }) container.addEventListener('click', (e) => { - const classNames = ['defra-chart-segmented-control__input', 'defra-chart-pagination__button'] - if (!classNames.some(className => e.target.classList.contains(className))) return - if (e.target.getAttribute('aria-disabled') === 'true') { - const container = e.target.classList.contains('defra-chart-pagination__button--back') ? pageBackDescription : pageForwardDescription - container.innerText = '' + const button = e.target.closest('.defra-chart-controls__button') + if (!button) return + if (button.getAttribute('aria-disabled') === 'true') { + const description = button.querySelector('.govuk-visually-hidden') + description.innerText = '' window.setTimeout(() => { - container.innerText = container === pageBackDescription ? 'No previous data' : 'No more data' + description.innerText = button.dataset.direction === 'back' ? 'No previous data' : 'No more data' }, 100) return } - changePage(e) + direction = button.getAttribute('data-direction') + pageStart = new Date(button.getAttribute('data-start')) + pageEnd = new Date(button.getAttribute('data-end')) + initChart() }) document.addEventListener('keyup', (e) => { diff --git a/server/src/js/components/bar-chart/pagination-controls.mjs b/server/src/js/components/bar-chart/pagination-controls.mjs new file mode 100644 index 000000000..74a6ec723 --- /dev/null +++ b/server/src/js/components/bar-chart/pagination-controls.mjs @@ -0,0 +1,83 @@ + +export function createPaginationControls () { + const pagination = document.createElement('div') + pagination.classList.add('defra-chart-controls__group', 'defra-chart-controls__group--pagination') + pagination.style.display = 'none' + + const pageBack = document.createElement('button') + pageBack.className = 'defra-chart-controls__button' + pageBack.setAttribute('data-direction', 'back') + pageBack.setAttribute('aria-controls', 'bar-chart') + pageBack.setAttribute('aria-describedby', 'page-back-description') + + const pageBackText = document.createElement('span') + pageBackText.className = 'defra-chart-controls__button-text' + + const pageBackDescription = document.createElement('span') + pageBackDescription.id = 'page-back-description' + pageBackDescription.className = 'govuk-visually-hidden' + pageBackDescription.setAttribute('aria-live', 'polite') + + pageBack.appendChild(pageBackText) + pageBack.appendChild(pageBackDescription) + + const pageForward = document.createElement('button') + pageForward.className = 'defra-chart-controls__button' + pageForward.setAttribute('data-direction', 'forward') + pageForward.setAttribute('aria-controls', 'bar-chart') + pageForward.setAttribute('aria-describedby', 'page-forward-description') + + const pageForwardText = document.createElement('span') + pageForwardText.className = 'defra-chart-controls__text' + + const pageForwardDescription = document.createElement('span') + pageForwardDescription.id = 'page-forward-description' + pageForwardDescription.className = 'govuk-visually-hidden' + pageForwardDescription.setAttribute('aria-live', 'polite') + + pageForward.appendChild(pageForwardText) + pageForward.appendChild(pageForwardDescription) + + pagination.appendChild(pageBack) + pagination.appendChild(pageForward) + + return { + pagination, + pageForward, + pageForwardText, + pageForwardDescription, + pageBack, + pageBackText, + pageBackDescription + } +} +export function updatePagination ({ + start, end, duration, dataStart, paginationControlGroup, + pageForward, pageForwardText, pageForwardDescription, + pageBack, pageBackText, pageBackDescription +}) { + // Set paging values and ensure they are within data range + const now = new Date() + let nextStart = new Date(start.getTime() + duration) + let nextEnd = new Date(end.getTime() + duration) + let previousStart = new Date(start.getTime() - duration) + let previousEnd = new Date(end.getTime() - duration) + nextEnd = nextEnd.getTime() <= now.getTime() ? nextEnd.toISOString().replace(/.\d+Z$/g, 'Z') : null + nextStart = nextEnd ? nextStart.toISOString().replace(/.\d+Z$/g, 'Z') : null + previousStart = previousStart.getTime() >= dataStart.getTime() ? previousStart.toISOString().replace(/.\d+Z$/g, 'Z') : null + previousEnd = previousStart ? previousEnd.toISOString().replace(/.\d+Z$/g, 'Z') : null + // Set properties + paginationControlGroup.style.display = (nextStart || previousEnd) ? 'inline-block' : 'none' + pageForward.setAttribute('data-start', nextStart) + pageForward.setAttribute('data-end', nextEnd) + pageBack.setAttribute('data-start', previousStart) + pageBack.setAttribute('data-end', previousEnd) + pageForward.setAttribute('aria-disabled', !(nextStart && nextEnd)) + pageBack.setAttribute('data-journey-click', 'Rainfall:Chart Interaction:Rainfall - Previous 24hrs') + pageForward.setAttribute('data-journey-click', 'Rainfall:Chart Interaction:Rainfall - Next 24hrs') + pageBack.setAttribute('aria-disabled', !(previousStart && previousEnd)) + pageForwardText.innerText = 'Forward' + pageBackText.innerText = 'Back' + pageForwardDescription.innerText = '' + pageBackDescription.innerText = '' +} diff --git a/server/src/js/components/bar-chart/resolution-controls.mjs b/server/src/js/components/bar-chart/resolution-controls.mjs new file mode 100644 index 000000000..03ee33748 --- /dev/null +++ b/server/src/js/components/bar-chart/resolution-controls.mjs @@ -0,0 +1,48 @@ + +const { forEach } = window.flood.utils + +export function createResolutionControls ({ bands }) { + const resolutionControlGroup = document.createElement('div') + resolutionControlGroup.classList.add('defra-chart-controls__group', 'defra-chart-controls__group--resolution') + for (let i = bands.length - 1; i >= 0; i--) { + const band = bands[i] + const control = document.createElement('button') + + const start = new Date() + const end = new Date() + start.setHours(start.getHours() - (bands.find(({ period }) => period === band.period).days * 24)) + + control.className = 'defra-chart-controls__button' + control.style.display = 'none' + control.setAttribute('data-period', band.period) + control.setAttribute('data-start', start.toISOString().replace(/.\d+Z$/g, 'Z')) + control.setAttribute('data-end', end.toISOString().replace(/.\d+Z$/g, 'Z')) + control.setAttribute('aria-controls', 'bar-chart') + + const text = document.createElement('span') + text.className = 'defra-chart-controls__text' + text.innerText = band.label + + control.appendChild(text) + resolutionControlGroup.appendChild(control) + } + return resolutionControlGroup +} + +export function updateResolutionControls ({ bands, dataCache, dataStart, period, resolutionControlGroup }) { + const now = new Date() + const dataDurationDays = (new Date(now.getTime() - dataStart.getTime())) / (1000 * 60 * 60 * 24) + // Check there are at least 2 telemetry arrays + let numBands = 0 + for (let i = 0; i < bands.length; i++) { + numBands += Object.getOwnPropertyDescriptor(dataCache, bands[i].period) ? 1 : 0 + } + // Determine which controls to display + forEach(resolutionControlGroup.querySelectorAll('.defra-chart-controls__button'), button => { + const isBand = period === button.getAttribute('data-period') + const band = bands.find(x => x.period === button.getAttribute('data-period')) + button.checked = isBand + button.style.display = (band.days <= dataDurationDays) && numBands > 1 ? 'inline-block' : 'none' + button.classList.toggle('defra-chart-controls__button--selected', isBand) + }) +} diff --git a/server/src/js/core.js b/server/src/js/core.mjs similarity index 99% rename from server/src/js/core.js rename to server/src/js/core.mjs index 806776b0b..8bf5707b0 100755 --- a/server/src/js/core.js +++ b/server/src/js/core.mjs @@ -1,8 +1,8 @@ 'use strict' // "flood" represents the global namespace for // client-side javascript across all our pages -import 'core-js/modules/es6.promise' -import 'core-js/modules/es6.array.iterator' +import 'core-js/modules/es6.promise.js' +import 'core-js/modules/es6.array.iterator.js' // Math.log2 Polyfil if (!Math.log2) { diff --git a/server/src/js/pages/rainfall.js b/server/src/js/pages/rainfall.js index 5fee773b8..1e4d097d6 100644 --- a/server/src/js/pages/rainfall.js +++ b/server/src/js/pages/rainfall.js @@ -1,6 +1,6 @@ 'use strict' import 'elm-pep' -import '../components/bar-chart' +import '../components/bar-chart/index.mjs' import '../components/nunjucks' import '../components/map/maps' import '../components/map/styles' diff --git a/server/src/sass/components/_bar-chart.scss b/server/src/sass/components/_bar-chart.scss index dd0dbf034..16969ef5e 100644 --- a/server/src/sass/components/_bar-chart.scss +++ b/server/src/sass/components/_bar-chart.scss @@ -24,19 +24,22 @@ @include mq ($from: desktop) { height:450px; } - .axis.y { + .axis.y { @include govuk-font($size: 14, $tabular: true); } - .axis.x { - @include govuk-font($size: 14); + .axis.x { + @include govuk-font($size: 14); } .axis.y text, .axis.x text { fill: $govuk-secondary-text-colour; + @include high-contrast-mode-only { + fill: currentColor; + } } .axis.y .tick line, .axis.y path, - .grid.y path.domain { + .grid.y path.domain { display: none; } .axis path, @@ -45,6 +48,9 @@ stroke: $govuk-border-colour; stroke-width: 1; shape-rendering: crispEdges; + @include high-contrast-mode-only { + stroke: currentColor; + } } .bar { pointer-events: none; @@ -55,12 +61,21 @@ } .bar__fill { fill: govuk-colour('blue'); + @include high-contrast-mode-only { + fill: currentColor; + } } .bar--selected .bar__fill { fill: govuk-colour('dark-blue'); + @include high-contrast-mode-only { + fill: currentColor; + } } .bar--incomplete .bar__fill { fill: govuk-colour('mid-grey'); + @include high-contrast-mode-only { + fill: currentColor; + } } .grid { pointer-events: none; @@ -77,9 +92,15 @@ stroke: govuk-colour('dark-grey'); stroke-dasharray: 3 3; shape-rendering: crispEdges; + @include high-contrast-mode-only { + stroke: currentColor; + } } .bar--selected .latest-line { stroke: govuk-colour('black'); + @include high-contrast-mode-only { + stroke: currentColor; + } } // Locator line .locator { @@ -94,6 +115,9 @@ &__background--visible { visibility: visible; fill: $govuk-focus-colour; + @include high-contrast-mode-only { + fill: currentColor; + } } &__line { visibility: hidden; @@ -113,13 +137,17 @@ visibility: visible; } .tooltip-bg { - fill:white; + fill: window; stroke-width: 1; stroke: $govuk-secondary-text-colour; shape-rendering: geometricPrecision; + @include high-contrast-mode-only { + stroke: currentColor; + } } .tooltip-text { @include govuk-font($size: 16); + fill: currentColor; } .tooltip-text__strong { @include govuk-font($size: 19, $weight:bold); diff --git a/server/src/sass/components/_chart-controls.scss b/server/src/sass/components/_chart-controls.scss index 215553514..e108774ee 100644 --- a/server/src/sass/components/_chart-controls.scss +++ b/server/src/sass/components/_chart-controls.scss @@ -1,91 +1,60 @@ .defra-chart-controls { position: relative; z-index: 1; -} -.defra-chart-segmented-control { - margin: auto; - &__segment { + overflow: auto; + margin: -3px -3px 0 -3px; + padding: 3px 3px 0 3px; + + &__group { + margin: auto; display: inline-block; - position: relative; - text-align: center; - margin-right: 15px; + padding-bottom: 4px; } - input { - position: absolute; - opacity: 0; - margin: 0; - top: 0; - right: 0; - bottom: 0; - left: 0; - width: 100%; - height: 100%; - cursor: pointer; + + &__group--pagination { + float: right; + margin-right: 10px; } - label { - cursor: pointer; - display: block; - @include govuk-font($size: 16); - padding: 5px 0; - border-bottom: 5px solid transparent; + + &__button { + @extend .defra-button-text-s; + touch-action: manipulation; + padding: 7.5px; + display: inline-block; position: relative; - outline: 3px solid transparent; + text-align: center; + text-decoration: none; + margin-bottom: -4px; + cursor: pointer; color: govuk-colour('blue'); } - input:hover + label { + + &__button:hover { color: $govuk-link-hover-colour; } - input:checked + label { - border-bottom: 5px solid govuk-colour('blue'); + &__button--selected { + border-bottom: 4px solid govuk-colour('blue'); } - input:focus + label { - border-bottom: 5px solid govuk-colour('black'); + &__button:focus { + border-bottom: 4px solid govuk-colour('black'); background-color: $govuk-focus-colour; color: govuk-colour('black'); - } -} -.defra-chart-pagination { - display: block; - padding-bottom: 15px; - &__button { - border: 0px; - background-color: white; - margin: 0px; - padding: 0px; - width: auto; - outline: 3px solid transparent; - color: $govuk-link-colour; - cursor: pointer; - touch-action: manipulation; - @include govuk-font($size: 16); - .defra-chart-pagination__text { - pointer-events: none; - } - &[aria-disabled="true"], - &[aria-disabled="true"]:after, - &[aria-disabled="true"]:before { - color: govuk-colour('mid-grey'); - } - &--back { - margin-right: 10px; - } - @include mq ($from: tablet) { - margin-top: 5px; + @include high-contrast-mode-only { + outline: 3px solid transparent; + margin-bottom: 1px; + border: none; } } - &__button[aria-disabled="true"] { + &__button[aria-disabled="true"], + &__button[aria-disabled="true"]:after, + &__button[aria-disabled="true"]:before { + color: govuk-colour('mid-grey'); cursor: not-allowed; + forced-color-adjust: none; } - &__button:hover:not([aria-disabled="true"]) { - color: $govuk-link-hover-colour; - &:after, &:before { - color: $govuk-link-hover-colour; - } - } - &__button--forward:after, - &__button--back:before { + &__button:after, + &__button:before { display: inline-block; - content: ''; border-width: 0 2px 2px 0; width: 8px; height: 8px; @@ -94,25 +63,16 @@ margin-right: 2px; margin-left: 2px; } - &__button--forward:after { + &__button[data-direction="forward"]:after { + content: ''; -webkit-transform: rotate(-45deg); -ms-transform: rotate(-45deg); transform: rotate(-45deg); } - &__button--back:before { + &__button[data-direction="back"]:before { + content: ''; -webkit-transform: rotate(135deg); -ms-transform: rotate(135deg); transform: rotate(135deg); } - &__button:focus:not([aria-disabled="true"]) { - color: $govuk-focus-text-colour; - background-color: $govuk-focus-colour; - box-shadow: 0 -2px $govuk-focus-colour, 0 4px govuk-colour('black'); - &:after, &:before { - color: $govuk-focus-text-colour; - } - } - &__button:focus[aria-disabled="true"] { - box-shadow: 0px 0px 0px 2px govuk-colour('black'), 0px 0px 0px 5px $govuk-focus-colour; - } } diff --git a/server/src/sass/components/_flood-levels-table.scss b/server/src/sass/components/_flood-levels-table.scss index 0cdbdaf30..850070711 100644 --- a/server/src/sass/components/_flood-levels-table.scss +++ b/server/src/sass/components/_flood-levels-table.scss @@ -179,6 +179,9 @@ left: 4px; top: 4px; color: govuk-colour('black'); + @include high-contrast-mode-only { + color: currentColor; + } @include mq ($from: tablet) { left:6px; top: 6px; diff --git a/server/src/sass/components/_flood-status.scss b/server/src/sass/components/_flood-status.scss index 2c3145c1f..aa09b7d7e 100644 --- a/server/src/sass/components/_flood-status.scss +++ b/server/src/sass/components/_flood-status.scss @@ -37,6 +37,14 @@ $amber: #f18700; background-color: govuk-colour('light-grey'); margin-top:0; margin-bottom:10px; + + @include high-contrast-mode-only { + border-top-width: 1px; + border-bottom-width: 1px; + border-right-width: 1px; + border-style: solid; + } + &:last-of-type { margin-bottom:5px; } diff --git a/server/src/sass/components/_line-chart.scss b/server/src/sass/components/_line-chart.scss index 57015d4ed..f27b088dd 100644 --- a/server/src/sass/components/_line-chart.scss +++ b/server/src/sass/components/_line-chart.scss @@ -78,7 +78,7 @@ } .observed-area { fill: rgba($govuk-link-colour, 0.1); - @media screen and (-ms-high-contrast: active), screen and (forced-colors: active) { + @include high-contrast-mode-only { fill: none; } } @@ -92,7 +92,7 @@ } .forecast-area { fill: rgba($govuk-border-colour, 0.1); - @media screen and (-ms-high-contrast: active), screen and (forced-colors: active) { + @include high-contrast-mode-only { fill: none; } } @@ -119,7 +119,7 @@ color: $govuk-secondary-text-colour; stroke: currentColor; } - @media screen and (-ms-high-contrast: active), screen and (forced-colors: active) { + @include high-contrast-mode-only { .locator-point { fill: window; } @@ -147,7 +147,7 @@ .tooltip-text__strong { @include govuk-font($size: 19, $weight:bold); } - @media screen and (-ms-high-contrast: active), screen and (forced-colors: active) { + @include high-contrast-mode-only { .tooltip-bg { fill: window; } @@ -227,7 +227,7 @@ color: $govuk-text-colour; fill: currentColor; } - @media screen and (-ms-high-contrast: active), screen and (forced-colors: active) { + @include high-contrast-mode-only { .threshold__line { stroke: currentColor; } @@ -243,7 +243,7 @@ .threshold.threshold--selected { .threshold__remove { opacity: 1; - } + } .threshold-label { visibility: visible; pointer-events: auto; @@ -256,7 +256,7 @@ .threshold__remove line { stroke: $govuk-text-colour; } - @media screen and (-ms-high-contrast: active), screen and (forced-colors: active) { + @include high-contrast-mode-only { .threshold__line { stroke: currentColor; } diff --git a/server/src/sass/components/_navbar.scss b/server/src/sass/components/_navbar.scss index 5aee7de6b..a8482b672 100644 --- a/server/src/sass/components/_navbar.scss +++ b/server/src/sass/components/_navbar.scss @@ -91,7 +91,7 @@ color: govuk-colour('black'); background-color: transparent; svg { - color: govuk-colour('black'); + color: currentColor; } } &:active { @@ -166,7 +166,6 @@ svg { position: relative; display: inline-block; - color: govuk-colour('black'); vertical-align: top; left: 0px; margin: 0px 7px -3px 1px; @@ -188,12 +187,15 @@ color: $govuk-link-hover-colour; svg { color: $govuk-link-hover-colour; + @include high-contrast-mode-only { + color: currentColor; + } } } .defra-navbar__item a:focus { color: govuk-colour('black'); svg { - color: govuk-colour('black'); + color: currentColor; } } .defra-navbar__item--selected a:not(:focus) { diff --git a/server/src/sass/components/_search.scss b/server/src/sass/components/_search.scss index a07aaf036..65d09ea78 100644 --- a/server/src/sass/components/_search.scss +++ b/server/src/sass/components/_search.scss @@ -45,7 +45,6 @@ z-index: 1; cursor: pointer; color: white; - outline: 3px solid transparent; svg { position:absolute; top: 8px; diff --git a/server/src/sass/objects/_buttons.scss b/server/src/sass/objects/_buttons.scss index b32330313..215152c42 100644 --- a/server/src/sass/objects/_buttons.scss +++ b/server/src/sass/objects/_buttons.scss @@ -9,10 +9,13 @@ margin-left:5px; vertical-align: middle; top:-1px; + @include high-contrast-mode-only { + color: currentColor; + } } } -// Secondoary button +// Secondary button a.defra-button-secondary, button.defra-button-secondary { position: relative; @@ -47,11 +50,13 @@ button.defra-button-secondary { &--icon { padding-left: 31px; svg { - color: govuk-colour('black'); position: absolute; left: 10px; top: 50%; margin-top: -11px; + @include high-contrast-mode-only { + color: currentColor; + } } } } @@ -105,13 +110,22 @@ button.defra-button-secondary { margin-right: 8px; top: 4px; } + @include high-contrast-mode-only { + color: currentColor; + } } &:hover svg { color: $govuk-link-hover-colour; + @include high-contrast-mode-only { + color: currentColor; + } } &:focus svg, &:active svg { color: govuk-colour('black'); + @include high-contrast-mode-only { + color: currentColor; + } } } .defra-link-icon-s { diff --git a/server/src/sass/tools/_mixins.scss b/server/src/sass/tools/_mixins.scss index bbdf86cce..14f11d3d8 100644 --- a/server/src/sass/tools/_mixins.scss +++ b/server/src/sass/tools/_mixins.scss @@ -15,6 +15,15 @@ white-space: nowrap !important; } +@mixin high-contrast-mode-only() { + @media + screen and (forced-colors: active), + screen and (-ms-high-contrast: active) + { + @content + } +} + // // Function to create an optimized svg url diff --git a/server/views/national.html b/server/views/national.html index 8053a5d11..efaaedf22 100644 --- a/server/views/national.html +++ b/server/views/national.html @@ -58,6 +58,7 @@

Check for flooding near you +

Latest river, sea, groundwater and rainfall levels

diff --git a/test/data/telemetry.json b/test/data/telemetry.json new file mode 100644 index 000000000..ade840ee4 --- /dev/null +++ b/test/data/telemetry.json @@ -0,0 +1,2425 @@ +{ + "latestDateTime": "2023-07-18T13:00:00Z", + "rangeStartDateTime": "2023-07-13T14:38:27Z", + "rangeEndDateTime": "2023-07-18T14:38:27Z", + "dataStartDateTime": "2023-07-13T14:38:27Z", + "dataEndDateTime": "2023-07-18T14:38:27Z", + "latest1hr": 2, + "latest6hr": 3.8, + "latest24hr": 5.8, + "minutes": { + "latestDateTime": "2023-07-18T13:00:00Z", + "values": [ + { + "dateTime": "2023-07-18T14:45:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T14:30:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T14:15:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T14:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T13:45:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T13:30:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T13:15:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T13:00:00Z", + "value": 0.6 + }, + { + "dateTime": "2023-07-18T12:45:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-18T12:30:00Z", + "value": 0.6 + }, + { + "dateTime": "2023-07-18T12:15:00Z", + "value": 0.6 + }, + { + "dateTime": "2023-07-18T12:00:00Z", + "value": 0.4 + }, + { + "dateTime": "2023-07-18T11:45:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-18T11:30:00Z", + "value": 0.6 + }, + { + "dateTime": "2023-07-18T11:15:00Z", + "value": 0.4 + }, + { + "dateTime": "2023-07-18T11:00:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-18T10:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T10:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T10:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T10:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T09:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T09:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T09:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T09:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T08:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T08:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T08:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T08:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T07:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T07:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T07:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T07:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T06:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T06:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T06:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T06:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T05:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T05:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T05:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T05:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T04:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T04:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T04:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T04:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T03:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T03:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T03:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T03:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T02:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T02:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T02:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T02:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T01:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T01:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T01:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T01:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T00:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T00:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T00:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T00:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T23:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T23:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T23:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T23:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T22:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T22:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T22:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T22:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T21:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T21:30:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-17T21:15:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-17T21:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T20:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T20:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T20:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T20:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T19:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T19:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T19:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T19:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T18:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T18:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T18:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T18:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T17:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T17:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T17:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T17:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T16:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T16:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T16:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T16:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T15:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T15:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T15:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T15:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T14:45:00Z", + "value": 1 + }, + { + "dateTime": "2023-07-17T14:30:00Z", + "value": 0.6 + }, + { + "dateTime": "2023-07-17T14:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T14:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T13:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T13:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T13:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T13:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T12:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T12:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T12:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T12:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T11:45:00Z", + "value": 0.8 + }, + { + "dateTime": "2023-07-17T11:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T11:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T11:00:00Z", + "value": 0.8 + }, + { + "dateTime": "2023-07-17T10:45:00Z", + "value": 10.8 + }, + { + "dateTime": "2023-07-17T10:30:00Z", + "value": 1.6 + }, + { + "dateTime": "2023-07-17T10:15:00Z", + "value": 2.2 + }, + { + "dateTime": "2023-07-17T10:00:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-17T09:45:00Z", + "value": 0.8 + }, + { + "dateTime": "2023-07-17T09:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T09:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T09:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T08:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T08:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T08:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T08:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T07:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T07:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T07:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T07:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T06:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T06:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T06:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T06:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T05:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T05:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T05:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T05:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T04:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T04:30:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-17T04:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T04:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T03:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T03:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T03:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T03:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T02:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T02:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T02:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T02:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T01:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T01:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T01:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T01:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T00:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T00:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T00:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T00:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T23:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T23:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T23:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T23:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T22:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T22:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T22:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T22:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T21:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T21:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T21:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T21:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T20:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T20:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T20:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T20:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T19:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T19:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T19:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T19:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T18:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T18:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T18:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T18:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T17:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T17:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T17:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T17:00:00Z", + "value": 1.6 + }, + { + "dateTime": "2023-07-16T16:45:00Z", + "value": 0.6 + }, + { + "dateTime": "2023-07-16T16:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T16:15:00Z", + "value": 0.6 + }, + { + "dateTime": "2023-07-16T16:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T15:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T15:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T15:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T15:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T14:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T14:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T14:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T14:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T13:45:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-16T13:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T13:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T13:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T12:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T12:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T12:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T12:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T11:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T11:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T11:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T11:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T10:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T10:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T10:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T10:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T09:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T09:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T09:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T09:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T08:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T08:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T08:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T08:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T07:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T07:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T07:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T07:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T06:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T06:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T06:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T06:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T05:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T05:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T05:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T05:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T04:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T04:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T04:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T04:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T03:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T03:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T03:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T03:00:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-16T02:45:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-16T02:30:00Z", + "value": 0.4 + }, + { + "dateTime": "2023-07-16T02:15:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-16T02:00:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-16T01:45:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-16T01:30:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-16T01:15:00Z", + "value": 0.4 + }, + { + "dateTime": "2023-07-16T01:00:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-16T00:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T00:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T00:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T00:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T23:45:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-15T23:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T23:15:00Z", + "value": 0.4 + }, + { + "dateTime": "2023-07-15T23:00:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-15T22:45:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-15T22:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T22:15:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-15T22:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T21:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T21:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T21:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T21:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T20:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T20:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T20:15:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-15T20:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T19:45:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-15T19:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T19:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T19:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T18:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T18:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T18:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T18:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T17:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T17:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T17:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T17:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T16:45:00Z", + "value": 1.2 + }, + { + "dateTime": "2023-07-15T16:30:00Z", + "value": 3.4 + }, + { + "dateTime": "2023-07-15T16:15:00Z", + "value": 1.6 + }, + { + "dateTime": "2023-07-15T16:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T15:45:00Z", + "value": 1.6 + }, + { + "dateTime": "2023-07-15T15:30:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-15T15:15:00Z", + "value": 0.8 + }, + { + "dateTime": "2023-07-15T15:00:00Z", + "value": 2 + }, + { + "dateTime": "2023-07-15T14:45:00Z", + "value": 1.4 + }, + { + "dateTime": "2023-07-15T14:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T14:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T14:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T13:45:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-15T13:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T13:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T13:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T12:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T12:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T12:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T12:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T11:45:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-15T11:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T11:15:00Z", + "value": 0.4 + }, + { + "dateTime": "2023-07-15T11:00:00Z", + "value": 3.6 + }, + { + "dateTime": "2023-07-15T10:45:00Z", + "value": 0.8 + }, + { + "dateTime": "2023-07-15T10:30:00Z", + "value": 1 + }, + { + "dateTime": "2023-07-15T10:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T10:00:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-15T09:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T09:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T09:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T09:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T08:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T08:30:00Z", + "value": 1.6 + }, + { + "dateTime": "2023-07-15T08:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T08:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T07:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T07:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T07:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T07:00:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-15T06:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T06:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T06:15:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-15T06:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T05:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T05:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T05:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T05:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T04:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T04:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T04:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T04:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T03:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T03:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T03:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T03:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T02:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T02:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T02:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T02:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T01:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T01:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T01:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T01:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T00:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T00:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T00:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T00:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T23:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T23:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T23:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T23:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T22:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T22:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T22:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T22:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T21:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T21:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T21:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T21:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T20:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T20:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T20:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T20:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T19:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T19:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T19:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T19:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T18:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T18:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T18:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T18:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T17:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T17:30:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-14T17:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T17:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T16:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T16:30:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-14T16:15:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-14T16:00:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-14T15:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T15:30:00Z", + "value": 0.4 + }, + { + "dateTime": "2023-07-14T15:15:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-14T15:00:00Z", + "value": 0.4 + }, + { + "dateTime": "2023-07-14T14:45:00Z", + "value": 0.4 + }, + { + "dateTime": "2023-07-14T14:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T14:15:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-14T14:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T13:45:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-14T13:30:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-14T13:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T13:00:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-14T12:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T12:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T12:15:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-14T12:00:00Z", + "value": 0.4 + }, + { + "dateTime": "2023-07-14T11:45:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-14T11:30:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-14T11:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T11:00:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-14T10:45:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-14T10:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T10:15:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-14T10:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T09:45:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-14T09:30:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-14T09:15:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-14T09:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T08:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T08:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T08:15:00Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-14T08:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T07:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T07:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T07:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T07:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T06:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T06:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T06:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T06:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T05:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T05:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T05:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T05:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T04:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T04:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T04:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T04:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T03:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T03:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T03:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T03:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T02:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T02:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T02:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T02:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T01:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T01:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T01:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T01:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T00:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T00:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T00:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T00:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T23:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T23:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T23:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T23:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T22:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T22:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T22:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T22:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T21:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T21:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T21:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T21:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T20:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T20:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T20:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T20:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T19:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T19:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T19:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T19:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T18:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T18:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T18:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T18:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T17:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T17:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T17:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T17:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T16:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T16:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T16:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T16:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T15:45:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T15:30:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T15:15:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T15:00:00Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T14:45:00Z", + "value": 0 + } + ] + }, + "hours": { + "latestDateTime": "2023-07-18T13:00:00.000Z", + "values": [ + { + "dateTime": "2023-07-18T15:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T14:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T13:00:00.000Z", + "value": 2 + }, + { + "dateTime": "2023-07-18T12:00:00.000Z", + "value": 1.6 + }, + { + "dateTime": "2023-07-18T11:00:00.000Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-18T10:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T09:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T08:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T07:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T06:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T05:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T04:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T03:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T02:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T01:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-18T00:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T23:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T22:00:00.000Z", + "value": 0.4 + }, + { + "dateTime": "2023-07-17T21:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T20:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T19:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T18:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T17:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T16:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T15:00:00.000Z", + "value": 1.6 + }, + { + "dateTime": "2023-07-17T14:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T13:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T12:00:00.000Z", + "value": 0.8 + }, + { + "dateTime": "2023-07-17T11:00:00.000Z", + "value": 15.4 + }, + { + "dateTime": "2023-07-17T10:00:00.000Z", + "value": 1 + }, + { + "dateTime": "2023-07-17T09:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T08:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T07:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T06:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T05:00:00.000Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-17T04:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T03:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T02:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T01:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-17T00:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T23:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T22:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T21:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T20:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T19:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T18:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T17:00:00.000Z", + "value": 2.8 + }, + { + "dateTime": "2023-07-16T16:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T15:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T14:00:00.000Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-16T13:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T12:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T11:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T10:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T09:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T08:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T07:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T06:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T05:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T04:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-16T03:00:00.000Z", + "value": 1 + }, + { + "dateTime": "2023-07-16T02:00:00.000Z", + "value": 1 + }, + { + "dateTime": "2023-07-16T01:00:00.000Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-16T00:00:00.000Z", + "value": 0.6 + }, + { + "dateTime": "2023-07-15T23:00:00.000Z", + "value": 0.6 + }, + { + "dateTime": "2023-07-15T22:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T21:00:00.000Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-15T20:00:00.000Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-15T19:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T18:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T17:00:00.000Z", + "value": 6.2 + }, + { + "dateTime": "2023-07-15T16:00:00.000Z", + "value": 2.6 + }, + { + "dateTime": "2023-07-15T15:00:00.000Z", + "value": 3.4 + }, + { + "dateTime": "2023-07-15T14:00:00.000Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-15T13:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T12:00:00.000Z", + "value": 0.6 + }, + { + "dateTime": "2023-07-15T11:00:00.000Z", + "value": 5.4 + }, + { + "dateTime": "2023-07-15T10:00:00.000Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-15T09:00:00.000Z", + "value": 1.6 + }, + { + "dateTime": "2023-07-15T08:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T07:00:00.000Z", + "value": 0.4 + }, + { + "dateTime": "2023-07-15T06:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T05:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T04:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T03:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T02:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T01:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-15T00:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T23:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T22:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T21:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T20:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T19:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T18:00:00.000Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-14T17:00:00.000Z", + "value": 0.4 + }, + { + "dateTime": "2023-07-14T16:00:00.000Z", + "value": 0.8 + }, + { + "dateTime": "2023-07-14T15:00:00.000Z", + "value": 1 + }, + { + "dateTime": "2023-07-14T14:00:00.000Z", + "value": 0.4 + }, + { + "dateTime": "2023-07-14T13:00:00.000Z", + "value": 0.4 + }, + { + "dateTime": "2023-07-14T12:00:00.000Z", + "value": 0.8 + }, + { + "dateTime": "2023-07-14T11:00:00.000Z", + "value": 0.6 + }, + { + "dateTime": "2023-07-14T10:00:00.000Z", + "value": 0.6 + }, + { + "dateTime": "2023-07-14T09:00:00.000Z", + "value": 0.2 + }, + { + "dateTime": "2023-07-14T08:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T07:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T06:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T05:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T04:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T03:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T02:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T01:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-14T00:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T23:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T22:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T21:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T20:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T19:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T18:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T17:00:00.000Z", + "value": 0 + }, + { + "dateTime": "2023-07-13T16:00:00.000Z", + "value": 0 + } + ] + }, + "status": "success" +} diff --git a/test/dom.js b/test/dom.js new file mode 100644 index 000000000..d361ee63e --- /dev/null +++ b/test/dom.js @@ -0,0 +1,30 @@ +const { JSDOM } = require('jsdom') + +module.exports = { + setupDOM, + cleanupDOM +} +function setupDOM () { + const dom = new JSDOM('') + global.window = dom.window + global.document = dom.window.document + dom.window.flood = {} + polyfillSVG(dom.window) +} + +function cleanupDOM () { + delete global.window + delete global.document +} + +function polyfillSVG (window) { + Object.defineProperty(window.SVGElement.prototype, 'getBBox', { + writable: true, + value: () => ({ + x: 0, + y: 0, + width: 0, + height: 0 + }) + }) +} diff --git a/test/src/js/components/bar-chart.js b/test/src/js/components/bar-chart.js new file mode 100644 index 000000000..81104ed4b --- /dev/null +++ b/test/src/js/components/bar-chart.js @@ -0,0 +1,142 @@ +const Lab = require('@hapi/lab') +const { expect } = require('@hapi/code') +const mockdate = require('mockdate') + +const telemetryFixture = require('../../../data/telemetry.json') +const { cleanupDOM, setupDOM } = require('../../../dom') + +const { experiment, test, before, after, beforeEach } = exports.lab = Lab.script() +const initialTimezone = process.env.TZ +experiment('BarChart', () => { + before(async () => { + setupDOM() + process.env.TZ = 'Etc/UTC' + mockdate.set('2023-07-19T00:00:00.000Z') + await import('../../../../server/src/js/core.mjs') + await import('../../../../server/src/js/components/bar-chart/index.mjs') + }) + + after(() => { + process.env.TZ = initialTimezone + cleanupDOM() + mockdate.reset() + }) + + beforeEach(() => { + document.body.innerHTML = '' + }) + + test('The hours and minutes controls are rendered with hours as the default', async () => { + // Arrange + const chartId = 'example-chart-id' + const telemetry = telemetryFixture + const chartContainer = document.createElement('div') + chartContainer.setAttribute('id', 'bar-chart-container') + document.body.appendChild(chartContainer) + + // Act + window.flood.charts.createBarChart('bar-chart-container', chartId, telemetry) + const controlsContainer = chartContainer.querySelector('.defra-chart-controls__group--resolution') + const [fiveDaysControl, twentyFourHoursControl] = controlsContainer.children + + // Assert + expect(controlsContainer).not.to.equal(null) + expect(controlsContainer.children).to.have.length(2) + + expect(fiveDaysControl.children[0].innerText).to.equal('5 days') + expect({ ...fiveDaysControl.dataset }).to.equal({ + period: 'hours', + start: '2023-07-14T00:00:00Z', + end: '2023-07-19T00:00:00Z' + }) + + expect(twentyFourHoursControl.children[0].innerText).to.equal('24 hours') + expect({ ...twentyFourHoursControl.dataset }).to.equal({ + period: 'minutes', + start: '2023-07-18T00:00:00Z', + end: '2023-07-19T00:00:00Z' + }) + + const description = chartContainer.querySelector('#bar-chart-description').textContent + expect(description).to.contain('Showing 5 days') + expect(description).to.contain('from 14 July 2023 at 1:00AM to 18 July 2023 at 3:00PM in hourly totals.') + }) + + test('The 24 hours control switches the chart to 24 hour range', async () => { + // Arrange + const chartId = 'example-chart-id' + const telemetry = telemetryFixture + const chartContainer = document.createElement('div') + chartContainer.setAttribute('id', 'bar-chart-container') + document.body.appendChild(chartContainer) + window.flood.charts.createBarChart('bar-chart-container', chartId, telemetry) + const twentyFourHoursControl = chartContainer.querySelector('.defra-chart-controls__group--resolution').children[1] + + // Act + twentyFourHoursControl.click() + + // Assert + const description = chartContainer.querySelector('#bar-chart-description').textContent + expect(description).to.contain('Showing 24 hours') + expect(description).to.contain('from 18 July 2023 at 12:15AM to 18 July 2023 at 2:45PM in 15 minute totals.') + }) + + test('The pagination buttons are shown when the chart is in the 24 hour range', async () => { + // Arrange + const chartId = 'example-chart-id' + const telemetry = telemetryFixture + const chartContainer = document.createElement('div') + chartContainer.setAttribute('id', 'bar-chart-container') + document.body.appendChild(chartContainer) + + // Act + window.flood.charts.createBarChart('bar-chart-container', chartId, telemetry) + chartContainer.querySelector('.defra-chart-controls__group--resolution .defra-chart-controls__button[data-period="minutes"]').click() + + // Assert + const outerContainer = document.querySelector('.defra-chart-controls__group--pagination') + expect(outerContainer).not.to.equal(null) + expect(outerContainer.style.display).to.equal('inline-block') + expect(outerContainer.children).to.have.length(2) + + expect(outerContainer.children[0].dataset.direction).to.equal('back') + expect(outerContainer.children[1].dataset.direction).to.equal('forward') + }) + + test('The pagination buttons are not shown when the chart is in the 5 day range', async () => { + // Arrange + const chartId = 'example-chart-id' + const telemetry = telemetryFixture + const chartContainer = document.createElement('div') + chartContainer.setAttribute('id', 'bar-chart-container') + document.body.appendChild(chartContainer) + + // Act + window.flood.charts.createBarChart('bar-chart-container', chartId, telemetry) + chartContainer.querySelector('.defra-chart-controls__group--resolution .defra-chart-controls__button[data-period="hours"]').click() + + // Assert + const paginationControls = document.querySelector('.defra-chart-controls__group--pagination') + expect(paginationControls).not.to.equal(null) + expect(paginationControls.style.display).to.equal('none') + }) + + test('The pagination buttons allow changing the page range', async () => { + // Arrange + const chartId = 'example-chart-id' + const telemetry = telemetryFixture + const chartContainer = document.createElement('div') + chartContainer.setAttribute('id', 'bar-chart-container') + document.body.appendChild(chartContainer) + + // Act + window.flood.charts.createBarChart('bar-chart-container', chartId, telemetry) + chartContainer.querySelector('.defra-chart-controls__group--resolution .defra-chart-controls__button[data-period="minutes"]').click() + chartContainer.querySelector('.defra-chart-controls__group--pagination .defra-chart-controls__button[data-direction="back"]').click() + + // Assert + const description = chartContainer.querySelector('#bar-chart-description').textContent + expect(description).to.contain('Showing 24 hours') + expect(description).to.contain('from 17 July 2023 at 12:15AM to 18 July 2023 at 12:15AM in 15 minute totals') + }) +}) diff --git a/webpack.config.js b/webpack.config.js index d41b9d4f3..3ef02b093 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -6,7 +6,7 @@ module.exports = (env, argv) => ({ mode: !inDev ? 'production' : 'development', devtool: !inDev ? false : 'source-map', entry: { - core: './server/src/js/core', + core: './server/src/js/core.mjs', 'alerts-and-warnings': './server/src/js/pages/alerts-and-warnings', impacts: './server/src/js/pages/impacts', national: './server/src/js/pages/national',