diff --git a/README.md b/README.md index 89e65a5..eee29ae 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,8 @@ npm run build npm run start:server ``` +For the Push Notifications we sadly need a manual edit of the webpack config and add `importScripts: ['pushSw.js'],` to `GenerateSW` + ## Technologies * React diff --git a/package-lock.json b/package-lock.json index 73c9460..fd83961 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,19 +13,19 @@ } }, "@babel/core": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.6.2.tgz", - "integrity": "sha512-l8zto/fuoZIbncm+01p8zPSDZu/VuuJhAfA7d/AbzM09WR7iVhavvfNDYCNpo1VvLk6E6xgAoP9P+/EMJHuRkQ==", + "version": "7.7.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.7.5.tgz", + "integrity": "sha512-M42+ScN4+1S9iB6f+TL7QBpoQETxbclx+KNoKJABghnKYE+fMzSGqst0BZJc8CpI625bwPwYgUyRvxZ+0mZzpw==", "dev": true, "requires": { "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.6.2", - "@babel/helpers": "^7.6.2", - "@babel/parser": "^7.6.2", - "@babel/template": "^7.6.0", - "@babel/traverse": "^7.6.2", - "@babel/types": "^7.6.0", - "convert-source-map": "^1.1.0", + "@babel/generator": "^7.7.4", + "@babel/helpers": "^7.7.4", + "@babel/parser": "^7.7.5", + "@babel/template": "^7.7.4", + "@babel/traverse": "^7.7.4", + "@babel/types": "^7.7.4", + "convert-source-map": "^1.7.0", "debug": "^4.1.0", "json5": "^2.1.0", "lodash": "^4.17.13", @@ -44,75 +44,95 @@ } }, "@babel/generator": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.2.tgz", - "integrity": "sha512-j8iHaIW4gGPnViaIHI7e9t/Hl8qLjERI6DcV9kEpAIDJsAOrcnXqRS7t+QbhL76pwbtqP+QCQLL0z1CyVmtjjQ==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.4.tgz", + "integrity": "sha512-m5qo2WgdOJeyYngKImbkyQrnUN1mPceaG5BV+G0E3gWsa4l/jCSryWJdM2x8OuGAOyh+3d5pVYfZWCiNFtynxg==", "dev": true, "requires": { - "@babel/types": "^7.6.0", + "@babel/types": "^7.7.4", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" } }, + "@babel/helper-function-name": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.4.tgz", + "integrity": "sha512-AnkGIdiBhEuiwdoMnKm7jfPfqItZhgRaZfMg1XX3bS25INOnLPjPG1Ppnajh8eqgt5kPJnfqrRHqFqmjKDZLzQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.7.4", + "@babel/template": "^7.7.4", + "@babel/types": "^7.7.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.4.tgz", + "integrity": "sha512-QTGKEdCkjgzgfJ3bAyRwF4yyT3pg+vDgan8DSivq1eS0gwi+KGKE5x8kRcbeFTb/673mkO5SN1IZfmCfA5o+EA==", + "dev": true, + "requires": { + "@babel/types": "^7.7.4" + } + }, "@babel/helper-split-export-declaration": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", - "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.4.tgz", + "integrity": "sha512-guAg1SXFcVr04Guk9eq0S4/rWS++sbmyqosJzVs8+1fH5NI+ZcmkaSkc7dmtAFbHFva6yRJnjW3yAcGxjueDug==", "dev": true, "requires": { - "@babel/types": "^7.4.4" + "@babel/types": "^7.7.4" } }, "@babel/helpers": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.6.2.tgz", - "integrity": "sha512-3/bAUL8zZxYs1cdX2ilEE0WobqbCmKWr/889lf2SS0PpDcpEIY8pb1CCyz0pEcX3pEb+MCbks1jIokz2xLtGTA==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.7.4.tgz", + "integrity": "sha512-ak5NGZGJ6LV85Q1Zc9gn2n+ayXOizryhjSUBTdu5ih1tlVCJeuQENzc4ItyCVhINVXvIT/ZQ4mheGIsfBkpskg==", "dev": true, "requires": { - "@babel/template": "^7.6.0", - "@babel/traverse": "^7.6.2", - "@babel/types": "^7.6.0" + "@babel/template": "^7.7.4", + "@babel/traverse": "^7.7.4", + "@babel/types": "^7.7.4" } }, "@babel/parser": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.2.tgz", - "integrity": "sha512-mdFqWrSPCmikBoaBYMuBulzTIKuXVPtEISFbRRVNwMWpCms/hmE2kRq0bblUHaNRKrjRlmVbx1sDHmjmRgD2Xg==", + "version": "7.7.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.5.tgz", + "integrity": "sha512-KNlOe9+/nk4i29g0VXgl8PEXIRms5xKLJeuZ6UptN0fHv+jDiriG+y94X6qAgWTR0h3KaoM1wK5G5h7MHFRSig==", "dev": true }, "@babel/template": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.6.0.tgz", - "integrity": "sha512-5AEH2EXD8euCk446b7edmgFdub/qfH1SN6Nii3+fyXP807QRx9Q73A2N5hNwRRslC2H9sNzaFhsPubkS4L8oNQ==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.4.tgz", + "integrity": "sha512-qUzihgVPguAzXCK7WXw8pqs6cEwi54s3E+HrejlkuWO6ivMKx9hZl3Y2fSXp9i5HgyWmj7RKP+ulaYnKM4yYxw==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.6.0", - "@babel/types": "^7.6.0" + "@babel/parser": "^7.7.4", + "@babel/types": "^7.7.4" } }, "@babel/traverse": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.2.tgz", - "integrity": "sha512-8fRE76xNwNttVEF2TwxJDGBLWthUkHWSldmfuBzVRmEDWOtu4XdINTgN7TDWzuLg4bbeIMLvfMFD9we5YcWkRQ==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.4.tgz", + "integrity": "sha512-P1L58hQyupn8+ezVA2z5KBm4/Zr4lCC8dwKCMYzsa5jFMDMQAzaBNy9W5VjB+KAmBjb40U7a/H6ao+Xo+9saIw==", "dev": true, "requires": { "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.6.2", - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.6.2", - "@babel/types": "^7.6.0", + "@babel/generator": "^7.7.4", + "@babel/helper-function-name": "^7.7.4", + "@babel/helper-split-export-declaration": "^7.7.4", + "@babel/parser": "^7.7.4", + "@babel/types": "^7.7.4", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" } }, "@babel/types": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.1.tgz", - "integrity": "sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz", + "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==", "dev": true, "requires": { "esutils": "^2.0.2", @@ -120,11 +140,14 @@ "to-fast-properties": "^2.0.0" } }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } } } }, @@ -132,6 +155,7 @@ "version": "7.3.0", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.3.0.tgz", "integrity": "sha512-dZTwMvTgWfhmibq4V9X+LMf6Bgl7zAodRn9PvcPdhlzFMbvUutx74dbEv7Atz3ToeEpevYEJtAwfxq/bDCzHWg==", + "dev": true, "requires": { "@babel/types": "^7.3.0", "jsesc": "^2.5.1", @@ -144,6 +168,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz", "integrity": "sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q==", + "dev": true, "requires": { "@babel/types": "^7.0.0" } @@ -152,6 +177,7 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz", "integrity": "sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w==", + "dev": true, "requires": { "@babel/helper-explode-assignable-expression": "^7.1.0", "@babel/types": "^7.0.0" @@ -171,6 +197,7 @@ "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.4.4.tgz", "integrity": "sha512-l79boDFJ8S1c5hvQvG+rc+wHw6IuH7YldmRKsYtpbawsxURu/paVy57FZMomGK22/JckepaikOkY0MoAmdyOlQ==", + "dev": true, "requires": { "@babel/helper-hoist-variables": "^7.4.4", "@babel/traverse": "^7.4.4", @@ -181,6 +208,7 @@ "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.4.4.tgz", "integrity": "sha512-53UOLK6TVNqKxf7RUh8NE851EHRxOOeVXKbK2bivdb+iziMyk03Sr4eaE9OELCbyZAAafAKPDwF2TPUES5QbxQ==", + "dev": true, "requires": { "@babel/types": "^7.4.4", "jsesc": "^2.5.1", @@ -193,6 +221,7 @@ "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==", + "dev": true, "requires": { "@babel/types": "^7.4.4" } @@ -200,12 +229,14 @@ "@babel/parser": { "version": "7.4.5", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.5.tgz", - "integrity": "sha512-9mUqkL1FF5T7f0WDFfAoDdiMVPWsdD1gZYzSnaXsxUCUqzuch/8of9G3VUSNiZmMBoRxT3neyVsqeiL/ZPcjew==" + "integrity": "sha512-9mUqkL1FF5T7f0WDFfAoDdiMVPWsdD1gZYzSnaXsxUCUqzuch/8of9G3VUSNiZmMBoRxT3neyVsqeiL/ZPcjew==", + "dev": true }, "@babel/traverse": { "version": "7.4.5", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.5.tgz", "integrity": "sha512-Vc+qjynwkjRmIFGxy0KYoPj4FdVDxLej89kMHFsWScq999uX+pwcX4v9mWRjW0KcAYTPAuVQl2LKP1wEVLsp+A==", + "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "@babel/generator": "^7.4.4", @@ -222,6 +253,7 @@ "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz", "integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==", + "dev": true, "requires": { "esutils": "^2.0.2", "lodash": "^4.17.11", @@ -314,6 +346,30 @@ } } }, + "@babel/helper-create-regexp-features-plugin": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.7.4.tgz", + "integrity": "sha512-Mt+jBKaxL0zfOIWrfQpnfYCN7/rS6GKx6CCCfuoqVVd+17R8zNDlzVYmIi9qyb2wOk002NsmSTDymkIygDUH7A==", + "requires": { + "@babel/helper-regex": "^7.4.4", + "regexpu-core": "^4.6.0" + }, + "dependencies": { + "regexpu-core": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.6.0.tgz", + "integrity": "sha512-YlVaefl8P5BnFYOITTNzDvan1ulLOiXJzCNZxduTIosN17b87h3bvG9yHMoHaRuo88H4mQ06Aodj5VtYGGGiTg==", + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^8.1.0", + "regjsgen": "^0.5.0", + "regjsparser": "^0.6.0", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.1.0" + } + } + } + }, "@babel/helper-define-map": { "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.4.4.tgz", @@ -342,6 +398,7 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz", "integrity": "sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA==", + "dev": true, "requires": { "@babel/traverse": "^7.1.0", "@babel/types": "^7.0.0" @@ -351,6 +408,7 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", + "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.0.0", "@babel/template": "^7.1.0", @@ -361,6 +419,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", + "dev": true, "requires": { "@babel/types": "^7.0.0" } @@ -369,6 +428,7 @@ "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.4.4.tgz", "integrity": "sha512-VYk2/H/BnYbZDDg39hr3t2kKyifAm1W6zHRfhx8jGjIHpQEBv9dry7oQ2f3+J703TLu69nYdxsovl0XYfcnK4w==", + "dev": true, "requires": { "@babel/types": "^7.4.4" }, @@ -377,6 +437,7 @@ "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz", "integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==", + "dev": true, "requires": { "esutils": "^2.0.2", "lodash": "^4.17.11", @@ -398,6 +459,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz", "integrity": "sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A==", + "dev": true, "requires": { "@babel/types": "^7.0.0" } @@ -406,6 +468,7 @@ "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.4.4.tgz", "integrity": "sha512-3Z1yp8TVQf+B4ynN7WoHPKS8EkdTbgAEy0nU0rs/1Kw4pDgmvYH3rz3aI11KgxKCba2cn7N+tqzV1mY2HMN96w==", + "dev": true, "requires": { "@babel/helper-module-imports": "^7.0.0", "@babel/helper-simple-access": "^7.1.0", @@ -419,6 +482,7 @@ "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==", + "dev": true, "requires": { "@babel/types": "^7.4.4" } @@ -426,12 +490,14 @@ "@babel/parser": { "version": "7.4.5", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.5.tgz", - "integrity": "sha512-9mUqkL1FF5T7f0WDFfAoDdiMVPWsdD1gZYzSnaXsxUCUqzuch/8of9G3VUSNiZmMBoRxT3neyVsqeiL/ZPcjew==" + "integrity": "sha512-9mUqkL1FF5T7f0WDFfAoDdiMVPWsdD1gZYzSnaXsxUCUqzuch/8of9G3VUSNiZmMBoRxT3neyVsqeiL/ZPcjew==", + "dev": true }, "@babel/template": { "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz", "integrity": "sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==", + "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "@babel/parser": "^7.4.4", @@ -442,6 +508,7 @@ "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz", "integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==", + "dev": true, "requires": { "esutils": "^2.0.2", "lodash": "^4.17.11", @@ -454,6 +521,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz", "integrity": "sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g==", + "dev": true, "requires": { "@babel/types": "^7.0.0" } @@ -475,6 +543,7 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz", "integrity": "sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg==", + "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.0.0", "@babel/helper-wrap-function": "^7.1.0", @@ -557,6 +626,7 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz", "integrity": "sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w==", + "dev": true, "requires": { "@babel/template": "^7.1.0", "@babel/types": "^7.0.0" @@ -566,6 +636,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz", "integrity": "sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag==", + "dev": true, "requires": { "@babel/types": "^7.0.0" } @@ -574,6 +645,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz", "integrity": "sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ==", + "dev": true, "requires": { "@babel/helper-function-name": "^7.1.0", "@babel/template": "^7.1.0", @@ -674,12 +746,14 @@ "@babel/parser": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.3.1.tgz", - "integrity": "sha512-ATz6yX/L8LEnC3dtLQnIx4ydcPxhLcoy9Vl6re00zb2w5lG6itY6Vhnr1KFRPq/FHNsgl/gh2mjNN20f9iJTTA==" + "integrity": "sha512-ATz6yX/L8LEnC3dtLQnIx4ydcPxhLcoy9Vl6re00zb2w5lG6itY6Vhnr1KFRPq/FHNsgl/gh2mjNN20f9iJTTA==", + "dev": true }, "@babel/plugin-proposal-async-generator-functions": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz", "integrity": "sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ==", + "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/helper-remap-async-to-generator": "^7.1.0", @@ -687,108 +761,141 @@ } }, "@babel/plugin-proposal-class-properties": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.5.5.tgz", - "integrity": "sha512-AF79FsnWFxjlaosgdi421vmYG6/jg79bVD0dpD44QdgobzHKuLZ6S3vl8la9qIeSwGi8i1fS0O1mfuDAAdo1/A==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.7.4.tgz", + "integrity": "sha512-EcuXeV4Hv1X3+Q1TsuOmyyxeTRiSqurGJ26+I/FW1WbymmRRapVORm6x1Zl3iDIHyRxEs+VXWp6qnlcfcJSbbw==", "requires": { - "@babel/helper-create-class-features-plugin": "^7.5.5", + "@babel/helper-create-class-features-plugin": "^7.7.4", "@babel/helper-plugin-utils": "^7.0.0" }, "dependencies": { - "@babel/code-frame": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", - "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", - "requires": { - "@babel/highlight": "^7.0.0" - } - }, "@babel/generator": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.2.tgz", - "integrity": "sha512-j8iHaIW4gGPnViaIHI7e9t/Hl8qLjERI6DcV9kEpAIDJsAOrcnXqRS7t+QbhL76pwbtqP+QCQLL0z1CyVmtjjQ==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.4.tgz", + "integrity": "sha512-m5qo2WgdOJeyYngKImbkyQrnUN1mPceaG5BV+G0E3gWsa4l/jCSryWJdM2x8OuGAOyh+3d5pVYfZWCiNFtynxg==", "requires": { - "@babel/types": "^7.6.0", + "@babel/types": "^7.7.4", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" } }, "@babel/helper-create-class-features-plugin": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.6.0.tgz", - "integrity": "sha512-O1QWBko4fzGju6VoVvrZg0RROCVifcLxiApnGP3OWfWzvxRZFCoBD81K5ur5e3bVY2Vf/5rIJm8cqPKn8HUJng==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.7.4.tgz", + "integrity": "sha512-l+OnKACG4uiDHQ/aJT8dwpR+LhCJALxL0mJ6nzjB25e5IPwqV1VOsY7ah6UB1DG+VOXAIMtuC54rFJGiHkxjgA==", "requires": { - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-member-expression-to-functions": "^7.5.5", - "@babel/helper-optimise-call-expression": "^7.0.0", + "@babel/helper-function-name": "^7.7.4", + "@babel/helper-member-expression-to-functions": "^7.7.4", + "@babel/helper-optimise-call-expression": "^7.7.4", "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.5.5", - "@babel/helper-split-export-declaration": "^7.4.4" + "@babel/helper-replace-supers": "^7.7.4", + "@babel/helper-split-export-declaration": "^7.7.4" + } + }, + "@babel/helper-function-name": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.4.tgz", + "integrity": "sha512-AnkGIdiBhEuiwdoMnKm7jfPfqItZhgRaZfMg1XX3bS25INOnLPjPG1Ppnajh8eqgt5kPJnfqrRHqFqmjKDZLzQ==", + "requires": { + "@babel/helper-get-function-arity": "^7.7.4", + "@babel/template": "^7.7.4", + "@babel/types": "^7.7.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.4.tgz", + "integrity": "sha512-QTGKEdCkjgzgfJ3bAyRwF4yyT3pg+vDgan8DSivq1eS0gwi+KGKE5x8kRcbeFTb/673mkO5SN1IZfmCfA5o+EA==", + "requires": { + "@babel/types": "^7.7.4" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.5.5.tgz", - "integrity": "sha512-5qZ3D1uMclSNqYcXqiHoA0meVdv+xUEex9em2fqMnrk/scphGlGgg66zjMrPJESPwrFJ6sbfFQYUSa0Mz7FabA==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.7.4.tgz", + "integrity": "sha512-9KcA1X2E3OjXl/ykfMMInBK+uVdfIVakVe7W7Lg3wfXUNyS3Q1HWLFRwZIjhqiCGbslummPDnmb7vIekS0C1vw==", "requires": { - "@babel/types": "^7.5.5" + "@babel/types": "^7.7.4" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.7.4.tgz", + "integrity": "sha512-VB7gWZ2fDkSuqW6b1AKXkJWO5NyNI3bFL/kK79/30moK57blr6NbH8xcl2XcKCwOmJosftWunZqfO84IGq3ZZg==", + "requires": { + "@babel/types": "^7.7.4" } }, "@babel/helper-replace-supers": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.5.5.tgz", - "integrity": "sha512-XvRFWrNnlsow2u7jXDuH4jDDctkxbS7gXssrP4q2nUD606ukXHRvydj346wmNg+zAgpFx4MWf4+usfC93bElJg==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.7.4.tgz", + "integrity": "sha512-pP0tfgg9hsZWo5ZboYGuBn/bbYT/hdLPVSS4NMmiRJdwWhP0IznPwN9AE1JwyGsjSPLC364I0Qh5p+EPkGPNpg==", "requires": { - "@babel/helper-member-expression-to-functions": "^7.5.5", - "@babel/helper-optimise-call-expression": "^7.0.0", - "@babel/traverse": "^7.5.5", - "@babel/types": "^7.5.5" + "@babel/helper-member-expression-to-functions": "^7.7.4", + "@babel/helper-optimise-call-expression": "^7.7.4", + "@babel/traverse": "^7.7.4", + "@babel/types": "^7.7.4" } }, "@babel/helper-split-export-declaration": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", - "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.4.tgz", + "integrity": "sha512-guAg1SXFcVr04Guk9eq0S4/rWS++sbmyqosJzVs8+1fH5NI+ZcmkaSkc7dmtAFbHFva6yRJnjW3yAcGxjueDug==", "requires": { - "@babel/types": "^7.4.4" + "@babel/types": "^7.7.4" } }, "@babel/parser": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.2.tgz", - "integrity": "sha512-mdFqWrSPCmikBoaBYMuBulzTIKuXVPtEISFbRRVNwMWpCms/hmE2kRq0bblUHaNRKrjRlmVbx1sDHmjmRgD2Xg==" + "version": "7.7.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.5.tgz", + "integrity": "sha512-KNlOe9+/nk4i29g0VXgl8PEXIRms5xKLJeuZ6UptN0fHv+jDiriG+y94X6qAgWTR0h3KaoM1wK5G5h7MHFRSig==" + }, + "@babel/template": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.4.tgz", + "integrity": "sha512-qUzihgVPguAzXCK7WXw8pqs6cEwi54s3E+HrejlkuWO6ivMKx9hZl3Y2fSXp9i5HgyWmj7RKP+ulaYnKM4yYxw==", + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.7.4", + "@babel/types": "^7.7.4" + } }, "@babel/traverse": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.2.tgz", - "integrity": "sha512-8fRE76xNwNttVEF2TwxJDGBLWthUkHWSldmfuBzVRmEDWOtu4XdINTgN7TDWzuLg4bbeIMLvfMFD9we5YcWkRQ==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.4.tgz", + "integrity": "sha512-P1L58hQyupn8+ezVA2z5KBm4/Zr4lCC8dwKCMYzsa5jFMDMQAzaBNy9W5VjB+KAmBjb40U7a/H6ao+Xo+9saIw==", "requires": { "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.6.2", - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.6.2", - "@babel/types": "^7.6.0", + "@babel/generator": "^7.7.4", + "@babel/helper-function-name": "^7.7.4", + "@babel/helper-split-export-declaration": "^7.7.4", + "@babel/parser": "^7.7.4", + "@babel/types": "^7.7.4", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", + "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", + "requires": { + "@babel/highlight": "^7.0.0" + } + } } }, "@babel/types": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.1.tgz", - "integrity": "sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz", + "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==", "requires": { "esutils": "^2.0.2", "lodash": "^4.17.13", "to-fast-properties": "^2.0.0" } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" } } }, @@ -804,18 +911,19 @@ } }, "@babel/plugin-proposal-dynamic-import": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.5.0.tgz", - "integrity": "sha512-x/iMjggsKTFHYC6g11PL7Qy58IK8H5zqfm9e6hu4z1iH2IRyAp9u9dL80zA6R76yFovETFLKz2VJIC2iIPBuFw==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.7.4.tgz", + "integrity": "sha512-StH+nGAdO6qDB1l8sZ5UBV8AC3F2VW2I8Vfld73TMKyptMU9DY5YsJAS8U81+vEtxcH3Y/La0wG0btDrhpnhjQ==", "requires": { "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-dynamic-import": "^7.2.0" + "@babel/plugin-syntax-dynamic-import": "^7.7.4" } }, "@babel/plugin-proposal-json-strings": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz", "integrity": "sha512-MAFV1CA/YVmYwZG0fBQyXhmj0BHCB5egZHCKWIFVv/XCxAeVGIHfos3SwDck4LvCllENIAg7xMKOG5kH0dzyUg==", + "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-syntax-json-strings": "^7.2.0" @@ -835,6 +943,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz", "integrity": "sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g==", + "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-syntax-optional-catch-binding": "^7.2.0" @@ -855,6 +964,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz", "integrity": "sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg==", + "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -869,9 +979,9 @@ } }, "@babel/plugin-syntax-dynamic-import": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.2.0.tgz", - "integrity": "sha512-mVxuJ0YroI/h/tbFTPGZR8cv6ai+STMKNBq0f8hFxsxWjl94qqhsb+wXbpNMDPU3cfR1TIsVFzU3nXyZMqyK4w==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.7.4.tgz", + "integrity": "sha512-jHQW0vbRGvwQNgyVxwDh4yuXu4bH1f5/EICJLAhl1SblLs2CDhrsmCk+v5XLdE9wxtAFRyxx+P//Iw+a5L/tTg==", "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -889,6 +999,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz", "integrity": "sha512-5UGYnMSLRE1dqqZwug+1LISpA403HzlSfsg6P9VXU6TBjcSHeNlw4DxDx7LgpF+iKZoOG/+uzqoRHTdcUpiZNg==", + "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -906,6 +1017,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz", "integrity": "sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA==", + "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -914,6 +1026,15 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz", "integrity": "sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.7.4.tgz", + "integrity": "sha512-wdsOw0MvkL1UIgiQ/IFr3ETcfv1xb8RMM0H9wbiDyLaJFyiDg5oZvDLCXosIXmFeIlweML5iOBXAkqddkYNizg==", "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -931,6 +1052,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz", "integrity": "sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg==", + "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -950,6 +1072,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz", "integrity": "sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w==", + "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -1054,6 +1177,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz", "integrity": "sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA==", + "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -1091,6 +1215,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz", "integrity": "sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A==", + "dev": true, "requires": { "@babel/helper-builder-binary-assignment-operator-visitor": "^7.1.0", "@babel/helper-plugin-utils": "^7.0.0" @@ -1110,6 +1235,7 @@ "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.4.4.tgz", "integrity": "sha512-9T/5Dlr14Z9TIEXLXkt8T1DU7F24cbhwhMNUziN3hB1AXoZcdzPcTiKGRn/6iOymDqtTKWnr/BtRKN9JwbKtdQ==", + "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -1118,6 +1244,7 @@ "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.4.4.tgz", "integrity": "sha512-iU9pv7U+2jC9ANQkKeNF6DrPy4GBa4NWQtl6dHB4Pb3izX2JOEvDTFarlNsBj/63ZEzNNIAMs3Qw4fNCcSOXJA==", + "dev": true, "requires": { "@babel/helper-function-name": "^7.1.0", "@babel/helper-plugin-utils": "^7.0.0" @@ -1127,6 +1254,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz", "integrity": "sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg==", + "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -1135,6 +1263,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.2.0.tgz", "integrity": "sha512-HiU3zKkSU6scTidmnFJ0bMX8hz5ixC93b4MHMiYebmk2lUVNGOboPsqQvx5LzooihijUoLR/v7Nc1rbBtnc7FA==", + "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -1174,6 +1303,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.2.0.tgz", "integrity": "sha512-BV3bw6MyUH1iIsGhXlOK6sXhmSarZjtJ/vMiD9dNmpY8QXFFQTj+6v92pcfy1iqa8DeAfJFwoxcrS/TUZda6sw==", + "dev": true, "requires": { "@babel/helper-module-transforms": "^7.1.0", "@babel/helper-plugin-utils": "^7.0.0" @@ -1192,6 +1322,7 @@ "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.4.4.tgz", "integrity": "sha512-r1z3T2DNGQwwe2vPGZMBNjioT2scgWzK9BCnDEh+46z8EEwXBq24uRzd65I7pjtugzPSj921aM15RpESgzsSuA==", + "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -1210,6 +1341,7 @@ "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.4.4.tgz", "integrity": "sha512-oMh5DUO1V63nZcu/ZVLQFqiihBGo4OpxJxR1otF50GMeCLiRx5nUdtokd+u9SuVJrvvuIh9OosRFPP4pIPnwmw==", + "dev": true, "requires": { "@babel/helper-call-delegate": "^7.4.4", "@babel/helper-get-function-arity": "^7.0.0", @@ -1220,6 +1352,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.2.0.tgz", "integrity": "sha512-9q7Dbk4RhgcLp8ebduOpCbtjh7C0itoLYHXd9ueASKAG/is5PQtMR5VJGka9NKqGhYEGn5ITahd4h9QeBMylWQ==", + "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -1278,6 +1411,7 @@ "version": "7.4.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.4.5.tgz", "integrity": "sha512-gBKRh5qAaCWntnd09S8QC7r3auLCqq5DI6O0DlfoyDjslSBVqBibrMdsqO+Uhmx3+BlOmE/Kw1HFxmGbv0N9dA==", + "dev": true, "requires": { "regenerator-transform": "^0.14.0" } @@ -1286,6 +1420,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.2.0.tgz", "integrity": "sha512-fz43fqW8E1tAB3DKF19/vxbpib1fuyCwSPE418ge5ZxILnBhWyhtPgz8eh1RCGGJlwvksHkyxMxh0eenFi+kFw==", + "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -1306,6 +1441,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz", "integrity": "sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg==", + "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -1323,6 +1459,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz", "integrity": "sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw==", + "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/helper-regex": "^7.0.0" @@ -1332,6 +1469,7 @@ "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.4.4.tgz", "integrity": "sha512-mQrEC4TWkhLN0z8ygIvEL9ZEToPhG5K7KDW3pzGqOfIGZ28Jb0POUkeWcoz8HnHvhFy6dwAT1j8OzqN8s804+g==", + "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.0.0", "@babel/helper-plugin-utils": "^7.0.0" @@ -1341,6 +1479,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.2.0.tgz", "integrity": "sha512-2LNhETWYxiYysBtrBTqL8+La0jIoQQnIScUJc74OYvUGRmkskNY4EzLCnjHBzdmb38wqtTaixpo1NctEcvMDZw==", + "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -1367,288 +1506,632 @@ } }, "@babel/preset-env": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.6.2.tgz", - "integrity": "sha512-Ru7+mfzy9M1/YTEtlDS8CD45jd22ngb9tXnn64DvQK3ooyqSw9K4K9DUWmYknTTVk4TqygL9dqCrZgm1HMea/Q==", + "version": "7.7.5", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.7.5.tgz", + "integrity": "sha512-wDPbiaZdGzsJuTWlpLHJxmwslwHGLZ8F5v69zX3oAWeTOFWdy4OJHoTKg26oAnFg052v+/LAPY5os9KB0LrOEA==", "requires": { - "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-module-imports": "^7.7.4", "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-async-generator-functions": "^7.2.0", - "@babel/plugin-proposal-dynamic-import": "^7.5.0", - "@babel/plugin-proposal-json-strings": "^7.2.0", - "@babel/plugin-proposal-object-rest-spread": "^7.6.2", - "@babel/plugin-proposal-optional-catch-binding": "^7.2.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.6.2", - "@babel/plugin-syntax-async-generators": "^7.2.0", - "@babel/plugin-syntax-dynamic-import": "^7.2.0", - "@babel/plugin-syntax-json-strings": "^7.2.0", - "@babel/plugin-syntax-object-rest-spread": "^7.2.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.2.0", - "@babel/plugin-transform-arrow-functions": "^7.2.0", - "@babel/plugin-transform-async-to-generator": "^7.5.0", - "@babel/plugin-transform-block-scoped-functions": "^7.2.0", - "@babel/plugin-transform-block-scoping": "^7.6.2", - "@babel/plugin-transform-classes": "^7.5.5", - "@babel/plugin-transform-computed-properties": "^7.2.0", - "@babel/plugin-transform-destructuring": "^7.6.0", - "@babel/plugin-transform-dotall-regex": "^7.6.2", - "@babel/plugin-transform-duplicate-keys": "^7.5.0", - "@babel/plugin-transform-exponentiation-operator": "^7.2.0", - "@babel/plugin-transform-for-of": "^7.4.4", - "@babel/plugin-transform-function-name": "^7.4.4", - "@babel/plugin-transform-literals": "^7.2.0", - "@babel/plugin-transform-member-expression-literals": "^7.2.0", - "@babel/plugin-transform-modules-amd": "^7.5.0", - "@babel/plugin-transform-modules-commonjs": "^7.6.0", - "@babel/plugin-transform-modules-systemjs": "^7.5.0", - "@babel/plugin-transform-modules-umd": "^7.2.0", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.6.2", - "@babel/plugin-transform-new-target": "^7.4.4", - "@babel/plugin-transform-object-super": "^7.5.5", - "@babel/plugin-transform-parameters": "^7.4.4", - "@babel/plugin-transform-property-literals": "^7.2.0", - "@babel/plugin-transform-regenerator": "^7.4.5", - "@babel/plugin-transform-reserved-words": "^7.2.0", - "@babel/plugin-transform-shorthand-properties": "^7.2.0", - "@babel/plugin-transform-spread": "^7.6.2", - "@babel/plugin-transform-sticky-regex": "^7.2.0", - "@babel/plugin-transform-template-literals": "^7.4.4", - "@babel/plugin-transform-typeof-symbol": "^7.2.0", - "@babel/plugin-transform-unicode-regex": "^7.6.2", - "@babel/types": "^7.6.0", + "@babel/plugin-proposal-async-generator-functions": "^7.7.4", + "@babel/plugin-proposal-dynamic-import": "^7.7.4", + "@babel/plugin-proposal-json-strings": "^7.7.4", + "@babel/plugin-proposal-object-rest-spread": "^7.7.4", + "@babel/plugin-proposal-optional-catch-binding": "^7.7.4", + "@babel/plugin-proposal-unicode-property-regex": "^7.7.4", + "@babel/plugin-syntax-async-generators": "^7.7.4", + "@babel/plugin-syntax-dynamic-import": "^7.7.4", + "@babel/plugin-syntax-json-strings": "^7.7.4", + "@babel/plugin-syntax-object-rest-spread": "^7.7.4", + "@babel/plugin-syntax-optional-catch-binding": "^7.7.4", + "@babel/plugin-syntax-top-level-await": "^7.7.4", + "@babel/plugin-transform-arrow-functions": "^7.7.4", + "@babel/plugin-transform-async-to-generator": "^7.7.4", + "@babel/plugin-transform-block-scoped-functions": "^7.7.4", + "@babel/plugin-transform-block-scoping": "^7.7.4", + "@babel/plugin-transform-classes": "^7.7.4", + "@babel/plugin-transform-computed-properties": "^7.7.4", + "@babel/plugin-transform-destructuring": "^7.7.4", + "@babel/plugin-transform-dotall-regex": "^7.7.4", + "@babel/plugin-transform-duplicate-keys": "^7.7.4", + "@babel/plugin-transform-exponentiation-operator": "^7.7.4", + "@babel/plugin-transform-for-of": "^7.7.4", + "@babel/plugin-transform-function-name": "^7.7.4", + "@babel/plugin-transform-literals": "^7.7.4", + "@babel/plugin-transform-member-expression-literals": "^7.7.4", + "@babel/plugin-transform-modules-amd": "^7.7.5", + "@babel/plugin-transform-modules-commonjs": "^7.7.5", + "@babel/plugin-transform-modules-systemjs": "^7.7.4", + "@babel/plugin-transform-modules-umd": "^7.7.4", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.7.4", + "@babel/plugin-transform-new-target": "^7.7.4", + "@babel/plugin-transform-object-super": "^7.7.4", + "@babel/plugin-transform-parameters": "^7.7.4", + "@babel/plugin-transform-property-literals": "^7.7.4", + "@babel/plugin-transform-regenerator": "^7.7.5", + "@babel/plugin-transform-reserved-words": "^7.7.4", + "@babel/plugin-transform-shorthand-properties": "^7.7.4", + "@babel/plugin-transform-spread": "^7.7.4", + "@babel/plugin-transform-sticky-regex": "^7.7.4", + "@babel/plugin-transform-template-literals": "^7.7.4", + "@babel/plugin-transform-typeof-symbol": "^7.7.4", + "@babel/plugin-transform-unicode-regex": "^7.7.4", + "@babel/types": "^7.7.4", "browserslist": "^4.6.0", - "core-js-compat": "^3.1.1", + "core-js-compat": "^3.4.7", "invariant": "^2.2.2", "js-levenshtein": "^1.1.3", "semver": "^5.5.0" }, "dependencies": { - "@babel/code-frame": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", - "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", - "requires": { - "@babel/highlight": "^7.0.0" - } - }, "@babel/generator": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.2.tgz", - "integrity": "sha512-j8iHaIW4gGPnViaIHI7e9t/Hl8qLjERI6DcV9kEpAIDJsAOrcnXqRS7t+QbhL76pwbtqP+QCQLL0z1CyVmtjjQ==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.4.tgz", + "integrity": "sha512-m5qo2WgdOJeyYngKImbkyQrnUN1mPceaG5BV+G0E3gWsa4l/jCSryWJdM2x8OuGAOyh+3d5pVYfZWCiNFtynxg==", "requires": { - "@babel/types": "^7.6.0", + "@babel/types": "^7.7.4", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" } }, + "@babel/helper-annotate-as-pure": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.7.4.tgz", + "integrity": "sha512-2BQmQgECKzYKFPpiycoF9tlb5HA4lrVyAmLLVK177EcQAqjVLciUb2/R+n1boQ9y5ENV3uz2ZqiNw7QMBBw1Og==", + "requires": { + "@babel/types": "^7.7.4" + } + }, + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.7.4.tgz", + "integrity": "sha512-Biq/d/WtvfftWZ9Uf39hbPBYDUo986m5Bb4zhkeYDGUllF43D+nUe5M6Vuo6/8JDK/0YX/uBdeoQpyaNhNugZQ==", + "requires": { + "@babel/helper-explode-assignable-expression": "^7.7.4", + "@babel/types": "^7.7.4" + } + }, + "@babel/helper-call-delegate": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.7.4.tgz", + "integrity": "sha512-8JH9/B7J7tCYJ2PpWVpw9JhPuEVHztagNVuQAFBVFYluRMlpG7F1CgKEgGeL6KFqcsIa92ZYVj6DSc0XwmN1ZA==", + "requires": { + "@babel/helper-hoist-variables": "^7.7.4", + "@babel/traverse": "^7.7.4", + "@babel/types": "^7.7.4" + } + }, "@babel/helper-define-map": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.5.5.tgz", - "integrity": "sha512-fTfxx7i0B5NJqvUOBBGREnrqbTxRh7zinBANpZXAVDlsZxYdclDp467G1sQ8VZYMnAURY3RpBUAgOYT9GfzHBg==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.7.4.tgz", + "integrity": "sha512-v5LorqOa0nVQUvAUTUF3KPastvUt/HzByXNamKQ6RdJRTV7j8rLL+WB5C/MzzWAwOomxDhYFb1wLLxHqox86lg==", "requires": { - "@babel/helper-function-name": "^7.1.0", - "@babel/types": "^7.5.5", + "@babel/helper-function-name": "^7.7.4", + "@babel/types": "^7.7.4", "lodash": "^4.17.13" } }, + "@babel/helper-explode-assignable-expression": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.7.4.tgz", + "integrity": "sha512-2/SicuFrNSXsZNBxe5UGdLr+HZg+raWBLE9vC98bdYOKX/U6PY0mdGlYUJdtTDPSU0Lw0PNbKKDpwYHJLn2jLg==", + "requires": { + "@babel/traverse": "^7.7.4", + "@babel/types": "^7.7.4" + } + }, + "@babel/helper-function-name": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.4.tgz", + "integrity": "sha512-AnkGIdiBhEuiwdoMnKm7jfPfqItZhgRaZfMg1XX3bS25INOnLPjPG1Ppnajh8eqgt5kPJnfqrRHqFqmjKDZLzQ==", + "requires": { + "@babel/helper-get-function-arity": "^7.7.4", + "@babel/template": "^7.7.4", + "@babel/types": "^7.7.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.4.tgz", + "integrity": "sha512-QTGKEdCkjgzgfJ3bAyRwF4yyT3pg+vDgan8DSivq1eS0gwi+KGKE5x8kRcbeFTb/673mkO5SN1IZfmCfA5o+EA==", + "requires": { + "@babel/types": "^7.7.4" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.7.4.tgz", + "integrity": "sha512-wQC4xyvc1Jo/FnLirL6CEgPgPCa8M74tOdjWpRhQYapz5JC7u3NYU1zCVoVAGCE3EaIP9T1A3iW0WLJ+reZlpQ==", + "requires": { + "@babel/types": "^7.7.4" + } + }, "@babel/helper-member-expression-to-functions": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.5.5.tgz", - "integrity": "sha512-5qZ3D1uMclSNqYcXqiHoA0meVdv+xUEex9em2fqMnrk/scphGlGgg66zjMrPJESPwrFJ6sbfFQYUSa0Mz7FabA==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.7.4.tgz", + "integrity": "sha512-9KcA1X2E3OjXl/ykfMMInBK+uVdfIVakVe7W7Lg3wfXUNyS3Q1HWLFRwZIjhqiCGbslummPDnmb7vIekS0C1vw==", + "requires": { + "@babel/types": "^7.7.4" + } + }, + "@babel/helper-module-imports": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.7.4.tgz", + "integrity": "sha512-dGcrX6K9l8258WFjyDLJwuVKxR4XZfU0/vTUgOQYWEnRD8mgr+p4d6fCUMq/ys0h4CCt/S5JhbvtyErjWouAUQ==", "requires": { - "@babel/types": "^7.5.5" + "@babel/types": "^7.7.4" + } + }, + "@babel/helper-module-transforms": { + "version": "7.7.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.7.5.tgz", + "integrity": "sha512-A7pSxyJf1gN5qXVcidwLWydjftUN878VkalhXX5iQDuGyiGK3sOrrKKHF4/A4fwHtnsotv/NipwAeLzY4KQPvw==", + "requires": { + "@babel/helper-module-imports": "^7.7.4", + "@babel/helper-simple-access": "^7.7.4", + "@babel/helper-split-export-declaration": "^7.7.4", + "@babel/template": "^7.7.4", + "@babel/types": "^7.7.4", + "lodash": "^4.17.13" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.7.4.tgz", + "integrity": "sha512-VB7gWZ2fDkSuqW6b1AKXkJWO5NyNI3bFL/kK79/30moK57blr6NbH8xcl2XcKCwOmJosftWunZqfO84IGq3ZZg==", + "requires": { + "@babel/types": "^7.7.4" + } + }, + "@babel/helper-remap-async-to-generator": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.7.4.tgz", + "integrity": "sha512-Sk4xmtVdM9sA/jCI80f+KS+Md+ZHIpjuqmYPk1M7F/upHou5e4ReYmExAiu6PVe65BhJPZA2CY9x9k4BqE5klw==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.7.4", + "@babel/helper-wrap-function": "^7.7.4", + "@babel/template": "^7.7.4", + "@babel/traverse": "^7.7.4", + "@babel/types": "^7.7.4" } }, "@babel/helper-replace-supers": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.5.5.tgz", - "integrity": "sha512-XvRFWrNnlsow2u7jXDuH4jDDctkxbS7gXssrP4q2nUD606ukXHRvydj346wmNg+zAgpFx4MWf4+usfC93bElJg==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.7.4.tgz", + "integrity": "sha512-pP0tfgg9hsZWo5ZboYGuBn/bbYT/hdLPVSS4NMmiRJdwWhP0IznPwN9AE1JwyGsjSPLC364I0Qh5p+EPkGPNpg==", "requires": { - "@babel/helper-member-expression-to-functions": "^7.5.5", - "@babel/helper-optimise-call-expression": "^7.0.0", - "@babel/traverse": "^7.5.5", - "@babel/types": "^7.5.5" + "@babel/helper-member-expression-to-functions": "^7.7.4", + "@babel/helper-optimise-call-expression": "^7.7.4", + "@babel/traverse": "^7.7.4", + "@babel/types": "^7.7.4" + } + }, + "@babel/helper-simple-access": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.7.4.tgz", + "integrity": "sha512-zK7THeEXfan7UlWsG2A6CI/L9jVnI5+xxKZOdej39Y0YtDYKx9raHk5F2EtK9K8DHRTihYwg20ADt9S36GR78A==", + "requires": { + "@babel/template": "^7.7.4", + "@babel/types": "^7.7.4" } }, "@babel/helper-split-export-declaration": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", - "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.4.tgz", + "integrity": "sha512-guAg1SXFcVr04Guk9eq0S4/rWS++sbmyqosJzVs8+1fH5NI+ZcmkaSkc7dmtAFbHFva6yRJnjW3yAcGxjueDug==", "requires": { - "@babel/types": "^7.4.4" + "@babel/types": "^7.7.4" + } + }, + "@babel/helper-wrap-function": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.7.4.tgz", + "integrity": "sha512-VsfzZt6wmsocOaVU0OokwrIytHND55yvyT4BPB9AIIgwr8+x7617hetdJTsuGwygN5RC6mxA9EJztTjuwm2ofg==", + "requires": { + "@babel/helper-function-name": "^7.7.4", + "@babel/template": "^7.7.4", + "@babel/traverse": "^7.7.4", + "@babel/types": "^7.7.4" } }, "@babel/parser": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.2.tgz", - "integrity": "sha512-mdFqWrSPCmikBoaBYMuBulzTIKuXVPtEISFbRRVNwMWpCms/hmE2kRq0bblUHaNRKrjRlmVbx1sDHmjmRgD2Xg==" + "version": "7.7.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.5.tgz", + "integrity": "sha512-KNlOe9+/nk4i29g0VXgl8PEXIRms5xKLJeuZ6UptN0fHv+jDiriG+y94X6qAgWTR0h3KaoM1wK5G5h7MHFRSig==" + }, + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.7.4.tgz", + "integrity": "sha512-1ypyZvGRXriY/QP668+s8sFr2mqinhkRDMPSQLNghCQE+GAkFtp+wkHVvg2+Hdki8gwP+NFzJBJ/N1BfzCCDEw==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-remap-async-to-generator": "^7.7.4", + "@babel/plugin-syntax-async-generators": "^7.7.4" + } + }, + "@babel/plugin-proposal-json-strings": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.7.4.tgz", + "integrity": "sha512-wQvt3akcBTfLU/wYoqm/ws7YOAQKu8EVJEvHip/mzkNtjaclQoCCIqKXFP5/eyfnfbQCDV3OLRIK3mIVyXuZlw==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-json-strings": "^7.7.4" + } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.6.2.tgz", - "integrity": "sha512-LDBXlmADCsMZV1Y9OQwMc0MyGZ8Ta/zlD9N67BfQT8uYwkRswiu2hU6nJKrjrt/58aH/vqfQlR/9yId/7A2gWw==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.7.4.tgz", + "integrity": "sha512-rnpnZR3/iWKmiQyJ3LKJpSwLDcX/nSXhdLk4Aq/tXOApIvyu7qoabrige0ylsAJffaUC51WiBu209Q0U+86OWQ==", "requires": { "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-object-rest-spread": "^7.2.0" + "@babel/plugin-syntax-object-rest-spread": "^7.7.4" } }, - "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.6.2.tgz", - "integrity": "sha512-NxHETdmpeSCtiatMRYWVJo7266rrvAC3DTeG5exQBIH/fMIUK7ejDNznBbn3HQl/o9peymRRg7Yqkx6PdUXmMw==", + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.7.4.tgz", + "integrity": "sha512-DyM7U2bnsQerCQ+sejcTNZh8KQEUuC3ufzdnVnSiUv/qoGJp2Z3hanKL18KDhsBT5Wj6a7CMT5mdyCNJsEaA9w==", "requires": { "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-regex": "^7.4.4", - "regexpu-core": "^4.6.0" + "@babel/plugin-syntax-optional-catch-binding": "^7.7.4" + } + }, + "@babel/plugin-proposal-unicode-property-regex": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.7.4.tgz", + "integrity": "sha512-cHgqHgYvffluZk85dJ02vloErm3Y6xtH+2noOBOJ2kXOJH3aVCDnj5eR/lVNlTnYu4hndAPJD3rTFjW3qee0PA==", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.7.4", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.7.4.tgz", + "integrity": "sha512-Li4+EjSpBgxcsmeEF8IFcfV/+yJGxHXDirDkEoyFjumuwbmfCVHUt0HuowD/iGM7OhIRyXJH9YXxqiH6N815+g==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.7.4.tgz", + "integrity": "sha512-QpGupahTQW1mHRXddMG5srgpHWqRLwJnJZKXTigB9RPFCCGbDGCgBeM/iC82ICXp414WeYx/tD54w7M2qRqTMg==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.7.4.tgz", + "integrity": "sha512-mObR+r+KZq0XhRVS2BrBKBpr5jqrqzlPvS9C9vuOf5ilSwzloAl7RPWLrgKdWS6IreaVrjHxTjtyqFiOisaCwg==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.7.4.tgz", + "integrity": "sha512-4ZSuzWgFxqHRE31Glu+fEr/MirNZOMYmD/0BhBWyLyOOQz/gTAl7QmWm2hX1QxEIXsr2vkdlwxIzTyiYRC4xcQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.7.4.tgz", + "integrity": "sha512-zUXy3e8jBNPiffmqkHRNDdZM2r8DWhCB7HhcoyZjiK1TxYEluLHAvQuYnTT+ARqRpabWqy/NHkO6e3MsYB5YfA==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-async-to-generator": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.5.0.tgz", - "integrity": "sha512-mqvkzwIGkq0bEF1zLRRiTdjfomZJDV33AH3oQzHVGkI2VzEmXLpKKOBvEVaFZBJdN0XTyH38s9j/Kiqr68dggg==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.7.4.tgz", + "integrity": "sha512-zpUTZphp5nHokuy8yLlyafxCJ0rSlFoSHypTUWgpdwoDXWQcseaect7cJ8Ppk6nunOM6+5rPMkod4OYKPR5MUg==", "requires": { - "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-module-imports": "^7.7.4", "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-remap-async-to-generator": "^7.1.0" + "@babel/helper-remap-async-to-generator": "^7.7.4" + } + }, + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.7.4.tgz", + "integrity": "sha512-kqtQzwtKcpPclHYjLK//3lH8OFsCDuDJBaFhVwf8kqdnF6MN4l618UDlcA7TfRs3FayrHj+svYnSX8MC9zmUyQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-block-scoping": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.6.2.tgz", - "integrity": "sha512-zZT8ivau9LOQQaOGC7bQLQOT4XPkPXgN2ERfUgk1X8ql+mVkLc4E8eKk+FO3o0154kxzqenWCorfmEXpEZcrSQ==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.7.4.tgz", + "integrity": "sha512-2VBe9u0G+fDt9B5OV5DQH4KBf5DoiNkwFKOz0TCvBWvdAN2rOykCTkrL+jTLxfCAm76l9Qo5OqL7HBOx2dWggg==", "requires": { "@babel/helper-plugin-utils": "^7.0.0", "lodash": "^4.17.13" } }, "@babel/plugin-transform-classes": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.5.5.tgz", - "integrity": "sha512-U2htCNK/6e9K7jGyJ++1p5XRU+LJjrwtoiVn9SzRlDT2KubcZ11OOwy3s24TjHxPgxNwonCYP7U2K51uVYCMDg==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.0.0", - "@babel/helper-define-map": "^7.5.5", - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-optimise-call-expression": "^7.0.0", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.7.4.tgz", + "integrity": "sha512-sK1mjWat7K+buWRuImEzjNf68qrKcrddtpQo3swi9j7dUcG6y6R6+Di039QN2bD1dykeswlagupEmpOatFHHUg==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.7.4", + "@babel/helper-define-map": "^7.7.4", + "@babel/helper-function-name": "^7.7.4", + "@babel/helper-optimise-call-expression": "^7.7.4", "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.5.5", - "@babel/helper-split-export-declaration": "^7.4.4", + "@babel/helper-replace-supers": "^7.7.4", + "@babel/helper-split-export-declaration": "^7.7.4", "globals": "^11.1.0" } }, + "@babel/plugin-transform-computed-properties": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.7.4.tgz", + "integrity": "sha512-bSNsOsZnlpLLyQew35rl4Fma3yKWqK3ImWMSC/Nc+6nGjC9s5NFWAer1YQ899/6s9HxO2zQC1WoFNfkOqRkqRQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, "@babel/plugin-transform-destructuring": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.6.0.tgz", - "integrity": "sha512-2bGIS5P1v4+sWTCnKNDZDxbGvEqi0ijeqM/YqHtVGrvG2y0ySgnEEhXErvE9dA0bnIzY9bIzdFK0jFA46ASIIQ==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.7.4.tgz", + "integrity": "sha512-4jFMXI1Cu2aXbcXXl8Lr6YubCn6Oc7k9lLsu8v61TZh+1jny2BWmdtvY9zSUlLdGUvcy9DMAWyZEOqjsbeg/wA==", "requires": { "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-dotall-regex": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.6.2.tgz", - "integrity": "sha512-KGKT9aqKV+9YMZSkowzYoYEiHqgaDhGmPNZlZxX6UeHC4z30nC1J9IrZuGqbYFB1jaIGdv91ujpze0exiVK8bA==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.7.4.tgz", + "integrity": "sha512-mk0cH1zyMa/XHeb6LOTXTbG7uIJ8Rrjlzu91pUx/KS3JpcgaTDwMS8kM+ar8SLOvlL2Lofi4CGBAjCo3a2x+lw==", "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-regex": "^7.4.4", - "regexpu-core": "^4.6.0" + "@babel/helper-create-regexp-features-plugin": "^7.7.4", + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-duplicate-keys": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.5.0.tgz", - "integrity": "sha512-igcziksHizyQPlX9gfSjHkE2wmoCH3evvD2qR5w29/Dk0SMKE/eOI7f1HhBdNhR/zxJDqrgpoDTq5YSLH/XMsQ==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.7.4.tgz", + "integrity": "sha512-g1y4/G6xGWMD85Tlft5XedGaZBCIVN+/P0bs6eabmcPP9egFleMAo65OOjlhcz1njpwagyY3t0nsQC9oTFegJA==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.7.4.tgz", + "integrity": "sha512-MCqiLfCKm6KEA1dglf6Uqq1ElDIZwFuzz1WH5mTf8k2uQSxEJMbOIEh7IZv7uichr7PMfi5YVSrr1vz+ipp7AQ==", + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.7.4", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-for-of": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.7.4.tgz", + "integrity": "sha512-zZ1fD1B8keYtEcKF+M1TROfeHTKnijcVQm0yO/Yu1f7qoDoxEIc/+GX6Go430Bg84eM/xwPFp0+h4EbZg7epAA==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-function-name": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.7.4.tgz", + "integrity": "sha512-E/x09TvjHNhsULs2IusN+aJNRV5zKwxu1cpirZyRPw+FyyIKEHPXTsadj48bVpc1R5Qq1B5ZkzumuFLytnbT6g==", + "requires": { + "@babel/helper-function-name": "^7.7.4", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-literals": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.7.4.tgz", + "integrity": "sha512-X2MSV7LfJFm4aZfxd0yLVFrEXAgPqYoDG53Br/tCKiKYfX0MjVjQeWPIhPHHsCqzwQANq+FLN786fF5rgLS+gw==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-member-expression-literals": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.7.4.tgz", + "integrity": "sha512-9VMwMO7i69LHTesL0RdGy93JU6a+qOPuvB4F4d0kR0zyVjJRVJRaoaGjhtki6SzQUu8yen/vxPKN6CWnCUw6bA==", "requires": { "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-modules-amd": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.5.0.tgz", - "integrity": "sha512-n20UsQMKnWrltocZZm24cRURxQnWIvsABPJlw/fvoy9c6AgHZzoelAIzajDHAQrDpuKFFPPcFGd7ChsYuIUMpg==", + "version": "7.7.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.7.5.tgz", + "integrity": "sha512-CT57FG4A2ZUNU1v+HdvDSDrjNWBrtCmSH6YbbgN3Lrf0Di/q/lWRxZrE72p3+HCCz9UjfZOEBdphgC0nzOS6DQ==", "requires": { - "@babel/helper-module-transforms": "^7.1.0", + "@babel/helper-module-transforms": "^7.7.5", "@babel/helper-plugin-utils": "^7.0.0", "babel-plugin-dynamic-import-node": "^2.3.0" } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.6.0.tgz", - "integrity": "sha512-Ma93Ix95PNSEngqomy5LSBMAQvYKVe3dy+JlVJSHEXZR5ASL9lQBedMiCyVtmTLraIDVRE3ZjTZvmXXD2Ozw3g==", + "version": "7.7.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.7.5.tgz", + "integrity": "sha512-9Cq4zTFExwFhQI6MT1aFxgqhIsMWQWDVwOgLzl7PTWJHsNaqFvklAU+Oz6AQLAS0dJKTwZSOCo20INwktxpi3Q==", "requires": { - "@babel/helper-module-transforms": "^7.4.4", + "@babel/helper-module-transforms": "^7.7.5", "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-simple-access": "^7.1.0", + "@babel/helper-simple-access": "^7.7.4", "babel-plugin-dynamic-import-node": "^2.3.0" } }, "@babel/plugin-transform-modules-systemjs": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.5.0.tgz", - "integrity": "sha512-Q2m56tyoQWmuNGxEtUyeEkm6qJYFqs4c+XyXH5RAuYxObRNz9Zgj/1g2GMnjYp2EUyEy7YTrxliGCXzecl/vJg==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.7.4.tgz", + "integrity": "sha512-y2c96hmcsUi6LrMqvmNDPBBiGCiQu0aYqpHatVVu6kD4mFEXKjyNxd/drc18XXAf9dv7UXjrZwBVmTTGaGP8iw==", "requires": { - "@babel/helper-hoist-variables": "^7.4.4", + "@babel/helper-hoist-variables": "^7.7.4", "@babel/helper-plugin-utils": "^7.0.0", "babel-plugin-dynamic-import-node": "^2.3.0" } }, + "@babel/plugin-transform-modules-umd": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.7.4.tgz", + "integrity": "sha512-u2B8TIi0qZI4j8q4C51ktfO7E3cQ0qnaXFI1/OXITordD40tt17g/sXqgNNCcMTcBFKrUPcGDx+TBJuZxLx7tw==", + "requires": { + "@babel/helper-module-transforms": "^7.7.4", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.6.2.tgz", - "integrity": "sha512-xBdB+XOs+lgbZc2/4F5BVDVcDNS4tcSKQc96KmlqLEAwz6tpYPEvPdmDfvVG0Ssn8lAhronaRs6Z6KSexIpK5g==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.7.4.tgz", + "integrity": "sha512-jBUkiqLKvUWpv9GLSuHUFYdmHg0ujC1JEYoZUfeOOfNydZXp1sXObgyPatpcwjWgsdBGsagWW0cdJpX/DO2jMw==", "requires": { - "regexpu-core": "^4.6.0" + "@babel/helper-create-regexp-features-plugin": "^7.7.4" + } + }, + "@babel/plugin-transform-new-target": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.7.4.tgz", + "integrity": "sha512-CnPRiNtOG1vRodnsyGX37bHQleHE14B9dnnlgSeEs3ek3fHN1A1SScglTCg1sfbe7sRQ2BUcpgpTpWSfMKz3gg==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-object-super": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.5.5.tgz", - "integrity": "sha512-un1zJQAhSosGFBduPgN/YFNvWVpRuHKU7IHBglLoLZsGmruJPOo6pbInneflUdmq7YvSVqhpPs5zdBvLnteltQ==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.7.4.tgz", + "integrity": "sha512-ho+dAEhC2aRnff2JCA0SAK7V2R62zJd/7dmtoe7MHcso4C2mS+vZjn1Pb1pCVZvJs1mgsvv5+7sT+m3Bysb6eg==", "requires": { "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.5.5" + "@babel/helper-replace-supers": "^7.7.4" + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.7.4.tgz", + "integrity": "sha512-VJwhVePWPa0DqE9vcfptaJSzNDKrWU/4FbYCjZERtmqEs05g3UMXnYMZoXja7JAJ7Y7sPZipwm/pGApZt7wHlw==", + "requires": { + "@babel/helper-call-delegate": "^7.7.4", + "@babel/helper-get-function-arity": "^7.7.4", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-property-literals": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.7.4.tgz", + "integrity": "sha512-MatJhlC4iHsIskWYyawl53KuHrt+kALSADLQQ/HkhTjX954fkxIEh4q5slL4oRAnsm/eDoZ4q0CIZpcqBuxhJQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-regenerator": { + "version": "7.7.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.7.5.tgz", + "integrity": "sha512-/8I8tPvX2FkuEyWbjRCt4qTAgZK0DVy8QRguhA524UH48RfGJy94On2ri+dCuwOpcerPRl9O4ebQkRcVzIaGBw==", + "requires": { + "regenerator-transform": "^0.14.0" + } + }, + "@babel/plugin-transform-reserved-words": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.7.4.tgz", + "integrity": "sha512-OrPiUB5s5XvkCO1lS7D8ZtHcswIC57j62acAnJZKqGGnHP+TIc/ljQSrgdX/QyOTdEK5COAhuc820Hi1q2UgLQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-shorthand-properties": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.7.4.tgz", + "integrity": "sha512-q+suddWRfIcnyG5YiDP58sT65AJDZSUhXQDZE3r04AuqD6d/XLaQPPXSBzP2zGerkgBivqtQm9XKGLuHqBID6Q==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-spread": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.6.2.tgz", - "integrity": "sha512-DpSvPFryKdK1x+EDJYCy28nmAaIMdxmhot62jAXF/o99iA33Zj2Lmcp3vDmz+MUh0LNYVPvfj5iC3feb3/+PFg==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.7.4.tgz", + "integrity": "sha512-8OSs0FLe5/80cndziPlg4R0K6HcWSM0zyNhHhLsmw/Nc5MaA49cAsnoJ/t/YZf8qkG7fD+UjTRaApVDB526d7Q==", "requires": { "@babel/helper-plugin-utils": "^7.0.0" } }, - "@babel/plugin-transform-unicode-regex": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.6.2.tgz", - "integrity": "sha512-orZI6cWlR3nk2YmYdb0gImrgCUwb5cBUwjf6Ks6dvNVvXERkwtJWOQaEOjPiu0Gu1Tq6Yq/hruCZZOOi9F34Dw==", + "@babel/plugin-transform-sticky-regex": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.7.4.tgz", + "integrity": "sha512-Ls2NASyL6qtVe1H1hXts9yuEeONV2TJZmplLONkMPUG158CtmnrzW5Q5teibM5UVOFjG0D3IC5mzXR6pPpUY7A==", "requires": { "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-regex": "^7.4.4", - "regexpu-core": "^4.6.0" + "@babel/helper-regex": "^7.0.0" + } + }, + "@babel/plugin-transform-template-literals": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.7.4.tgz", + "integrity": "sha512-sA+KxLwF3QwGj5abMHkHgshp9+rRz+oY9uoRil4CyLtgEuE/88dpkeWgNk5qKVsJE9iSfly3nvHapdRiIS2wnQ==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.7.4", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-typeof-symbol": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.7.4.tgz", + "integrity": "sha512-KQPUQ/7mqe2m0B8VecdyaW5XcQYaePyl9R7IsKd+irzj6jvbhoGnRE+M0aNkyAzI07VfUQ9266L5xMARitV3wg==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.7.4.tgz", + "integrity": "sha512-N77UUIV+WCvE+5yHw+oks3m18/umd7y392Zv7mYTpFqHtkpcc+QUz+gLJNTWVlWROIWeLqY0f3OjZxV5TcXnRw==", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.7.4", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/template": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.4.tgz", + "integrity": "sha512-qUzihgVPguAzXCK7WXw8pqs6cEwi54s3E+HrejlkuWO6ivMKx9hZl3Y2fSXp9i5HgyWmj7RKP+ulaYnKM4yYxw==", + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.7.4", + "@babel/types": "^7.7.4" } }, "@babel/traverse": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.2.tgz", - "integrity": "sha512-8fRE76xNwNttVEF2TwxJDGBLWthUkHWSldmfuBzVRmEDWOtu4XdINTgN7TDWzuLg4bbeIMLvfMFD9we5YcWkRQ==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.4.tgz", + "integrity": "sha512-P1L58hQyupn8+ezVA2z5KBm4/Zr4lCC8dwKCMYzsa5jFMDMQAzaBNy9W5VjB+KAmBjb40U7a/H6ao+Xo+9saIw==", "requires": { "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.6.2", - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.6.2", - "@babel/types": "^7.6.0", + "@babel/generator": "^7.7.4", + "@babel/helper-function-name": "^7.7.4", + "@babel/helper-split-export-declaration": "^7.7.4", + "@babel/parser": "^7.7.4", + "@babel/types": "^7.7.4", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", + "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", + "requires": { + "@babel/highlight": "^7.0.0" + } + } } }, "@babel/types": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.1.tgz", - "integrity": "sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz", + "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==", "requires": { "esutils": "^2.0.2", "lodash": "^4.17.13", @@ -1663,22 +2146,55 @@ "object.assign": "^4.1.0" } }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + "caniuse-lite": { + "version": "1.0.30001015", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001015.tgz", + "integrity": "sha512-/xL2AbW/XWHNu1gnIrO8UitBGoFthcsDgU9VLK1/dpsoxbaD5LscHozKze05R6WLsBvLhqv78dAPozMFQBYLbQ==" }, - "regexpu-core": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.6.0.tgz", - "integrity": "sha512-YlVaefl8P5BnFYOITTNzDvan1ulLOiXJzCNZxduTIosN17b87h3bvG9yHMoHaRuo88H4mQ06Aodj5VtYGGGiTg==", + "core-js-compat": { + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.4.7.tgz", + "integrity": "sha512-57+mgz/P/xsGdjwQYkwtBZR3LuISaxD1dEwVDtbk8xJMqAmwqaxLOvnNT7kdJ7jYE/NjNptyzXi+IQFMi/2fCw==", "requires": { - "regenerate": "^1.4.0", - "regenerate-unicode-properties": "^8.1.0", - "regjsgen": "^0.5.0", - "regjsparser": "^0.6.0", - "unicode-match-property-ecmascript": "^1.0.4", - "unicode-match-property-value-ecmascript": "^1.1.0" + "browserslist": "^4.8.0", + "semver": "^6.3.0" + }, + "dependencies": { + "browserslist": { + "version": "4.8.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.8.2.tgz", + "integrity": "sha512-+M4oeaTplPm/f1pXDw84YohEv7B1i/2Aisei8s4s6k3QsoSHa7i5sz8u/cGQkkatCPxMASKxPualR4wwYgVboA==", + "requires": { + "caniuse-lite": "^1.0.30001015", + "electron-to-chromium": "^1.3.322", + "node-releases": "^1.1.42" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "electron-to-chromium": { + "version": "1.3.322", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.322.tgz", + "integrity": "sha512-Tc8JQEfGQ1MzfSzI/bTlSr7btJv/FFO7Yh6tanqVmIWOuNCu6/D1MilIEgLtmWqIrsv+o4IjpLAhgMBr/ncNAA==" + }, + "node-releases": { + "version": "1.1.42", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.42.tgz", + "integrity": "sha512-OQ/ESmUqGawI2PRX+XIRao44qWYBBfN54ImQYdWVTQqUckuejOg76ysSqDBK8NG3zwySRVnX36JwDQ6x+9GxzA==", + "requires": { + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } } } } @@ -1707,23 +2223,33 @@ } }, "@babel/register": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.6.2.tgz", - "integrity": "sha512-xgZk2LRZvt6i2SAUWxc7ellk4+OYRgS3Zpsnr13nMS1Qo25w21Uu8o6vTOAqNaxiqrnv30KTYzh9YWY2k21CeQ==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.7.4.tgz", + "integrity": "sha512-/fmONZqL6ZMl9KJUYajetCrID6m0xmL4odX7v+Xvoxcv0DdbP/oO0TWIeLUCHqczQ6L6njDMqmqHFy2cp3FFsA==", "dev": true, "requires": { "find-cache-dir": "^2.0.0", "lodash": "^4.17.13", - "mkdirp": "^0.5.1", + "make-dir": "^2.1.0", "pirates": "^4.0.0", - "source-map-support": "^0.5.9" + "source-map-support": "^0.5.16" }, "dependencies": { - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true + }, + "source-map-support": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", + "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } } } }, @@ -1739,6 +2265,7 @@ "version": "7.2.2", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.2.2.tgz", "integrity": "sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g==", + "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "@babel/parser": "^7.2.2", @@ -1749,6 +2276,7 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.2.3.tgz", "integrity": "sha512-Z31oUD/fJvEWVR0lNZtfgvVt512ForCTNKYcJBGbPb1QZfve4WGH8Wsy7+Mev33/45fhP/hwQtvgusNdcCMgSw==", + "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "@babel/generator": "^7.2.2", @@ -1765,6 +2293,7 @@ "version": "7.3.0", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.3.0.tgz", "integrity": "sha512-QkFPw68QqWU1/RVPyBe8SO7lXbPfjtqAxRYQKpFpaB8yMq7X2qAqfwK5LKoQufEkSmO5NQ70O6Kc3Afk03RwXw==", + "dev": true, "requires": { "esutils": "^2.0.2", "lodash": "^4.17.10", @@ -3349,6 +3878,15 @@ "@babel/helper-plugin-utils": "^7.0.0" } }, + "@babel/plugin-syntax-dynamic-import": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.2.0.tgz", + "integrity": "sha512-mVxuJ0YroI/h/tbFTPGZR8cv6ai+STMKNBq0f8hFxsxWjl94qqhsb+wXbpNMDPU3cfR1TIsVFzU3nXyZMqyK4w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, "@babel/preset-env": { "version": "7.4.3", "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.4.3.tgz", @@ -3593,6 +4131,18 @@ "tweetnacl": "^0.14.3" } }, + "bfj": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/bfj/-/bfj-6.1.2.tgz", + "integrity": "sha512-BmBJa4Lip6BPRINSZ0BPEIfB1wUY/9rwbwvIHQA1KjX9om29B6id0wnWXq7m3bn5JrUVjeOTnVuhPT1FiHwPGw==", + "dev": true, + "requires": { + "bluebird": "^3.5.5", + "check-types": "^8.0.3", + "hoopy": "^0.1.4", + "tryer": "^1.0.1" + } + }, "big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", @@ -3936,9 +4486,9 @@ "dev": true }, "bulma": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/bulma/-/bulma-0.6.0.tgz", - "integrity": "sha1-T1xd5YKBDRGqDPsfMK7Ip5LQ2Sw=" + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/bulma/-/bulma-0.8.0.tgz", + "integrity": "sha512-nhf3rGyiZh/VM7FrSJ/5KeLlfaFkXz0nYcXriynfPH4vVpnxnqyEwaNGdNCVzHyyCA3cHgkQAMpdF/SFbFGZfA==" }, "bytes": { "version": "3.0.0", @@ -4108,28 +4658,21 @@ "dev": true }, "chart.js": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-2.8.0.tgz", - "integrity": "sha512-Di3wUL4BFvqI5FB5K26aQ+hvWh8wnP9A3DWGvXHVkO13D3DSnaSsdZx29cXlEsYKVkn1E2az+ZYFS4t0zi8x0w==", + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-2.9.3.tgz", + "integrity": "sha512-+2jlOobSk52c1VU6fzkh3UwqHMdSlgH1xFv9FKMqHiNCpXsGPQa/+81AFa+i3jZ253Mq9aAycPwDjnn1XbRNNw==", "requires": { "chartjs-color": "^2.1.0", "moment": "^2.10.2" } }, "chartjs-color": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chartjs-color/-/chartjs-color-2.3.0.tgz", - "integrity": "sha512-hEvVheqczsoHD+fZ+tfPUE+1+RbV6b+eksp2LwAhwRTVXEjCSEavvk+Hg3H6SZfGlPh/UfmWKGIvZbtobOEm3g==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chartjs-color/-/chartjs-color-2.4.1.tgz", + "integrity": "sha512-haqOg1+Yebys/Ts/9bLo/BqUcONQOdr/hoEr2LLTRl6C5LXctUdHxsCYfvQVg5JIxITrfCNUDr4ntqmQk9+/0w==", "requires": { "chartjs-color-string": "^0.6.0", - "color-convert": "^0.5.3" - }, - "dependencies": { - "color-convert": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-0.5.3.tgz", - "integrity": "sha1-vbbGnOZg+t/+CwAHzER+G59ygr0=" - } + "color-convert": "^1.9.3" } }, "chartjs-color-string": { @@ -4140,6 +4683,12 @@ "color-name": "^1.0.0" } }, + "check-types": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/check-types/-/check-types-8.0.3.tgz", + "integrity": "sha512-YpeKZngUmG65rLudJ4taU7VLkOCTMhNl/u4ctNC56LQS/zJTyNH0Lrtwm1tfTsbLlwvlfsA2d1c8vCf/Kh2KwQ==", + "dev": true + }, "chokidar": { "version": "2.1.6", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.6.tgz", @@ -5151,6 +5700,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.1.3.tgz", "integrity": "sha512-EP018pVhgwsKHz3YoN1hTq49aRe+h017Kjz0NQz3nXV0cCRMvH3fLQl+vEPGr4r4J5sk4sU3tUC7U1aqTCeJeA==", + "dev": true, "requires": { "browserslist": "^4.6.0", "core-js-pure": "3.1.3", @@ -5160,14 +5710,16 @@ "semver": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.1.1.tgz", - "integrity": "sha512-rWYq2e5iYW+fFe/oPPtYJxYgjBm8sC4rmoGdUOgBB7VnwKt6HrL793l2voH1UlsyYZpJ4g0wfjnTEO1s1NP2eQ==" + "integrity": "sha512-rWYq2e5iYW+fFe/oPPtYJxYgjBm8sC4rmoGdUOgBB7VnwKt6HrL793l2voH1UlsyYZpJ4g0wfjnTEO1s1NP2eQ==", + "dev": true } } }, "core-js-pure": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.1.3.tgz", - "integrity": "sha512-k3JWTrcQBKqjkjI0bkfXS0lbpWPxYuHWfMMjC1VDmzU4Q58IwSbuXSo99YO/hUHlw/EB4AlfA2PVxOGkrIq6dA==" + "integrity": "sha512-k3JWTrcQBKqjkjI0bkfXS0lbpWPxYuHWfMMjC1VDmzU4Q58IwSbuXSo99YO/hUHlw/EB4AlfA2PVxOGkrIq6dA==", + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -5597,9 +6149,14 @@ } }, "date-fns": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz", - "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==" + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.10.0.tgz", + "integrity": "sha512-EhfEKevYGWhWlZbNeplfhIU/+N+x0iCIx7VzKlXma2EdQyznVlZhCptXUY+BegNpPW2kjdx15Rvq503YcXXrcA==" + }, + "date-fns-tz": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/date-fns-tz/-/date-fns-tz-1.0.10.tgz", + "integrity": "sha512-cHQAz0/9uDABaUNDM80Mj1FL4ODlxs1xEY4b0DQuAooO2UdNKvDkNbV8ogLnxLbv02Ru1HXFcot0pVvDRBgptg==" }, "date-now": { "version": "0.1.4", @@ -5986,6 +6543,12 @@ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, + "ejs": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.7.4.tgz", + "integrity": "sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA==", + "dev": true + }, "electron-to-chromium": { "version": "1.3.154", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.154.tgz", @@ -7605,9 +8168,9 @@ "dev": true }, "handlebars": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.4.2.tgz", - "integrity": "sha512-cIv17+GhL8pHHnRJzGu2wwcthL5sb8uDKBHvZ2Dtu5s1YNt0ljbzKbamnc+gr69y7bzwQiBdr5+hOpRd5pnOdg==", + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.5.3.tgz", + "integrity": "sha512-3yPecJoJHK/4c6aZhSvxOyG4vJKDshV36VHp0iVCDVh7o9w2vwi3NSnL2MMPj3YdduqaBcu7cGbggJQM0br9xA==", "dev": true, "requires": { "neo-async": "^2.6.0", @@ -7817,13 +8380,19 @@ } }, "hoist-non-react-statics": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.0.tgz", - "integrity": "sha512-0XsbTXxgiaCDYDIWFcwkmerZPSwywfUqYmwT4jzewKTQSWoE6FCMoUVOeBJWK3E/CrWbxRG3m5GzY4lnIwGRBA==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", + "integrity": "sha512-wbg3bpgA/ZqWrZuMOeJi8+SKMhr7X9TesL/rXMjTzh0p0JUBo3II8DHboYbuIXWRlttrUFxwcu/5kygrCw8fJw==", "requires": { "react-is": "^16.7.0" } }, + "hoopy": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", + "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==", + "dev": true + }, "hosted-git-info": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", @@ -10765,6 +11334,12 @@ "supports-color": "^2.0.0" } }, + "date-fns": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz", + "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==", + "dev": true + }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", @@ -11782,6 +12357,12 @@ "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", "dev": true }, + "opener": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.1.tgz", + "integrity": "sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA==", + "dev": true + }, "opn": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/opn/-/opn-5.4.0.tgz", @@ -13515,14 +14096,13 @@ } }, "react": { - "version": "16.8.6", - "resolved": "https://registry.npmjs.org/react/-/react-16.8.6.tgz", - "integrity": "sha512-pC0uMkhLaHm11ZSJULfOBqV4tIZkx87ZLvbbQYunNixAAvjnC+snJCg0XQXn9VIsttVsbZP/H/ewzgsd5fxKXw==", + "version": "16.12.0", + "resolved": "https://registry.npmjs.org/react/-/react-16.12.0.tgz", + "integrity": "sha512-fglqy3k5E+81pA8s+7K0/T3DBCF0ZDOher1elBFzF7O6arXJgzyu/FW+COxFvAWXJoJN9KIZbT2LXlukwphYTA==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", - "prop-types": "^15.6.2", - "scheduler": "^0.13.6" + "prop-types": "^15.6.2" } }, "react-app-polyfill": { @@ -13717,14 +14297,14 @@ } }, "react-dom": { - "version": "16.8.6", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.8.6.tgz", - "integrity": "sha512-1nL7PIq9LTL3fthPqwkvr2zY7phIPjYrT0jp4HjyEQrEROnw4dG41VVwi/wfoCneoleqrNX7iAD+pXebJZwrwA==", + "version": "16.12.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.12.0.tgz", + "integrity": "sha512-LMxFfAGrcS3kETtQaCkTKjMiifahaMySFDn71fZUNpPHZQEzmk/GiAeIT8JSOrHB23fnuCOMruL2a8NYlw+8Gw==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", "prop-types": "^15.6.2", - "scheduler": "^0.13.6" + "scheduler": "^0.18.0" } }, "react-error-overlay": { @@ -13759,9 +14339,9 @@ } }, "react-is": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.7.0.tgz", - "integrity": "sha512-Z0VRQdF4NPDoI0tsXVMLkJLiwEBa+RP66g0xDHxgxysxSoCUccSten4RTF/UFvZF1dZvZ9Zu1sx+MDXwcOR34g==" + "version": "16.12.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz", + "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==" }, "react-lifecycles-compat": { "version": "3.0.4", @@ -13769,12 +14349,12 @@ "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" }, "react-redux": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-5.1.1.tgz", - "integrity": "sha512-LE7Ned+cv5qe7tMV5BPYkGQ5Lpg8gzgItK07c67yHvJ8t0iaD9kPFPAli/mYkiyJYrs2pJgExR2ZgsGqlrOApg==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-5.1.2.tgz", + "integrity": "sha512-Ns1G0XXc8hDyH/OcBHOxNgQx9ayH3SPxBnFCOidGKSle8pKihysQw2rG/PmciUQRoclhVBO8HMhiRmGXnDja9Q==", "requires": { "@babel/runtime": "^7.1.2", - "hoist-non-react-statics": "^3.1.0", + "hoist-non-react-statics": "^3.3.0", "invariant": "^2.2.4", "loose-envify": "^1.1.0", "prop-types": "^15.6.1", @@ -14625,9 +15205,9 @@ } }, "scheduler": { - "version": "0.13.6", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.13.6.tgz", - "integrity": "sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.18.0.tgz", + "integrity": "sha512-agTSHR1Nbfi6ulI0kYNK0203joW2Y5W4po4l+v03tOoiJKpTBbxpNhWDvqc/4IcOw+KLmSiQLTasZ4cab2/UWQ==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" @@ -14719,9 +15299,9 @@ } }, "serialize-javascript": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.9.1.tgz", - "integrity": "sha512-0Vb/54WJ6k5v8sSWN09S0ora+Hnr+cX40r9F170nT+mSkaxltoE/7R3OrIdBSUv1OoiobH1QoWQbCnAO+e8J1A==" + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.1.tgz", + "integrity": "sha512-MPLPRpD4FNqWq9tTIjYG5LesFouDhdyH0EPY3gVK4DRD5+g4aDqdNSzLIwceulo3Yj+PL1bPh6laE5+H6LTcrQ==" }, "serve-favicon": { "version": "2.5.0", @@ -15633,6 +16213,12 @@ "worker-farm": "^1.5.2" }, "dependencies": { + "serialize-javascript": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.9.1.tgz", + "integrity": "sha512-0Vb/54WJ6k5v8sSWN09S0ora+Hnr+cX40r9F170nT+mSkaxltoE/7R3OrIdBSUv1OoiobH1QoWQbCnAO+e8J1A==", + "dev": true + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -15786,7 +16372,8 @@ "trim-right": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=" + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", + "dev": true }, "trough": { "version": "1.0.4", @@ -15794,6 +16381,12 @@ "integrity": "sha512-tdzBRDGWcI1OpPVmChbdSKhvSVurznZ8X36AYURAcl+0o2ldlCY2XPzyXNNxwJwwyIU+rIglTCG4kxtNKBQH7Q==", "dev": true }, + "tryer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", + "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==", + "dev": true + }, "ts-pnp": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.1.2.tgz", @@ -16370,6 +16963,38 @@ "webpack-sources": "^1.3.0" } }, + "webpack-bundle-analyzer": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.6.0.tgz", + "integrity": "sha512-orUfvVYEfBMDXgEKAKVvab5iQ2wXneIEorGNsyuOyVYpjYrI7CUOhhXNDd3huMwQ3vNNWWlGP+hzflMFYNzi2g==", + "dev": true, + "requires": { + "acorn": "^6.0.7", + "acorn-walk": "^6.1.1", + "bfj": "^6.1.1", + "chalk": "^2.4.1", + "commander": "^2.18.0", + "ejs": "^2.6.1", + "express": "^4.16.3", + "filesize": "^3.6.1", + "gzip-size": "^5.0.0", + "lodash": "^4.17.15", + "mkdirp": "^0.5.1", + "opener": "^1.5.1", + "ws": "^6.0.0" + }, + "dependencies": { + "ws": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", + "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } + } + } + }, "webpack-dev-middleware": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.0.tgz", diff --git a/package.json b/package.json index 2991615..b9896f4 100644 --- a/package.json +++ b/package.json @@ -3,26 +3,28 @@ "version": "0.1.0", "private": true, "devDependencies": { - "@babel/core": "^7.6.2", - "@babel/register": "^7.6.2", + "@babel/core": "^7.7.5", + "@babel/register": "^7.7.4", "husky": "^0.14.3", "lint-staged": "^6.1.1", "prettier": "1.7.4", - "react-scripts": "3.0.1" + "react-scripts": "3.0.1", + "webpack-bundle-analyzer": "^3.6.0" }, "dependencies": { - "@babel/plugin-proposal-class-properties": "^7.5.5", - "@babel/plugin-syntax-dynamic-import": "^7.2.0", - "@babel/preset-env": "^7.6.2", + "@babel/plugin-proposal-class-properties": "^7.7.4", + "@babel/plugin-syntax-dynamic-import": "^7.7.4", + "@babel/preset-env": "^7.7.5", "aceonline-framebreak": "^1.1.0", "aceonline-stats": "^1.2.0", "body-parser": "^1.19.0", - "bulma": "0.6.0", - "chart.js": "^2.8.0", + "bulma": "^0.8.0", + "chart.js": "^2.9.3", "classnames": "^2.2.6", "compression": "^1.7.4", "cross-env": "^5.2.1", - "date-fns": "^1.30.1", + "date-fns": "^2.10.0", + "date-fns-tz": "^1.0.10", "es6-promise": "^4.2.8", "express": "^4.17.1", "fetch-everywhere": "^1.0.5", @@ -36,20 +38,20 @@ "marked": "^0.7.0", "morgan": "^1.9.1", "prop-types": "^15.7.2", - "react": "^16.8.6", + "react": "^16.12.0", "react-async-bootstrapper": "^2.1.1", "react-async-component": "^2.0.0", "react-chartjs-2": "^2.8.0", - "react-dom": "^16.8.6", + "react-dom": "^16.12.0", "react-flatpickr": "^3.9.1", "react-helmet": "^5.2.1", - "react-redux": "^5.1.1", + "react-redux": "^5.1.2", "react-router-config": "^1.0.0-beta.4", "react-router-dom": "^4.3.1", "redux": "^3.7.2", "redux-persist": "^4.10.2", "redux-thunk": "^2.3.0", - "serialize-javascript": "^1.9.1", + "serialize-javascript": "^2.1.1", "serve-favicon": "^2.5.0" }, "lint-staged": { diff --git a/public/favicon.ico b/public/favicon.ico deleted file mode 100644 index 301f521..0000000 Binary files a/public/favicon.ico and /dev/null differ diff --git a/public/humans.txt b/public/humans.txt deleted file mode 100644 index b36e54c..0000000 --- a/public/humans.txt +++ /dev/null @@ -1,17 +0,0 @@ -# humanstxt.org/ -# The humans responsible & technology colophon - -/* TEAM */ - Creator:Tobias Kronthaler - GitHub:@kronthto - From:Bavaria, Germany - -/* SITE */ - Last update:2018-04-09 - Language:English - Doctype:HTML5 - -/* TECHNOLOGY COLOPHON */ - React - https://github.com/kronthto/api.vi0lation.de - https://github.com/kronthto/vi0lation.de diff --git a/public/img/icon.png b/public/img/icon.png new file mode 100644 index 0000000..59c52ea Binary files /dev/null and b/public/img/icon.png differ diff --git a/public/img/logo.png b/public/img/logo.png new file mode 100644 index 0000000..751b032 Binary files /dev/null and b/public/img/logo.png differ diff --git a/public/index.html b/public/index.html index 631f651..f1acf7e 100644 --- a/public/index.html +++ b/public/index.html @@ -4,21 +4,22 @@ - + - + + + {{HELMET_HEAD}} -
{{SSR}}
diff --git a/public/manifest.json b/public/manifest.json index af7905a..7cf3164 100644 --- a/public/manifest.json +++ b/public/manifest.json @@ -1,24 +1,16 @@ { - "short_name": "Vi0", - "name": "Vi0lation", + "short_name": "CRT", + "name": "CR Tools", "icons": [ { - "src": "https://cdn.vi0lation.de/img/app_icon.png", - "sizes": "144x144", - "type": "image/png" - }, - { - "src": "favicon.ico" - }, - { - "src": "https://cdn.vi0lation.de/img/viologo.png", - "sizes": "72x36", + "src": "img/logo.png", + "sizes": "512x512", "type": "image/png" } ], "start_url": "./", "display": "standalone", - "theme_color": "#4a4cff", + "theme_color": "#006488", "background_color": "#ffffff", - "description": "Vi0lation brigade website and AirRivals ranking" + "description": "ChromeRivals tools, statistics, tracking" } diff --git a/public/pushSw.js b/public/pushSw.js new file mode 100644 index 0000000..33ab7f3 --- /dev/null +++ b/public/pushSw.js @@ -0,0 +1,47 @@ +var notificationPushAllowOverride = [ + 'badge', + 'body', + 'icon', + 'tag', + 'image', + 'lang' +]; + +self.addEventListener('push', function(event) { + if (!(self.Notification && self.Notification.permission === 'granted')) { + return; + } + + const sendNotification = data => { + let title = 'CR Event'; // TODO: Dynamic + + let pushoptions = { + body: data.text, + icon: 'img/logo.png', + badge: 'img/icon.png', + data + }; + notificationPushAllowOverride.forEach(function(prop) { + if (typeof data[prop] !== 'undefined') { + pushoptions[prop] = data[prop]; + } + }); + if (typeof data.title !== 'undefined') { + title = data.title; + } + + return self.registration.showNotification(title, pushoptions); + }; + + if (event.data) { + let data; + try { + data = event.data.json(); + } catch (e) { + data = { text: event.data.text() }; + } + event.waitUntil(sendNotification(data)); + } else { + event.waitUntil(sendNotification({ text: 'no details (weird error)' })); // We always need to show a notif on push, so display something to be safe + } +}); diff --git a/public/robots.txt b/public/robots.txt index e94ab33..9e60f97 100644 --- a/public/robots.txt +++ b/public/robots.txt @@ -1,5 +1,2 @@ User-agent: * Disallow: - -# TODO -# SITEMAP: https://www.vi0lation.de/sitemap.xml diff --git a/public/sitemap.xml b/public/sitemap.xml deleted file mode 100644 index 1333ed7..0000000 --- a/public/sitemap.xml +++ /dev/null @@ -1 +0,0 @@ -TODO diff --git a/server/app.js b/server/app.js index 2d71c46..42ec67a 100644 --- a/server/app.js +++ b/server/app.js @@ -20,7 +20,7 @@ const { indexhtmlDirect } = require('./indexhtml') const app = express() // Server favicon before to not show up in logs -app.use(favicon(path.join(__dirname, '../build', 'favicon.ico'))) +//app.use(favicon(path.join(__dirname, '../build', 'icon.png'))) // Setup logger app.use(morgan('combined')) diff --git a/src/actions/cms.js b/src/actions/cms.js deleted file mode 100644 index 3c74647..0000000 --- a/src/actions/cms.js +++ /dev/null @@ -1,38 +0,0 @@ -import { REQUEST, RECEIVE } from '../types/cms' -import { CALL_API } from '../middleware/api' -import { isCurrentlyFetching, getCurrentTS } from '../utils/api' - -const cmsTtl = 21600000 // 6h - -function fetchCms(page) { - return { - [CALL_API]: { - endpoint: 'cms/' + page, - types: [REQUEST, RECEIVE] - }, - page - } -} - -function shouldFetchCms(page, state) { - const cmsState = state.cms - - const pageRequest = cmsState.requests[page] - - if (!pageRequest) return true - - if (isCurrentlyFetching(pageRequest)) return false - - // Should we check the actual data field? - - const { receivedAt } = pageRequest - return receivedAt && receivedAt + cmsTtl <= getCurrentTS() -} - -export function fetchCmsIfNeeded(page) { - return (dispatch, getState) => { - if (shouldFetchCms(page, getState())) { - return dispatch(fetchCms(page)) - } - } -} diff --git a/src/actions/highscores.js b/src/actions/highscores.js deleted file mode 100644 index 95d2cb0..0000000 --- a/src/actions/highscores.js +++ /dev/null @@ -1,48 +0,0 @@ -import { REQUEST, RECEIVE, REQFAIL } from '../types/highscores' -import { CALL_API } from '../middleware/api' -import { isCurrentlyFetching } from '../utils/api' - -function fetchHighscore(region, date) { - return { - [CALL_API]: { - endpoint: 'ranking/highscore?date=' + date, - types: [REQUEST, RECEIVE, REQFAIL], - acceptableErrorCodes: [404] - }, - date, - region - } -} - -function shouldFetchHighscore(region, date, state) { - const regionData = state.highscores[region] - - if (!regionData) { - return true - } - - const highscore = regionData[date] - - if (!highscore) { - return true - } - - const highscoreData = highscore.data - if ( - highscoreData || - highscoreData === false || - isCurrentlyFetching(highscore) - ) { - return false - } - - return true -} - -export function fetchHighscoreIfNeeded(region, date) { - return (dispatch, getState) => { - if (shouldFetchHighscore(region, date, getState())) { - return dispatch(fetchHighscore(region, date)) - } - } -} diff --git a/src/components/AR/EPList.js b/src/components/AR/EPList.js deleted file mode 100644 index f6f2f00..0000000 --- a/src/components/AR/EPList.js +++ /dev/null @@ -1,38 +0,0 @@ -import React, { Component } from 'react' -import { Helmet } from 'react-helmet' - -import EPListTable from './EPListTable' -import EPListCalculator from './EPListCalculator' - -class EPList extends Component { - shouldComponentUpdate() { - return false - } - - render() { - return ( -
- - - AirRivals/AceOnline EP List - - -

EP List

- -
-

EP to Level Calculator

- -
- -
- -
-
- ) - } -} - -export default EPList diff --git a/src/components/AR/EPListCalculator.js b/src/components/AR/EPListCalculator.js deleted file mode 100644 index 939ea87..0000000 --- a/src/components/AR/EPListCalculator.js +++ /dev/null @@ -1,62 +0,0 @@ -import React, { Component } from 'react' -import { calcProgessBarByEp } from '../../utils/AR/ep' - -class EPListCalculator extends Component { - constructor(props) { - super(props) - this.state = { ep: null } - } - - shouldComponentUpdate(prevProps, prevState) { - if (this.state.ep !== prevState.ep) { - return true - } - - return false - } - - calculate(e) { - e.preventDefault() - this.setState({ ep: Number(this.refs.ep.value) }) - } - - ep2LevelResult() { - let { ep } = this.state - - if (!ep) { - return null - } - - return {calcProgessBarByEp(ep)} - } - - render() { - return ( -
-
- -
-
- - {this.ep2LevelResult()} - -
-
- ) - } -} - -export default EPListCalculator diff --git a/src/components/AR/EPListTable.js b/src/components/AR/EPListTable.js deleted file mode 100644 index 253696a..0000000 --- a/src/components/AR/EPListTable.js +++ /dev/null @@ -1,55 +0,0 @@ -import React, { Component } from 'react' -import NumTD from './NumTD' - -import level2ep from '../../data/level2ep' - -const TableLegend = () => ( - - Level - - Needed EP - - - From previous - - -) - -class EPListTable extends Component { - shouldComponentUpdate() { - return false - } - - render() { - return ( - - - - - - {Object.keys(level2ep).map(level => { - let levelEp = level2ep[level] - let previousEp = level2ep[level - 1] - - return ( - - - - - - ) - })} - - - - -
{level}
- ) - } -} - -export default EPListTable diff --git a/src/components/AR/FBTool.js b/src/components/AR/FBTool.js deleted file mode 100644 index 43bc3c0..0000000 --- a/src/components/AR/FBTool.js +++ /dev/null @@ -1,49 +0,0 @@ -import React, { Component } from 'react' -import { Helmet } from 'react-helmet' - -import FrameBreakCalculator from './FrameBreakCalculator' - -class FBTool extends Component { - shouldComponentUpdate() { - return false - } - - render() { - return ( -
- - - AirRivals/AceOnline FrameBreak Tool - - -

FrameBreak Tool

- -
- Standard weapons in AceOnline / AirRivals / SCO (Space Cowboy Online) - only profit from very specific values of enchanted reattack (so called - "breakpoints") due to time quantization.
- The following tool can be used to calculate the optimal re-attack - enchants to use those breakpoints: -
- - - -

- - source on GitHub - -

-
- ) - } -} - -export default FBTool diff --git a/src/components/AR/FrameBreakCalculator.js b/src/components/AR/FrameBreakCalculator.js deleted file mode 100644 index f2c3a3a..0000000 --- a/src/components/AR/FrameBreakCalculator.js +++ /dev/null @@ -1,153 +0,0 @@ -import React, { Component } from 'react' -import NumTD from './NumTD' -import calcFbs from 'aceonline-framebreak' - -const TableLegend = () => ( - - - Rea Enchant - - - Bullets per second - - -) - -class FrameBreakCalculator extends Component { - constructor(props) { - super(props) - this.state = { baseRea: null, firingMode: null } - } - - shouldComponentUpdate(prevProps, prevState) { - if (this.state.baseRea !== prevState.baseRea) { - return true - } - if (this.state.firingMode !== prevState.firingMode) { - return true - } - if (this.state.fps !== prevState.fps) { - return true - } - - return false - } - - calculate(e) { - e.preventDefault() - this.setState({ - baseRea: Number(this.refs.rea.value), - firingMode: Number(this.refs.mode.value), - fps: Number(this.refs.fps.value) - }) - } - - render() { - const { baseRea, firingMode, fps } = this.state - const legend = - let data - if (baseRea && firingMode) { - data = calcFbs(baseRea, firingMode, fps || undefined) - } - - // TODO: Auslagern von generischen Form Stuff - return ( -
-
e.preventDefault()} className="margin-bot"> -
-
- -
-
-
-

- -

-
-
-
-
-
- -
-
-
-

- -

-
-
-
-
-
- -
-
-
-

- -

-
-
-
-
- - {legend} - - {data && - data.map(function(row) { - return ( - - - - - ) - })} - -
-
- ) - } -} - -export default FrameBreakCalculator diff --git a/src/components/AR/RankingInfo.js b/src/components/AR/RankingInfo.js deleted file mode 100644 index 125f1ca..0000000 --- a/src/components/AR/RankingInfo.js +++ /dev/null @@ -1,104 +0,0 @@ -import React, { Component } from 'react' -import { Helmet } from 'react-helmet' -import Link from 'react-router-dom/Link' -import { highscoresUrl } from '../../routes' - -class RankingInfo extends Component { - shouldComponentUpdate() { - return false - } - - render() { - return ( - // TODO: Hero Teaser zu den eigentlichen Seiten -
- - - AR Ranking - - -

AR Ranking

- -
-
- -
-
-

Highscores

-

The ladder for any given day

-
-
- -
-
- -
-

Motivation

-

- AirRivals, the EU Version of Masangsofts Aceonline (former{' '} - SCO), published the - highscores once a day and only of the current day. It was not - possible to view previous days. -

-

- Therefore, in 2012 I wrote a program that saves the data once a day, - and this website to make it publicly accessible, aswell as - performing deeper analysis on the data (progress/day, - Nation-balance). -

-
- -
-

Dataset

-

- The first day data was recorded is the 2012-07-27, since then up to - the 2016-08-24 - the day AR.de closed its gates - 1163 days are - recorded. Unfortunately, mostly in the beginning, some days are - missing, because the import wasn't stable. Since the 2014-01-05 - every day is on record. -

-
- -
-

Methodology

-

- AR.de published 5 tables every day: level, fame, brigade_total, - brigade_monthly, pvp (duels). These were copied without - modification/normalization into the same schema. All processing for - views is done using complex joins on these tables. -

-
- -
-

Data

-

- If you want to dig into the records yourself you are encouraged to! - All historical data is directly available: -

-

- - Download the MySQL Dump - -

-

- Use the API as this website does (CORS is enabled):{' '} - - api.vi0lation.de - -

-
-
- ) - } -} - -export default RankingInfo diff --git a/src/components/AR/WeaponCalc.js b/src/components/AR/WeaponCalc.js index 15a7b3c..9e5963b 100644 --- a/src/components/AR/WeaponCalc.js +++ b/src/components/AR/WeaponCalc.js @@ -14,12 +14,12 @@ class WeaponCalc extends Component { - AirRivals/AceOnline WeaponCalc + ChromeRivals: WeaponCalc -

Ace WeaponCalc

+

CR WeaponCalc

diff --git a/src/components/AR/WeaponCalc/TotalResult.js b/src/components/AR/WeaponCalc/TotalResult.js new file mode 100644 index 0000000..9a773af --- /dev/null +++ b/src/components/AR/WeaponCalc/TotalResult.js @@ -0,0 +1,325 @@ +import React, { Component } from 'react' +import aostats from 'aceonline-stats' +import aofb from 'aceonline-framebreak' +import { ITEMKIND_DEFENSE } from '../../../data/ao' +import { + determinePrefix, + getMergedDesBoni, + isAttrAdditiv, + PlusMinusNumber +} from './WeaponPreview' +import { colorName } from '../../../utils/AR/names' + +// oneshot potential / % (oof, kits..) + +const WEAPON_ATTRS = ['_MIN', '_MAX', '_PROB', '_PIERCE', '_SHOTS', '_MULTI'] + +const ARMOR_ATTRS = ['HP', 'DP', 'STD_DEF', 'ADV_DEF', 'STD_EVA', 'ADV_EVA'] + +const dmgPerSecond = (min, max, weaponStats, totalValues) => { + const fbRes = aofb( + weaponStats.STD_RA.base, + totalValues.STD_SHOTS.total, + 60, + weaponStats.STD_RA.bonuses * -100 + 1 + ) + const bps = fbRes[fbRes.length - 1].bps * totalValues.STD_MULTI.total + return { + min: bps * min, + max: bps * max, + bp: fbRes[fbRes.length - 1].rea + } +} +const dmgPerVolley = (min, max, totalValues) => { + let missilesPerVolley = + totalValues['ADV_SHOTS'].total * totalValues['ADV_MULTI'].total + return { + min: min * missilesPerVolley, + max: max * missilesPerVolley + } +} + +class TotalResult extends Component { + constructor(props) { + super(props) + this.state = {} + } + render() { + const { + item, + weaponStats, + gearStatPoints, + skills, + charm, + armorBonus + } = this.props + + const weaponElseArmor = item.kind !== ITEMKIND_DEFENSE + const attrPrefix = determinePrefix(item) + + let gearStatBonus = {} + if (weaponElseArmor && gearStatPoints.Atk) { + gearStatBonus[attrPrefix + '_PROB'] = aostats.prob(gearStatPoints.Atk) + gearStatBonus[attrPrefix + '_PIERCE'] = Math.floor( + aostats.pierce(gearStatPoints.Atk) + ) + let mm = aostats.dmgInc(gearStatPoints.Atk) + gearStatBonus[attrPrefix + '_MIN'] = mm + gearStatBonus[attrPrefix + '_MAX'] = mm + } else { + if (gearStatPoints.Eva) { + let eva = aostats.evasion(gearStatPoints.Eva) + gearStatBonus['STD_EVA'] = eva + gearStatBonus['ADV_EVA'] = eva + } + if (gearStatPoints.Def) { + let def = aostats.defense(gearStatPoints.Def) + gearStatBonus['STD_DEF'] = def + gearStatBonus['ADV_DEF'] = def + } + } + + let greenAdditives = [].concat(skills) + if (charm) { + greenAdditives.push(charm) + } + armorBonus.forEach(armorFix => { + if (armorFix) { + greenAdditives.push(armorFix) + } + }) + let skillsBonus = getMergedDesBoni(greenAdditives) + + const totalValues = calcTotalValues( + weaponElseArmor, + attrPrefix, + weaponStats, + gearStatBonus, + skillsBonus + ) + + let stdDps = null + if (attrPrefix === 'STD') { + const stdDpsData = dmgPerSecond( + totalValues['STD_MIN'].total, + totalValues['STD_MAX'].total, + weaponStats, + totalValues + ) + stdDps = ( +
  • + DPS @60fps:{' '} + {stdDpsData.min.toFixed(3)} ~ {stdDpsData.max.toFixed(3)} +
  • + ) + } + let advDps = null + if (attrPrefix === 'ADV') { + const advDpsData = dmgPerVolley( + totalValues['ADV_MIN'].total, + totalValues['ADV_MAX'].total, + totalValues + ) + advDps = ( +
  • + DMG/Volley: {advDpsData.min.toFixed(3)} ~ {advDpsData.max.toFixed(3)} +
  • + ) + } + + return ( +
    +
      + {Object.keys(totalValues).map(attr => ( + + ))} + {stdDps} + {advDps} +
    + {weaponElseArmor ? ( + + +
    + {['Def', 'Eva', 'HP', 'DP'].map(enemyStat => { + const id = 'Enm_' + enemyStat + return ( +
    + + + this.setState({ + [id]: e.target.value.length + ? Number(e.target.value) + : null + })} + /> +
    + ) + })} +
    + {this.valuesVs(totalValues, attrPrefix, weaponStats)} +
    + ) : null} +
    + ) + } + + valuesVs(totalValues, attrPrefix, weaponStats) { + if (!Object.values(this.state).some(Boolean)) { + return null + } + + let hitRate, hitApplyDamage + + if (this.state.Enm_Eva) { + hitRate = Math.max( + 0, + Math.min( + totalValues[attrPrefix + '_PROB'].total - this.state.Enm_Eva, + 100 + ) + ) + } + + if (this.state.Enm_Def) { + hitApplyDamage = + 100 - + Math.max( + 0, + Math.min( + this.state.Enm_Def - totalValues[attrPrefix + '_PIERCE'].total, + 100 + ) + ) + } + + let trueMin = totalValues[attrPrefix + '_MIN'].total + let trueMax = totalValues[attrPrefix + '_MAX'].total + if (typeof hitApplyDamage !== 'undefined') { + let trueFraction = hitApplyDamage / 100 + trueMin = Math.max(1, trueMin * trueFraction) + trueMax = Math.max(1, trueMax * trueFraction) + } + + let defEvaReducedMin = trueMin + let defEvaReducedMax = trueMax + if (typeof hitRate !== 'undefined') { + let evaTrueFraction = hitRate / 100 + defEvaReducedMin *= evaTrueFraction + defEvaReducedMax *= evaTrueFraction + } + let stdDpsTrue = null + let advDpsTrue = null + if (attrPrefix === 'STD') { + const stdDpsData = dmgPerSecond( + defEvaReducedMin, + defEvaReducedMax, + weaponStats, + totalValues + ) + stdDpsTrue = ( +
  • + Expected Avg. True DPS: {stdDpsData.min.toFixed(3)} ~{' '} + {stdDpsData.max.toFixed(3)} +
  • + ) + } + if (attrPrefix === 'ADV') { + const advDpsData = dmgPerVolley( + defEvaReducedMin, + defEvaReducedMax, + totalValues + ) + advDpsTrue = ( +
  • + Expected Avg. True DMG/Volley: {advDpsData.min.toFixed(3)} ~{' '} + {advDpsData.max.toFixed(3)} +
  • + ) + } + + return ( + + ) + } // refactor to class vars +} + +const calcTotalValues = ( + weaponElseArmor, + attrPrefix, + weaponStats, + gearStatBonus, + skillsBonus +) => { + let res = {} + ;(weaponElseArmor ? WEAPON_ATTRS : ARMOR_ATTRS).forEach(attr => { + if (attr.charAt(0) === '_') { + if (!attrPrefix) { + throw Error('Not a weapon item') + } + attr = attrPrefix + attr + } + + const statBonus = gearStatBonus[attr] + const skillBonus = skillsBonus[attr] + let value = weaponStats[attr] + + if (typeof value === 'undefined') { + value = { + additiv: isAttrAdditiv(attr), + base: 0 + } + } + + let totalBonuses = + (value.bonuses || 0) + (statBonus || 0) + (skillBonus || 0) + let total + + if (value.additiv) { + total = value.base + totalBonuses + } else { + total = value.base * (1 + totalBonuses) + } + + res[attr] = { + statBonus, + skillBonus, + total + } + }) + return res +} + +const DisplayStat = props => ( +
  • + {props.attr}:{' '} + {props.statBonus + ? colorName(`\\d[${PlusMinusNumber(props.statBonus)}]\\d`) + : null}{' '} + {typeof props.skillBonus !== 'undefined' + ? colorName(`\\g[${PlusMinusNumber(props.skillBonus)}]\\g`) + : null}{' '} + = {Number(props.total.toFixed(6))} +
  • +) + +export default TotalResult diff --git a/src/components/AR/WeaponCalc/WeaponPreview.js b/src/components/AR/WeaponCalc/WeaponPreview.js index 0f3c3f3..ee6d86d 100644 --- a/src/components/AR/WeaponCalc/WeaponPreview.js +++ b/src/components/AR/WeaponCalc/WeaponPreview.js @@ -1,15 +1,87 @@ import React from 'react' import { colorName } from '../../../utils/AR/names' +import { + baseValuesToDesKeyMap, + desKeyByDesNum, + IS_PRIMARY_WEAPON, + IS_SECONDARY_WEAPON, + ITEMKIND_DEFENSE +} from '../../../data/ao' + +export const prepareStats = (item, prefix, suffix, enchants) => { + let stats = mergeStats(collectStats(item, prefix, suffix, enchants)) + let displayStats = {} + + Object.keys(stats).forEach(attr => { + let value = Object.assign({}, stats[attr]) + + if (!(value.base || value.enchants || value.fixes)) { + return + } + + let factorBaseBy = 1 + let calcTotal = true + + if (attr.includes('_RA')) { + factorBaseBy = 1000 + } + if (attr.includes('_MIN') || attr.includes('_MAX')) { + calcTotal = false + } + + let base = (Number(value.base) || 0) / factorBaseBy + + let bonuses = (value.enchants || 0) + (value.fixes || null) + value.additiv = isAttrAdditiv(attr) + if (calcTotal) { + if (value.additiv) { + value.total = base + bonuses + } else { + // Weight/MM/RA + value.total = base * (1 + bonuses) + } + } + + value.base = base + value.bonuses = bonuses + + displayStats[attr] = value + }) + + return displayStats +} +export const isAttrAdditiv = attr => { + let baseIsPercentPoints = true + let upgradesArePercentPoints = true + + if (attr.includes('_RA')) { + baseIsPercentPoints = false + } + if (attr.includes('_MIN') || attr.includes('_MAX')) { + baseIsPercentPoints = false + } + if (attr === 'HP' || attr === 'DP') { + baseIsPercentPoints = false + upgradesArePercentPoints = false + } + if (attr.includes('WEIGHT')) { + baseIsPercentPoints = false + } + + return !upgradesArePercentPoints || baseIsPercentPoints +} const WeaponPreview = props => { - const { item, prefix, suffix } = props - let stats = visualizeStats(item) + const { item, prefix, suffix, enchants, stats } = props + return (

    {prefix && colorName(prefix.name)} -  {colorName(item.name)}  +  {colorName(item.name)} {colorName( + `\\e[E${enchants.reduce((acc, card) => acc + card.count, 0)}]\\e` + )}  {suffix && colorName(suffix.name)}

    @@ -17,7 +89,7 @@ const WeaponPreview = props => {
      {Object.keys(stats).map(attr => ( -
    • {`${attr}: ${stats[attr]}`}
    • + ))}
    @@ -26,17 +98,160 @@ const WeaponPreview = props => { ) } -const visualizeStats = item => { - let stats = { - 'Attack Power': item.AbilityMin + ' ~ ' + item.AbilityMax, - Accuracy: item.HitRate, - Pierce: item.FractionResistance, - Range: item.Range, - 'Reattack Time': item.ReAttacktime / 1000, - // TODO: Speed - Weight: item.Weight +const DisplayStat = props => { + const { attr, value } = props + + return ( +
  • + {attr}: {value.base || null}{' '} + {value.fixes + ? colorName(`\\g[${PlusMinusNumber(value.fixes)}]\\g`) + : null}{' '} + {value.enchants + ? colorName(`\\e[${PlusMinusNumber(value.enchants)}]\\e`) + : null}{' '} + {'total' in value && (value.fixes || value.enchants) + ? ` = ${Number(value.total.toFixed(6))}` + : null} +
  • + ) +} + +export const PlusMinusNumber = num => { + num = Number(num) + if (num < 0) { + return num.toFixed(2) + } + return '+' + num.toFixed(2) +} + +export const determinePrefix = item => { + if (IS_PRIMARY_WEAPON(item.kind)) { + return 'STD' + } + if (IS_SECONDARY_WEAPON(item.kind)) { + return 'ADV' + } + if (item.kind === ITEMKIND_DEFENSE) { + return null } - return stats + throw Error('Unexpected itemkind') +} + +const collectStats = (item, prefix, suffix, enchants) => { + let values = {} + + let desKeyPrefix = determinePrefix(item) + + Object.keys(baseValuesToDesKeyMap).forEach(prop => { + if (item[prop]) { + let desKey = baseValuesToDesKeyMap[prop] + if ( + !desKeyPrefix && + desKey === '_WEIGHT' && + item.kind === ITEMKIND_DEFENSE + ) { + desKey = 'WEIGHT' + } + if (desKey.charAt(0) === '_') { + if (!desKeyPrefix) { + throw Error('Not a weapon item') + } + desKey = desKeyPrefix + desKey + } + values[desKey] = item[prop] + } + }) + values = mergeAndSum(values, getBonusValuesFromDesParams(item.DesParameters)) + + // TODO: Speed + + return { + base: values, + fixes: getFixesStats([prefix, suffix].filter(Boolean)), + enchants: getEnchantsStats(enchants) + } +} + +const transformDesAttrsToArray = item => { + let desResult = {} + for (let i = 1; i <= 9; i++) { + let desNum = item[`DesParameter${i}`] + if (!desNum) { + continue + } + desResult[desNum] = item[`ParameterValue${i}`] + } + return desResult +} + +export const addDesParamsArrayToFixes = fixes => + fixes.map(fix => { + fix.DesParameters = transformDesAttrsToArray(fix) + return fix + }) + +const getFixesStats = fixes => getMergedDesBoni(addDesParamsArrayToFixes(fixes)) + +export const mergeAndSum = (o1, o2) => { + // is there a core-func for this? + Object.keys(o2).forEach(key => { + if (key in o1) { + o1[key] += o2[key] + } else { + o1[key] = o2[key] + } + }) + return o1 +} +export const getBonusValuesFromDesParams = desParameters => { + let values = {} + Object.keys(desParameters).forEach(desNum => { + desNum = Number(desNum) + let desKey = desKeyByDesNum(desNum) + if (!desKey) { + console.warn(`DesNum ${desNum} not mapped`) + return + } + + if (!(desKey in values)) { + values[desKey] = 0 + } + + values[desKey] += desParameters[desNum] + }) + return values +} +export const getMergedDesBoni = thingsWithDesParams => + thingsWithDesParams.reduce( + (acc, cur) => + mergeAndSum(acc, getBonusValuesFromDesParams(cur.DesParameters)), + {} + ) + +const getEnchantsStats = enchants => + enchants.reduce((acc, currentEnchantInfo) => { + let enchantBonusValues = getBonusValuesFromDesParams( + currentEnchantInfo.card.DesParameters + ) + Object.keys(enchantBonusValues).forEach(key => { + enchantBonusValues[key] = + enchantBonusValues[key] * currentEnchantInfo.count + }) + return mergeAndSum(acc, enchantBonusValues) + }, {}) + +const mergeStats = stats => { + let res = {} + Object.keys(stats).forEach(key => { + Object.keys(stats[key]).forEach(desKey => { + if (!(desKey in res)) { + res[desKey] = {} + } + res[desKey][key] = stats[key][desKey] + }) + }) + return res } export default WeaponPreview diff --git a/src/components/AR/WeaponCalc/index.js b/src/components/AR/WeaponCalc/index.js index a020610..55c35cf 100644 --- a/src/components/AR/WeaponCalc/index.js +++ b/src/components/AR/WeaponCalc/index.js @@ -1,85 +1,227 @@ import React, { Component } from 'react' import withRouter from 'react-router/withRouter' -import { callApi } from '../../../middleware/api' +import { callApiChecked } from '../../../middleware/api' import config from '../../../config' import { unitKinds, standardWeapons, advWeapons, - ITEMKIND_SKILL_ATTACK + ITEMKIND_SKILL_ATTACK, + ITEMKIND_DEFENSE, + COMPARE_ITEMKIND, + ITEMKIND_SKILL_DEFENSE, + ITEMKIND_ENCHANT, + DES_ENCHANT_INITIALIZE, + ITEMKIND_ACCESSORY_TIMELIMIT, + ITEMKIND_CARD } from '../../../data/ao' import LoadBlock from '../../LoadBlock' -import WeaponPreview from './WeaponPreview' +import WeaponPreview, { + addDesParamsArrayToFixes, + prepareStats +} from './WeaponPreview' +import TotalResult from './TotalResult' +import { colorName } from '../../../utils/AR/names' + +const eqKinds = [ITEMKIND_DEFENSE].concat(standardWeapons, advWeapons) +const isEquip = item => eqKinds.indexOf(item.kind) !== -1 + +const bannedEnchantNames = ['Swift ', '%]', 'E10', 'FFA', 'Platinum Guard'] +const isBannedEnchant = item => + bannedEnchantNames.some( + bannedName => + item.name.includes(bannedName) || + DES_ENCHANT_INITIALIZE in item.DesParameters + ) + +const bannedCharmDes = [162, 159, 160, 129, 130, 158, 157] // 161 (Blue Saph) would also remove Hax-Charm +const isBannedCharm = item => + bannedCharmDes.some(bannedDesNum => bannedDesNum in item.DesParameters) + +const BUFF_CARD_ITEMS = [7026601, 7026571, 7020641, 7020651, 7001100] + +const hasNonArmorDesParams = item => { + let desParams = Object.assign({}, item.DesParameters) + + delete desParams[13] + delete desParams[89] + delete desParams[22] + delete desParams[23] + delete desParams[24] + delete desParams[25] + + return Object.keys(desParams).length > 0 +} + +const stats = [ + { id: 'Atk', label: 'Attack' }, + { id: 'Def', label: 'Defense' }, + { id: 'Eva', label: 'Evasion' } +] + +// noinspection JSBitwiseOperatorUsage +const enchantCardMatches = (card, item, gear) => + COMPARE_ITEMKIND(card.ReqItemKind, item.kind) && + card.ReqUnitKind & unitKinds[gear] + +let instance + +export const resetCurrentInstance = () => { + if (instance) { + instance.reset() + } +} class WeaponCalcTool extends Component { + initState + gearItemDb = [] + gearArmorsWithBonus = [] gearSkillDb = [] + itemFixDb = [] + armorFixDb = [] + enchantItemDb = [] + buffItemDb = [] + charmDb = [] selectedItem prefix suffix + enchants + + reset() { + this.setState( + Object.assign( + { + arm: undefined, + ch: undefined, + sWp: undefined, + iPrf: undefined, + iSuf: undefined, + aPrf: undefined, + aSuf: undefined + }, + this.initState, + { gear: this.state.gear, sk: [], bc: [] } + ) + ) + } constructor(props) { super(props) - let initState = { - gear: 'B' + let defaultStat = {} + stats.forEach(stat => (defaultStat[stat.id] = 0)) + + this.initState = { + gear: 'B', + ench: {}, + stat: defaultStat, + sk: [], + bc: [] } + let initStateWithFrag = Object.assign({}, this.initState) let hash = this.props.location.hash.substr(1) if (hash) { - Object.assign(initState, JSON.parse(atob(hash))) + Object.assign(initStateWithFrag, JSON.parse(atob(hash))) } - this.state = initState + this.state = initStateWithFrag + + instance = this + } + + componentWillUnmount() { + instance = null } filterItemDbs(itemdb, gear) { - let itemDbGear = itemdb.filter(item => item.ReqUnitKind & unitKinds[gear]) - this.gearItemDb = itemDbGear.filter( - item => [].concat(standardWeapons, advWeapons).indexOf(item.kind) !== -1 + // noinspection JSBitwiseOperatorUsage + let itemDbGear = itemdb.filter( + item => + item.ReqUnitKind & unitKinds[gear] || + (item.kind >= 50 && item.SkillTargetType === 2 && item.Range) + ) // Matches Gear or is a skill that applies to form (Type&Range) (Ragings) + this.gearItemDb = itemDbGear.filter(isEquip) + this.gearArmorsWithBonus = this.gearItemDb.filter( + item => item.kind === ITEMKIND_DEFENSE && hasNonArmorDesParams(item) ) this.gearSkillDb = itemDbGear.filter( - item => item.kind === ITEMKIND_SKILL_ATTACK + item => + (item.kind === ITEMKIND_SKILL_ATTACK || + item.kind === ITEMKIND_SKILL_DEFENSE) && + item.name.indexOf('\\c') === 0 ) } componentDidMount() { - callApi( + callApiChecked( config.apibase + 'chromerivals/omi?category=item' ).then(allItems => { let reducedItemDb = Object.values(allItems) .filter(item => { - const { kind, ReqMinLevel } = item - if (kind === ITEMKIND_SKILL_ATTACK) { - return true - } + const { kind, ReqMinLevel, name } = item if ( - ReqMinLevel > 103 && - ReqMinLevel < 109 && - (advWeapons.indexOf(kind) !== -1 || - standardWeapons.indexOf(kind) !== -1) + kind === ITEMKIND_SKILL_ATTACK || + kind === ITEMKIND_SKILL_DEFENSE || + kind === ITEMKIND_ENCHANT || + kind === ITEMKIND_ACCESSORY_TIMELIMIT || + kind === ITEMKIND_CARD ) { return true } + if (name.charAt(0) !== '\\') { + return false + } + // noinspection RedundantIfStatementJS + if (ReqMinLevel > 103 && ReqMinLevel <= 115 && isEquip(item)) { + return true + } return false }) .sort((a, b) => b.ReqMinLevel - a.ReqMinLevel) this.filterItemDbs(reducedItemDb, this.state.gear) + this.enchantItemDb = reducedItemDb.filter( + item => item.kind === ITEMKIND_ENCHANT && !isBannedEnchant(item) + ) + this.buffItemDb = reducedItemDb.filter( + item => BUFF_CARD_ITEMS.indexOf(item.id) !== -1 + ) + this.charmDb = reducedItemDb.filter( + item => + item.kind === ITEMKIND_ACCESSORY_TIMELIMIT && + item.Time === 18000000 && + item.name.indexOf('(5H)') !== -1 && + !isBannedCharm(item) && + item.name.indexOf('Holy') === -1 + ) this.setState({ itemdb: reducedItemDb }) }) - callApi( + callApiChecked( config.apibase + 'chromerivals/omi?category=rareitems' ).then(allFixes => { let fixDb = Object.values(allFixes) - .filter(fix => fix.probability !== 0) + .filter( + fix => + fix.probability !== 0 && + ['m', 'c', 'r', 'l', 'y'].indexOf(fix.name.charAt(1)) !== -1 + ) .sort((a, b) => a.probability - b.probability) + this.armorFixDb = addDesParamsArrayToFixes( + fixDb.filter(fix => { + return COMPARE_ITEMKIND(fix.ReqItemKind, ITEMKIND_DEFENSE) + }) + ) this.setState({ fixDb }) }) } componentDidUpdate(prevProps, prevState) { + const serializedState = this.serializeState() this.props.history.replace({ - hash: btoa(JSON.stringify(this.serializeState())) + hash: Object.keys(serializedState).length + ? btoa(JSON.stringify(this.serializeState())) + : null }) } @@ -87,10 +229,26 @@ class WeaponCalcTool extends Component { let obj = Object.assign({}, this.state) delete obj.itemdb delete obj.fixDb + + Object.keys(obj).forEach(stateKey => { + const stateKeyVal = obj[stateKey] + if ( + !stateKeyVal || + (Array.isArray(stateKeyVal) && stateKeyVal.length === 0) || + (typeof stateKeyVal === 'object' && + Object.values(stateKeyVal).filter(Boolean).length === 0) + ) { + delete obj[stateKey] + } + }) + if (Object.keys(obj).length === 1 && 'gear' in obj) { + delete obj.gear + } + return obj } - renderFixSelect(saveAs, prefix) { + renderFixSelect(saveAs, prefix, fixDb) { const def = this.state[saveAs] return ( - this.setState({ selWeap: this.refs.weapsel.value })} - value={selWeap || ''} + onChange={() => { + let newItem = this.gearItemDb.find( + item => item.id === Number(this.refs.weapsel.value) + ) + let stateUpdate = { + sWp: this.refs.weapsel.value, + ench: this.cleanseEnchants(newItem, gear) + } + if (stateUpdate.sWp && !isNaN(stateUpdate.sWp)) { + stateUpdate.sWp = Number(stateUpdate.sWp) + } + + if (newItem && this.selectedItem) { + // oof + if (COMPARE_ITEMKIND(ITEMKIND_DEFENSE, newItem.kind)) { + // Switched to armor + //console.log(this.state, "toArmor"); + if (this.state.aPrf) { + stateUpdate['iPrf'] = this.state.aPrf + } + if (this.state.aSuf) { + stateUpdate['iSuf'] = this.state.aSuf + } + stateUpdate['aPrf'] = null + stateUpdate['aSuf'] = null + } else { + if ( + COMPARE_ITEMKIND( + ITEMKIND_DEFENSE, + this.selectedItem.kind + ) + ) { + // switched from armor to weapon + // console.log(this.state, "toWeap"); + if (this.state.iPrf) { + stateUpdate['aPrf'] = this.state.iPrf + } + if (this.state.iSuf) { + stateUpdate['aSuf'] = this.state.iSuf + } + stateUpdate['iPrf'] = null + stateUpdate['iSuf'] = null + } + } + } + + this.setState(stateUpdate) + }} + value={sWp || ''} > {this.gearItemDb.map(item => { return ( ) })} @@ -183,37 +466,298 @@ class WeaponCalcTool extends Component {
    -
    -
    -
    +
    + {!isArmor && ( +
    +
    + +
    + {this.renderFixSelect('aPrf', true, this.armorFixDb)} +
    +
    + +
    + +
    + {this.renderFixSelect('aSuf', false, this.armorFixDb)} +
    + )} + {this.selectedItem && ( +
    +
    + {!isArmor && ( + + + TODO: Übernahme bei Wechsel +
    + +
    +
    + )} + + +
    + +
    +
    + {this.enchants.map(cardInfo => ( +
    + + +
    + ))} +
    +
    +
    + +
    +
    + )} +
    + +
    + {stats.map(stat => { + const id = 'stat' + stat.id + return ( +
    + + + this.setState({ + stat: Object.assign({}, this.state.stat, { + [stat.id]: Number(e.target.value) + }) + })} + /> +
    + ) + })} +
    + +
    + {this.gearSkillDb.map(skill => ( + this.handleSkillClick(skill)} + > + {colorName(skill.name)} + + ))} +
    +
    + {this.buffItemDb.map(buff => ( + this.handleBuffcardClick(buff)} + > + {colorName(buff.name)} + + ))}
    +
    +
    + +
    + +
    +
    +
    +
    {this.selectedItem && ( - + this.gearSkillDb.find(skill => skill.id === skillId) + ) + .concat( + this.state.bc.map(buffId => + this.buffItemDb.find(skill => skill.id === buffId) + ) + )} + charm={this.charmDb.find( + charmItem => charmItem.id === this.state.ch + )} + armorBonus={ + isArmor + ? [] + : [this.state.aPrf, this.state.aSuf] + .map(fixId => + this.armorFixDb.find(fix => fix.id === Number(fixId)) + ) + .concat([ + this.gearArmorsWithBonus.find( + item => item.id === this.state.arm + ) + ]) + } /> )} ) } + + handleSkillClick(skill) { + let skillState = this.state.sk + + if (skillState.indexOf(skill.id) === -1) { + skillState.push(skill.id) + } else { + skillState = skillState.filter(skillId => skillId !== skill.id) + } + + this.setState({ sk: skillState }) + } + + handleBuffcardClick(skill) { + let buffCardState = this.state.bc + + if (buffCardState.indexOf(skill.id) === -1) { + buffCardState.push(skill.id) + } else { + buffCardState = buffCardState.filter(skillId => skillId !== skill.id) + } + + this.setState({ bc: buffCardState }) + } } export default withRouter(WeaponCalcTool) diff --git a/src/components/About.js b/src/components/About.js deleted file mode 100644 index b02b524..0000000 --- a/src/components/About.js +++ /dev/null @@ -1,32 +0,0 @@ -import React, { PureComponent } from 'react' -import { connect } from 'react-redux' -import { Helmet } from 'react-helmet' -import MarkdownViewer from './MarkdownViewer' - -class About extends PureComponent { - render() { - const { content } = this.props - - return ( -
    - - - About - - - -
    - ) - } -} - -const mapStateToProps = state => { - return { - content: state.cms.contents.about - } -} - -export default connect(mapStateToProps)(About) diff --git a/src/components/ChromeRivals/OnlineCountChart.js b/src/components/ChromeRivals/OnlineCountChart.js index b345811..edefa4a 100644 --- a/src/components/ChromeRivals/OnlineCountChart.js +++ b/src/components/ChromeRivals/OnlineCountChart.js @@ -3,10 +3,10 @@ import { callApiChecked } from '../../middleware/api' import config from '../../config' import { seriesColorCoding } from '../../utils/colors' import AsyncLineChart from '../AsyncLineChart' -import isBefore from 'date-fns/is_before' -import subDays from 'date-fns/sub_days' -import startOfHour from 'date-fns/start_of_hour' -import startOfday from 'date-fns/start_of_day' +import isBefore from 'date-fns/isBefore' +import subDays from 'date-fns/subDays' +import startOfHour from 'date-fns/startOfHour' +import startOfday from 'date-fns/startOfDay' const options = (scale = 'day') => { return { diff --git a/src/components/Contact.js b/src/components/Contact.js deleted file mode 100644 index 6b681df..0000000 --- a/src/components/Contact.js +++ /dev/null @@ -1,140 +0,0 @@ -import React, { Component } from 'react' -import { Helmet } from 'react-helmet' - -import tobiasImg from '../img/techguy_t.jpg' - -const SrcLinkFE = () => { - return ( - - Frontend - - ) -} - -const SrcLinkBE = () => { - return ( - - API-Backend - - ) -} - -const TS3Ref = () => { - return ( - - Address:{' '} - - vi0lation.de - - - ) -} - -class Contact extends Component { - shouldComponentUpdate() { - return false - } - - render() { - return ( -
    - - - Contact - - -

    Contact

    - -
    -

    Tech guy

    - -
    -
    -
    -
    -
    - Tobias -
    -
    -
    -

    Tobias

    -

    - - IGN - : DrDelay -

    -
    -
    -
    -

    - Discord: DrDelay#1337 -

    -

    - - 📧 - {' '} - - info@vi0lation.de - {' '} - ( - PGP - ) -

    -
    -
    -
    -
    - -
    -

    TeamSpeak

    -

    - -

    -
    - -
    -

    Site Source-Code

    -
      -
    • - -
    • -
    • - -
    • -
    -
    -
    - ) - } -} - -export default Contact -export { SrcLinkFE, SrcLinkBE, TS3Ref } diff --git a/src/components/Footer.js b/src/components/Footer.js index 4893e9c..ba30dfc 100644 --- a/src/components/Footer.js +++ b/src/components/Footer.js @@ -1,5 +1,4 @@ import React, { Component } from 'react' -import Link from 'react-router-dom/Link' class Footer extends Component { shouldComponentUpdate() { @@ -10,24 +9,7 @@ class Footer extends Component { return ( ) diff --git a/src/components/Home.js b/src/components/Home.js index 4a25e12..d55dc89 100644 --- a/src/components/Home.js +++ b/src/components/Home.js @@ -1,5 +1,6 @@ import React, { Component } from 'react' import Link from 'react-router-dom/Link' +import { crTopKillsIntervalUrl } from '../routes' class Home extends Component { shouldComponentUpdate() { @@ -9,41 +10,49 @@ class Home extends Component { render() { return (
    -

    Vi0

    +

    ChromeRivals Tools

    - +
    -

    AirRivals/AceOnline

    -

    Tools & Stats

    +

    Fame Ranking

    +

    Date comparison

    -
    - +
    -

    TeamSpeak 3

    -

    Listing of the TS3 Servers

    +

    Playercount

    +

    Online history

    -
    - +
    -

    TERA

    -

    Gameplay / services / stats

    +

    WeaponCalc

    +

    Item/gear stats

    +
    ) diff --git a/src/components/LoadSpinner.css b/src/components/LoadSpinner.css index 40bf90f..221d783 100644 --- a/src/components/LoadSpinner.css +++ b/src/components/LoadSpinner.css @@ -10,8 +10,8 @@ height: 46px; margin: 1px; border-radius: 50%; - border: 5px solid #df691a; - border-color: #df691a transparent #df691a transparent; + border: 5px solid #006488; + border-color: #006488 transparent #006488 transparent; animation: lds-dual-ring 1.2s linear infinite; } @keyframes lds-dual-ring { diff --git a/src/components/Navi.js b/src/components/Navi.js index c97f292..2e07c86 100644 --- a/src/components/Navi.js +++ b/src/components/Navi.js @@ -2,17 +2,8 @@ import React, { Component } from 'react' import withRouter from 'react-router/withRouter' import NavLink from './NavLink' -import classNames from 'classnames' - -import { highscoresUrl, crTopKillsIntervalUrl } from '../routes' - -const NavTab = props => { - return ( -
    - {props.children} -
    - ) -} +import { crTopKillsIntervalUrl } from '../routes' +import { resetCurrentInstance as resetCurrentWeapCalcInstance } from './AR/WeaponCalc/index' const responsiveExpandedClass = 'is-active' const mainNav = 'mainNav' @@ -45,7 +36,7 @@ class Navi extends Component {
    - Vi0 + CRT
    - - - AR/AO - -
    - FrameBreak Tool - StatCalc - EP List - Prokyon/DE Highscores - - ChromeRivals Ranking - - - ChromeRivals Fame chart - - - ChromeRivals Online-players - -
    -
    - - - TeamSpeak 3 - - - - - TERA - - + + Ranking + + + Fame-Chart + + + Playercount + + resetCurrentWeapCalcInstance()} + > + WeaponCalc + + + Events +
    diff --git a/src/components/PushSub.js b/src/components/PushSub.js new file mode 100644 index 0000000..b7b29a1 --- /dev/null +++ b/src/components/PushSub.js @@ -0,0 +1,223 @@ +import React, { Component } from 'react' +import { connect } from 'react-redux' +import { + generateSubscriptionBody, + checkServiceWorkerSupported, + checkPushNotificationsSupported, + checkNotificationsSupported, + checkNotificationDeniedByUser, + push_updateSubscription, + push_subscribe, + sendPushToServer +} from '../utils/pushUtils' +import LoadBlock from './LoadBlock' +import classNames from 'classnames' +import { isNode } from '../utils/env' + +const POSSIBLE_EVENTS = [ + { key: 'sp', name: 'Strategic Point (up to 4 min after spawn)' }, + { key: 'ms', name: 'Mothership (1 hour in advance)' }, + { key: 'op', name: 'Outpost (1 hour in advance)' }, + { key: 'custom', name: 'Custom/Manual notifications' } +] + +class PushSub extends Component { + constructor(props) { + super(props) + this.state = { + buttonDisabled: false, + isPushEnabled: null, + buttonContent: 'Enable Notifications', + errorMessage: null + } + } + + componentDidMount() { + if (isNode) { + return + } + if (!checkServiceWorkerSupported()) { + this.changePushButtonState('incompatible') + this.setState({ + errorMessage: 'Service workers are not supported by this browser!' + }) + return + } + + if (!checkPushNotificationsSupported()) { + this.changePushButtonState('incompatible') + this.setState({ + errorMessage: 'Push notifications are not supported by this browser!' + }) + return + } + + if (!checkNotificationsSupported()) { + this.changePushButtonState('incompatible') + this.setState({ + errorMessage: 'Notifications are not supported by this browser!' + }) + return + } + + if (!checkNotificationDeniedByUser()) { + this.changePushButtonState('incompatible') + this.setState({ errorMessage: 'Notifications are denied by the user!' }) + return + } + + push_updateSubscription(this.changePushButtonState.bind(this)) + } + + render() { + const { + buttonDisabled, + buttonContent, + errorMessage, + isPushEnabled + } = this.state + + if (errorMessage) { + return ( +

    + Not supported: Your browser doesn't provide all the + features required to use push notifications. +
    + Error: {errorMessage} +

    + ) + } + if (isPushEnabled === null) { + return + } + return ( + + ) + } + + changePushSubscriptionButton() { + if (this.state.isPushEnabled) { + this.push_unsubscribe() + } else { + push_subscribe(this.changePushButtonState.bind(this)) + } + } + + changePushButtonState(state, body) { + switch (state) { + case 'enabled': + this.setState({ + buttonDisabled: false, + buttonContent: 'Disable Notifications', + isPushEnabled: true, + pushSubCredBody: body + }) + break + case 'disabled': + this.setState({ + buttonDisabled: false, + buttonContent: 'Enable Notifications', + isPushEnabled: false + }) + break + case 'computing': + this.setState({ buttonDisabled: true, buttonContent: 'Please wait' }) + break + case 'incompatible': + this.setState({ + buttonDisabled: true, + buttonContent: + 'Push notifications are not compatible with this browser' + }) + break + default: + console.error('Unhandled push button state', state) + break + } + } + + push_unsubscribe() { + this.changePushButtonState('computing') + + // To unsubscribe from push messaging, you need to get the subscription object + navigator.serviceWorker.ready + .then(serviceWorkerRegistration => + serviceWorkerRegistration.pushManager.getSubscription() + ) + .then(subscription => { + // Check that we have a subscription to unsubscribe + if (!subscription) { + // No subscription object, so set the state + // to allow the user to subscribe to push + this.changePushButtonState('disabled') + return + } + + // We have a subscription, unsubscribe + // Remove push subscription from server + let body = generateSubscriptionBody(subscription) + + return sendPushToServer('DELETE', body).then(() => subscription) + }) + .then(subscription => subscription.unsubscribe()) + .then(() => this.changePushButtonState('disabled')) + .catch(e => { + // We failed to unsubscribe, this can lead to + // an unusual state, so it may be best to remove + // the users data from your data store and + // inform the user that you have done so + console.error('Error when unsubscribing the user', e) + this.changePushButtonState('disabled') + }) + } +} + +const mapStateToProps = state => { + return { + subEvents: state.push.events + } +} + +export default connect(mapStateToProps)(PushSub) diff --git a/src/components/TERA.js b/src/components/TERA.js deleted file mode 100644 index 1b518a3..0000000 --- a/src/components/TERA.js +++ /dev/null @@ -1,39 +0,0 @@ -import React, { Component } from 'react' -import { Helmet } from 'react-helmet' - -class TERA extends Component { - shouldComponentUpdate() { - return false - } - - render() { - return ( -
    - - - TERA - - -

    TERA

    - -
    -

    DPS Meter Server

    - An instance of{' '} - - tera-dpsmeter-server - {' '} - is deployed at{' '} - tera-dps.vi0lation.de. -
    -
    - ) - } -} - -export default TERA diff --git a/src/components/TS3List.js b/src/components/TS3List.js deleted file mode 100644 index 7d5a3f3..0000000 --- a/src/components/TS3List.js +++ /dev/null @@ -1,56 +0,0 @@ -import React, { Component } from 'react' -import { Helmet } from 'react-helmet' - -const TSRef = props => { - let { url, port } = props.server - - return ( -
  • - - {url} - {' '} - (Port: {port}) -
  • - ) -} - -class TS3List extends Component { - static tsServers = [ - { url: 'vi0lation.de', port: 9987 }, - { url: 'aces.vi0lation.de', port: 9994 }, - { url: 'benson.vi0lation.de', port: 9991 }, - { url: 'epic.vi0lation.de', port: 9993 }, - { url: 'hon.vi0lation.de', port: 9990 }, - { url: 'topgun.vi0lation.de', port: 9988 }, - { url: 'um.vi0lation.de', port: 9989 }, - { url: 'unity.vi0lation.de', port: 9992 } - ] - - shouldComponentUpdate() { - return false - } - - render() { - return ( -
    - - - TeamSpeak 3 Server - - -

    TeamSpeak 3 Server

    - -
      - {this.constructor.tsServers.map(server => ( - - ))} -
    -
    - ) - } -} - -export default TS3List diff --git a/src/components/TS404Server.js b/src/components/TS404Server.js deleted file mode 100644 index a381ed2..0000000 --- a/src/components/TS404Server.js +++ /dev/null @@ -1,44 +0,0 @@ -import React, { Component } from 'react' -import { Helmet } from 'react-helmet' -import Link from 'react-router-dom/Link' - -class TS404Server extends Component { - shouldComponentUpdate() { - return false - } - - render() { - return ( -
    - - - TS3 404-Server - - -

    TS3 404-Server

    - -

    - Getting routed to the 404-Server instead of your intended destination - can generally mean two things: -

    -
      -
    • - There was a temporary with the TSDNS service. Trying to connect - again a bit later will most likely work. -
    • -
    • - You entered an address that is not or no longer mapped to a server -
    • -
    -

    - Refer to the list of available TS3 Servers. -

    -
    - ) - } -} - -export default TS404Server diff --git a/src/config.js b/src/config.js index 699fe7b..09f5eeb 100644 --- a/src/config.js +++ b/src/config.js @@ -1,5 +1,6 @@ const config = { - apibase: 'https://api.vi0lation.de/api/' + apibase: 'https://api.vi0lation.de/api/', + crapibase: 'https://cr-api.vi0.de/q/' } export default config diff --git a/src/containers/AR/Highscores.js b/src/containers/AR/Highscores.js deleted file mode 100644 index 629ab2f..0000000 --- a/src/containers/AR/Highscores.js +++ /dev/null @@ -1,223 +0,0 @@ -import React, { Component } from 'react' -import { Helmet } from 'react-helmet' -import { connect } from 'react-redux' -import PropTypes from 'prop-types' -import Flatpickr from 'react-flatpickr' -import 'flatpickr/dist/themes/material_blue.css' -import dateformat from 'date-fns/format' -import NumTD from '../../components/AR/NumTD' -import { minDate, maxDate } from '../../data/dataset' -import { calcProgessBarByEp } from '../../utils/AR/ep' -import { fetchHighscoreIfNeeded } from '../../actions/highscores' -import { highscoresUrl } from '../../routes' -import withRouter from 'react-router/withRouter' -import { isNode } from '../../utils/env' - -const region = 'de' - -class Ranking extends Component { - // TODO: shouldUpdate - - bootstrap() { - if (isNode) { - return this.queryCurrentDate() - } - } - - componentDidMount() { - this.queryCurrentDate() - } - - componentDidUpdate(prevProps) { - if (this.props.date !== prevProps.date) { - this.queryCurrentDate() - } - } - - queryCurrentDate() { - const { dispatch, date } = this.props - return this.constructor.queryForDate(dispatch, date) - } - - static queryForDate(dispatch, date) { - let hsPromise = dispatch(fetchHighscoreIfNeeded(region, date)) - - return hsPromise - } - - dateSelected(v) { - let dateSelected = dateformat(v[0], 'YYYY-MM-DD') - const { date, history } = this.props - - if (date === dateSelected) { - return - } - - history.push(highscoresUrl + '/' + dateSelected) - } - - tableInfo() { - return ( - - - # - - Name - Gear - Level - Fame - - W - - - L - - - P - - Brigade - Nation - - ) - } - - renderLoadingIndicator() { - const { data } = this.props - if (data || data === false) { - return null - } - return ... - } - - renderForm() { - const { date } = this.props - - return ( - // TODO: Auslagern von generischen Form Stuff -
    e.preventDefault()} className="margin-bot"> -
    -
    - -
    -
    -
    -

    - -

    -
    -
    -
    {this.renderLoadingIndicator()}
    -
    -
    -
    -
    - ) - } - - render() { - const { data, date } = this.props - const is404 = data === false - - if (is404 && this.context.router.staticContext) - this.context.router.staticContext.statusCode = 404 - - return ( -
    - - - {`AirRivals.de ${date} Player Highscores`} - - -

    AirRivals.de Highscores

    -

    {date}

    - - {this.renderForm()} - - {is404 ? ( -
    - No data available for the selected date -
    - ) : ( - this.renderTable(data) - )} -
    - ) - } - - renderTable(data) { - return ( -
    - - {this.tableInfo()} - - {data && - data.map(function(row, idx) { - return ( - - - - - - - - - - - - - ) - })} - - {this.tableInfo()} -
    {idx + 1}{row.name}{row.gear}{calcProgessBarByEp(row.data.ep, row.data.level)}{row.brigade}{row.nation}
    -
    - ) - } -} - -Ranking.propTypes = { - // TODO -} - -Ranking.contextTypes = { - router: PropTypes.shape({ - staticContext: PropTypes.object - }).isRequired -} - -const mapStateToProps = (state, ownProps) => { - const regionData = state.highscores[region] - const { date } = ownProps.match.params - - let data = null - if (regionData) { - const dateData = regionData[date] - if (dateData) { - data = dateData.data - } - } - - return { - date, - data - } -} - -export default withRouter(connect(mapStateToProps)(Ranking)) diff --git a/src/containers/App.js b/src/containers/App.js index b0f3cca..8499a31 100644 --- a/src/containers/App.js +++ b/src/containers/App.js @@ -8,34 +8,31 @@ import routes from '../routes' import Navi from '../components/Navi' import Footer from '../components/Footer' -import { isNode } from '../utils/env' - -import { fetchCmsIfNeeded } from '../actions/cms' +import { isBrowser, isNode } from '../utils/env' +import { canUsePush, push_updateSubscription } from '../utils/pushUtils' const defaultMeta = () => { return ( - + ) } -export const queryData = dispatch => { - return dispatch(fetchCmsIfNeeded('all')) -} - class App extends Component { bootstrap() { if (isNode) { - return queryData(this.props.dispatch) + // return queryData(this.props.dispatch) } } componentDidMount() { - queryData(this.props.dispatch) + if (isBrowser && canUsePush() && navigator.onLine) { + push_updateSubscription(() => {}) + } } render() { diff --git a/src/containers/ChromeRivals/KillsInInterval.js b/src/containers/ChromeRivals/KillsInInterval.js index e4d7801..eb5760e 100644 --- a/src/containers/ChromeRivals/KillsInInterval.js +++ b/src/containers/ChromeRivals/KillsInInterval.js @@ -1,10 +1,8 @@ import React, { Component } from 'react' import { Helmet } from 'react-helmet' -import { connect } from 'react-redux' import dateformat from 'date-fns/format' -import diffMins from 'date-fns/difference_in_minutes' +import subHours from 'date-fns/subHours' import NumTD from '../../components/AR/NumTD' -import { fetchDatesIfNeeded } from '../../actions/cr' import withRouter from 'react-router/withRouter' import Link from 'react-router-dom/Link' import { parse, stringify } from 'querystring' @@ -12,26 +10,32 @@ import { callApiChecked } from '../../middleware/api' import config from '../../config' import { colorName } from '../../utils/AR/names' import blankImg from '../../img/000000-0.png' +import { zonedTimeToUtc, utcToZonedTime, format } from 'date-fns-tz' +import { isNode } from '../../utils/env' +/* import { buildPlayerFameDatasets, options as playerFameChartOpts, queryPlayers } from '../../components/ChromeRivals/PlayerFameChart' import AsyncLineChart from '../../components/AsyncLineChart' - -export const CRDisclaimer = () => ( - - Server:{' '} - - ChromeRivals - . Stats displayed here are based on leaderboard data kindly provided by - their staff / API. - -) +*/ + +const serverTimeZone = 'Europe/Paris' +const browserTimeZone = + Intl && Intl.DateTimeFormat + ? Intl.DateTimeFormat().resolvedOptions().timeZone + : serverTimeZone +const formatDateForTransfer = dateString => { + let parseDate = new Date(dateString) + if (isNaN(parseDate) || !(parseDate instanceof Date)) { + return null + } + return format(parseDate, 'yyyy-MM-dd HH:mm:ssXXX', { + timeZone: serverTimeZone + }) +} +const dateTimeLocalFormat = "yyyy-MM-dd'T'HH:mm:ss" const StatTag = props => (
    @@ -39,17 +43,27 @@ const StatTag = props => ( {props.label} - {props.val.toLocaleString()} + {props.val !== '' ? props.val.toLocaleString() : ''}
    ) class KillsInInterval extends Component { - // TODO: shouldUpdate/Perf - constructor(props) { super(props) - this.state = { result: null } + + let nowServerTimeDate = utcToZonedTime( + zonedTimeToUtc(new Date(), browserTimeZone), + serverTimeZone + ) + + this.state = { + result: null, + resultNation: null, + resultGearDeaths: null, + nowServerTime: nowServerTimeDate, + nowInServerTimezone: dateformat(nowServerTimeDate, dateTimeLocalFormat) + } this.TableInfo = ( @@ -65,82 +79,112 @@ class KillsInInterval extends Component { } componentDidMount() { - this.queryAvailableDates() this.queryData() + let latestKillDatePromise = callApiChecked( + config.crapibase + 'latestKillDate' + ) + latestKillDatePromise.then(res => { + let resDate = new Date(res) + this.setState({ + nowServerTime: resDate, + nowInServerTimezone: dateformat(resDate, dateTimeLocalFormat) + }) + this.preselectOnLoad() + }) } - queryAvailableDates() { - this.props.dispatch(fetchDatesIfNeeded()) - } + preselectOnLoad() { + if (isNode) { + return + } + const currentQs = this.getQueryParams() + if (currentQs.from || currentQs.to) { + return false + } - queryData(qs) { - const { dispatch } = this.props + let qs = { + from: dateformat( + subHours(this.state.nowServerTime, 1), + dateTimeLocalFormat + ), + to: this.state.nowInServerTimezone + } + this.props.history.replace({ + search: stringify(qs) + }) + this.queryData(qs) + } - if (!qs) { - qs = this.getQueryParams() + queryData(qsOrg) { + if (!qsOrg) { + qsOrg = this.getQueryParams() } - let dataPromise = this.constructor.queryForDate(dispatch, qs.from, qs.to) - this.setState({ - result: null, - loadingData: dataPromise, - topchartdata: null - }) - if (dataPromise) { - dataPromise.then(result => { - if (!('stats' in result)) { - result = false - } - this.setState({ result, loadingData: false }) - if ( - result && - result.data.length > 4 && - diffMins(qs.to, qs.from) > 59 && - diffMins(qs.to, qs.from) < 600 - ) { - let topnames = result.data - .slice(0, Math.min(8, result.data.length)) - .map(row => row.name) - let topChartPromises = queryPlayers( - topnames, - stringify({ - from: qs.from, - to: qs.to - }) - ) - this.setState({ loadingTopChartData: topChartPromises }) - topChartPromises.then(data => { - this.setState({ - topchartdata: data.map(player => { - let playerStartFame = player.data[0].fame - player.data = player.data.map(playerdataRow => { - playerdataRow.fame = playerdataRow.fame - playerStartFame - return playerdataRow - }) - return player - }), - loadingTopChartData: false - }) - }) - } + if (!(qsOrg.to && qsOrg.from)) { + this.setState({ + result: null, + loadingData: null, + topchartdata: null }) + return } - } - static queryForDate(dispatch, from, to) { - if (!(to && from)) { - return null + let qs = { + from: formatDateForTransfer(qsOrg.from), + to: formatDateForTransfer(qsOrg.to) } - let endpoint = - config.apibase + - 'chromerivals/topkillsinterval?' + - stringify({ - from, - to + if (!(qs.to && qs.from)) { + this.setState({ + result: null, + loadingData: null, + topchartdata: null }) - let hsPromise = callApiChecked(endpoint, {}, [400, 404]) + return + } + + let dateQuery = '?' + stringify(qs) + + let playerKillsPromise = callApiChecked( + config.crapibase + 'killsBetween' + dateQuery + ) + let nationKillsPromise = callApiChecked( + config.crapibase + 'nationKillsBetween' + dateQuery + ) + let gearDeathsPromise = callApiChecked( + config.crapibase + 'gearDeathsBetween' + dateQuery + ) - return hsPromise + this.setState({ + resultNation: null, + resultGearDeaths: null, + result: null, + loadingData: Promise.all([ + playerKillsPromise, + nationKillsPromise, + gearDeathsPromise + ]), + topchartdata: null // Make this working again? + }) + playerKillsPromise.then(result => { + if (!('stats' in result) || result.data.length === 0) { + result = false + } + this.setState({ result, loadingData: false }) + }) + nationKillsPromise.then(result => { + let resultObj = { BCU: 0, ANI: 0 } + result.forEach(nation => { + resultObj[nation.nation] = nation.killcount + }) + this.setState({ resultNation: resultObj }) + }) + gearDeathsPromise.then(result => { + let resultObj = { I: 0, M: 0, B: 0, A: 0 } + result.forEach(gear => { + resultObj[gear.gear] = gear.deathcount + }) + this.setState({ resultGearDeaths: resultObj }) + }) } getQueryParams() { @@ -148,6 +192,7 @@ class KillsInInterval extends Component { } dateSelected(v, arg) { + console.log(v) const currentQs = this.getQueryParams() let dateSelected = v @@ -188,10 +233,6 @@ class KillsInInterval extends Component { } renderForm() { - if (this.props.rankingDates === null || this.props.isFetchingDates) { - return ... - } - return (
    e.preventDefault()} className="margin-bot">
    @@ -212,25 +253,17 @@ class KillsInInterval extends Component { return (
    -
    - -
    + this.dateSelected(e.target.value, fromto)} + />
    ) @@ -238,7 +271,6 @@ class KillsInInterval extends Component { render() { const { result } = this.state - const is404 = result === false const { from, to } = this.getQueryParams() @@ -256,19 +288,11 @@ class KillsInInterval extends Component { {`ChromeRivals: Fame between`} -

    ChromeRivals: Fame between

    +

    CR Fame between

    {this.renderForm()} - {is404 ? ( -
    - No data available for the selected date -
    - ) : ( - this.renderTable(result) - )} - - + {this.renderTable(result)}
    ) } @@ -285,13 +309,46 @@ class KillsInInterval extends Component {

    Kills

    - - + +
    +
    +

    Deaths

    + + + + +

    Player-Count (Fame-Diff ≠ 0)

    {['I', 'M', 'B', 'A'].map(gear => @@ -308,7 +365,7 @@ class KillsInInterval extends Component { } renderDataLoading() { - if (this.state.loadingData || this.state.loadingTopChartData) { + if (this.state.loadingData) { return ( ... @@ -333,32 +390,37 @@ class KillsInInterval extends Component { {result && result.data && result.data.map(function(row, idx) { - let showLadder = lastKillNum !== row.diff - lastKillNum = row.diff + let showLadder = lastKillNum !== row.killcount + lastKillNum = row.killcount + + if (!row.player) { + console.warn('Row without player entity', row) + return null + } return ( - + {showLadder ? idx + 1 : null} - {colorName(row.name)} + {colorName(row.player.name)} - - {row.gear} + + {row.player.gear} - {row.brigade && ( + {row.player.brigade && ( {row.brigade} )}{' '} - {row.brigade} + {row.player.brigade} - {row.nation} + {row.player.nation} ) })} @@ -379,43 +441,9 @@ class KillsInInterval extends Component { {this.TableInfo}
    - {this.state.topchartdata && ( - - )}
    ) } } -const mapStateToProps = state => { - const rankingDatesStore = state.cr.dates - - let rankingDates = null - let isFetchingDates = false - if (rankingDatesStore) { - isFetchingDates = rankingDatesStore.isFetching - } - if (rankingDatesStore && 'data' in rankingDatesStore) { - const tzRegex = /(\+.*)$/ - rankingDates = rankingDatesStore.data.map(date => { - let tz = date.match(tzRegex)[1] - return [ - dateformat(new Date(date.replace(/\+.*$/, '')), 'YYYY-MM-DD HH:mm'), - tz - ] - }) - } - - return { - rankingDates, - isFetchingDates - } -} - -export default withRouter(connect(mapStateToProps)(KillsInInterval)) +export default withRouter(KillsInInterval) diff --git a/src/containers/ChromeRivals/OnlineCount.js b/src/containers/ChromeRivals/OnlineCount.js index f6239fa..8522558 100644 --- a/src/containers/ChromeRivals/OnlineCount.js +++ b/src/containers/ChromeRivals/OnlineCount.js @@ -1,7 +1,6 @@ import React, { Component } from 'react' import { Helmet } from 'react-helmet' import OnlineCountChart from '../../components/ChromeRivals/OnlineCountChart' -import { CRDisclaimer } from './KillsInInterval' import debounce from 'lodash.debounce' class OnlineCount extends Component { @@ -56,13 +55,11 @@ class OnlineCount extends Component { {title} -

    {title}

    +

    CR Player count

    {this.renderForm()} {backdays > 0 && } - -
    ) } diff --git a/src/containers/ChromeRivals/PlayerFameChart.js b/src/containers/ChromeRivals/PlayerFameChart.js index 7ce4587..0c7653d 100644 --- a/src/containers/ChromeRivals/PlayerFameChart.js +++ b/src/containers/ChromeRivals/PlayerFameChart.js @@ -3,7 +3,6 @@ import { Helmet } from 'react-helmet' import debounce from 'lodash.debounce' import withRouter from 'react-router/withRouter' import PlayerFameChartChart from '../../components/ChromeRivals/PlayerFameChart' -import { CRDisclaimer } from './KillsInInterval' import { parse, stringify } from 'querystring' class PlayerFameChart extends Component { @@ -107,7 +106,7 @@ class PlayerFameChart extends Component { {title} -

    {title}

    +

    CR Fame growth chart

    {this.renderForm()} @@ -119,8 +118,6 @@ class PlayerFameChart extends Component { brigade={brigade} /> )} - -
    ) } diff --git a/src/data/ao.js b/src/data/ao.js index b84c133..d3cc34d 100644 --- a/src/data/ao.js +++ b/src/data/ao.js @@ -8,4 +8,77 @@ export const unitKinds = { export const standardWeapons = [0, 1, 2, 3, 4, 5, 6, 7] export const advWeapons = [8, 9, 10, 11, 12, 13, 14, 15] +const ITEMKIND_ALL_ITEM = 40 +export const ITEMKIND_ACCESSORY_TIMELIMIT = 32 export const ITEMKIND_SKILL_ATTACK = 50 +export const ITEMKIND_SKILL_DEFENSE = 51 +export const ITEMKIND_DEFENSE = 16 +export const ITEMKIND_CARD = 20 +export const ITEMKIND_ENCHANT = 21 + +export const DES_ENCHANT_INITIALIZE = 105 + +const ITEMKIND_PRIMARY_WEAPON = 44 +const ITEMKIND_SECONDARY_WEAPON = 48 + +export const IS_PRIMARY_WEAPON = kind => standardWeapons.indexOf(kind) !== -1 +export const IS_SECONDARY_WEAPON = kind => advWeapons.indexOf(kind) !== -1 + +export const COMPARE_ITEMKIND = (_REQ_ITEM_KIND, _TARGET_KIND_VAR) => { + if (_REQ_ITEM_KIND === ITEMKIND_ALL_ITEM) { + return true + } + if (_TARGET_KIND_VAR === _REQ_ITEM_KIND) { + return true + } + switch (_REQ_ITEM_KIND) { + case ITEMKIND_PRIMARY_WEAPON: + return IS_PRIMARY_WEAPON(_TARGET_KIND_VAR) + case ITEMKIND_SECONDARY_WEAPON: + return IS_SECONDARY_WEAPON(_TARGET_KIND_VAR) + default: + //throw new Error('Unexpected _REQ_ITEM_KIND '+_REQ_ITEM_KIND) + return false + } +} + +export const DES_MAP = { + STD_MIN: 18, + STD_MAX: 71, + STD_PROB: 20, + ADV_MIN: 19, + ADV_MAX: 72, + ADV_PROB: 21, + STD_EVA: 24, + ADV_EVA: 25, + STD_DEF: 22, + ADV_DEF: 23, + HP: 13, + DP: 89, + STD_PIERCE: 184, + ADV_PIERCE: 185, + STD_RA: 31, + ADV_RA: 32, + STD_WEIGHT: 75, + ADV_WEIGHT: 76, + STD_SHOTS: 44, + ADV_SHOTS: 69, + STD_MULTI: 45, + ADV_MULTI: 70 +} + +export const desKeyByDesNum = desNum => { + let foundPair = Object.entries(DES_MAP).find(pair => pair[1] === desNum) + return foundPair ? foundPair[0] : false +} + +export const baseValuesToDesKeyMap = { + AbilityMin: `_MIN`, + AbilityMax: `_MAX`, + HitRate: '_PROB', + FractionResistance: '_PIERCE', + ReAttacktime: '_RA', + Weight: '_WEIGHT', + ShotNum: '_SHOTS', + MultiNum: '_MULTI' +} diff --git a/src/data/dataset.js b/src/data/dataset.js deleted file mode 100644 index 85da710..0000000 --- a/src/data/dataset.js +++ /dev/null @@ -1,2 +0,0 @@ -export const minDate = '2012-01-01' -export const maxDate = '2016-08-24' diff --git a/src/img/techguy_t.jpg b/src/img/techguy_t.jpg deleted file mode 100644 index 0bee3ac..0000000 Binary files a/src/img/techguy_t.jpg and /dev/null differ diff --git a/src/index.css b/src/index.css index 49936c4..36c8b47 100644 --- a/src/index.css +++ b/src/index.css @@ -20,3 +20,20 @@ body { img.profile { border-radius: 10%; } + +.button.is-info { + background-color: #006488; +} + +.hero.vi0 { + background-image: linear-gradient( + 141deg, + #bb340b, + #df691a 71%, + #ec9726 + ) !important; +} + +.tag:not(body).is-activated { + box-shadow: 0 0 0 2pt #48c774; +} diff --git a/src/index.js b/src/index.js index 2369f75..ecc945a 100644 --- a/src/index.js +++ b/src/index.js @@ -21,7 +21,7 @@ import toast from './utils/toast' // If provided by server, use it, else let the reducers handle initial state // const initialState = window.DATA || {} -const store = configureStore() +export const store = configureStore() const app = ( { - if (i < 120) { - return true - } - let dt = new Date(date) - let dayDiffDt = dayDiff(now, dt) - if (dayDiffDt <= 6) { - return true - } - let dayFrmt = format(dt, 'YYYY-MM-DD') - let dateHm = format(dt, 'HH:mm') - if (days.indexOf(dayFrmt) !== -1) { - if (midNightRegex.test(dateHm)) { - nextDay = format(sub_days(dt, 1), 'YYYY-MM-DD') - } else { - return false - } - } - days.push(dayFrmt) - if (nextDay === dayFrmt && twentyThreeHoursRegex.test(dateHm)) { - return false - } - return true - }) - }) - }) - default: - return state - } + return state } diff --git a/src/reducers/highscores.js b/src/reducers/highscores.js deleted file mode 100644 index 8338604..0000000 --- a/src/reducers/highscores.js +++ /dev/null @@ -1,33 +0,0 @@ -import { REQUEST, RECEIVE } from '../types/highscores' -import { getCurrentTS } from '../utils/api' - -const initialState = { - de: {} -} - -export default function reducer(state = initialState, action) { - let { region, date } = action - let regionData = Object.assign({}, state[region]) - switch (action.type) { - case REQUEST: - return Object.assign({}, state, { - [region]: Object.assign(regionData, { - [date]: { - isFetching: getCurrentTS() - } - }) - }) - case RECEIVE: - const { response } = action - return Object.assign({}, state, { - [region]: Object.assign(regionData, { - [date]: { - isFetching: false, - data: response.date ? false : response // object with date key -> an error occured - } - }) - }) - default: - return state - } -} diff --git a/src/reducers/index.js b/src/reducers/index.js index e2627c4..b81e043 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -1,11 +1,9 @@ import { combineReducers } from 'redux' -import highscores from './highscores' -import cms from './cms' import cr from './cr' +import push from './push' export default combineReducers({ - highscores, - cms, - cr + cr, + push }) diff --git a/src/reducers/push.js b/src/reducers/push.js new file mode 100644 index 0000000..5a831da --- /dev/null +++ b/src/reducers/push.js @@ -0,0 +1,14 @@ +const initialState = { + events: [] +} + +export default function reducer(state = initialState, action) { + switch (action.type) { + case 'SET_EVENTS': + return Object.assign({}, state, { + events: action.events + }) + default: + return state + } +} diff --git a/src/routes.js b/src/routes.js index be816ef..09d9bae 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1,25 +1,14 @@ import React from 'react' -import Redirect from 'react-router/Redirect' import Home from './components/Home' -import TS3List from './components/TS3List' -import TERA from './components/TERA' -import TS404Server from './components/TS404Server' -import About from './components/About' -import Contact from './components/Contact' - -import RankingInfo from './components/AR/RankingInfo' import NoMatch from './components/NoMatch' -import { maxDate } from './data/dataset' - import lazyImport from './utils/lazyImportHack' import { asyncComponent } from 'react-async-component' import LoadBlock from './components/LoadBlock' -export const highscoresUrl = '/ranking/de/highscores' -export const crTopKillsIntervalUrl = '/ranking/chromerivals/topkillsinterval' +export const crTopKillsIntervalUrl = '/killsBetween' const LoadingComponent = () => @@ -37,57 +26,13 @@ const routes = [ component: Home }, { - path: '/ts3', - component: TS3List - }, - { - path: '/tera', - component: TERA - }, - { - path: '/404server', - component: TS404Server - }, - { - path: '/about', - component: About - }, - { - path: '/contact', - component: Contact - }, - { - path: '/ranking', - exact: true, - component: RankingInfo - }, - { - path: '/ranking/eplist', - component: makeAsync(() => lazyImport(import('./components/AR/EPList'))) - }, - { - path: '/ranking/fbtool', - component: makeAsync(() => lazyImport(import('./components/AR/FBTool'))) - }, - { - path: '/ranking/statcalc', + path: '/statcalc', component: makeAsync(() => lazyImport(import('./components/AR/StatCalc'))) }, - /* { - path: '/ranking/weaponcalc', + path: '/weaponcalc', component: makeAsync(() => lazyImport(import('./components/AR/WeaponCalc'))) }, - */ - { - path: highscoresUrl, - exact: true, - component: () => - }, - { - path: highscoresUrl + '/:date(\\d{4}-\\d{2}-\\d{2})', - component: makeAsync(() => lazyImport(import('./containers/AR/Highscores'))) - }, { path: crTopKillsIntervalUrl, component: makeAsync(() => @@ -95,17 +40,21 @@ const routes = [ ) }, { - path: '/ranking/chromerivals/playerFame', + path: '/fameChart', component: makeAsync(() => lazyImport(import('./containers/ChromeRivals/PlayerFameChart')) ) }, { - path: '/ranking/chromerivals/usercount', + path: '/usercount', component: makeAsync(() => lazyImport(import('./containers/ChromeRivals/OnlineCount')) ) }, + { + path: '/events', + component: makeAsync(() => lazyImport(import('./components/PushSub'))) + }, { component: NoMatch } diff --git a/src/style/bulma.scss b/src/style/bulma.scss index d2d8187..892662b 100644 --- a/src/style/bulma.scss +++ b/src/style/bulma.scss @@ -7,9 +7,9 @@ $family-sans-serif: 'Roboto', sans-serif; $family-primary: $family-sans-serif; -$background-color: #2b3e50; +$background-color: #080325; -$primary: #df691a; +$primary: #006488; $viowhite: #ebebeb; diff --git a/src/types/cms.js b/src/types/cms.js deleted file mode 100644 index caf9421..0000000 --- a/src/types/cms.js +++ /dev/null @@ -1,4 +0,0 @@ -const prefix = 'CMS/' - -export const REQUEST = prefix + 'REQUEST' -export const RECEIVE = prefix + 'RECEIVE' diff --git a/src/types/highscores.js b/src/types/highscores.js deleted file mode 100644 index 0cb2a02..0000000 --- a/src/types/highscores.js +++ /dev/null @@ -1,5 +0,0 @@ -const prefix = 'HIGHSCORES/' - -export const REQUEST = prefix + 'REQUEST' -export const RECEIVE = prefix + 'RECEIVE' -export const REQFAIL = prefix + 'REQFAIL' diff --git a/src/utils/AR/names.js b/src/utils/AR/names.js index 9bb0c5a..b58acaf 100644 --- a/src/utils/AR/names.js +++ b/src/utils/AR/names.js @@ -3,11 +3,22 @@ import React from 'react' const colorMap = { e: '#F4AE0B', c: '#00CCCC', - m: '#ff00ff' + m: '#ff00ff', + a: '#A8A8FF', + h: '#ff8811', + k: '#aa4400', + u: '#aa33ff', + v: '#007300', + b: '#2255ff', + d: '#777777', + y: '#C2C200', + l: '#00aaff', + g: '#00ff00', + r: '#ff0000' } function specialNames(name) { - let regex = name.match(/^(.+)4K$/) + let regex = name.match(/^(.*)4K(.*)$/) if (!regex) { return name } @@ -15,13 +26,15 @@ function specialNames(name) { {regex[1]} 4K + {regex[2]} ) } export function colorName(name) { - let regex = name.match(/^\\([a-z])(.+)\\[a-z]$/) - if (!regex) { + let regex = name.match(/^\\([a-z])(.+)\\([a-z])$/) + if (!regex || regex[1] !== regex[3]) { + // opening/closing color differ? return specialNames(name) } let color = colorMap[regex[1]] diff --git a/src/utils/pushUtils.js b/src/utils/pushUtils.js new file mode 100644 index 0000000..f61a46a --- /dev/null +++ b/src/utils/pushUtils.js @@ -0,0 +1,134 @@ +import { callApiChecked } from '../middleware/api' +import config from '../config' + +const applicationServerKey = + 'BKj3l3KSXQlD52OW8NszYbgGYmIuk_BUevF5u7TDTfaY9HDtPO_iwcYHgY1jpAkBouP5MwdQ2B-45acMXZMDVRg' + +export function checkServiceWorkerSupported() { + return 'serviceWorker' in navigator +} + +export function checkPushNotificationsSupported() { + return 'PushManager' in window +} + +export function checkNotificationsSupported() { + return 'showNotification' in ServiceWorkerRegistration.prototype +} + +export function checkNotificationDeniedByUser() { + // Check the current Notification permission. + // If its denied, the button should appears as such, until the user changes the permission manually + return Notification.permission !== 'denied' +} + +export function canUsePush() { + return ( + checkServiceWorkerSupported() && + checkPushNotificationsSupported() && + checkNotificationsSupported() && + checkNotificationDeniedByUser() + ) +} + +export function urlBase64ToUint8Array(base64String) { + const padding = '='.repeat((4 - base64String.length % 4) % 4) + // eslint-disable-next-line + const base64 = (base64String + padding).replace(/\-/g, '+').replace(/_/g, '/') + + const rawData = window.atob(base64) + const outputArray = new Uint8Array(rawData.length) + + for (let i = 0; i < rawData.length; ++i) { + outputArray[i] = rawData.charCodeAt(i) + } + return outputArray +} + +export function generateSubscriptionBody(subscription) { + const key = subscription.getKey('p256dh') + const token = subscription.getKey('auth') + return { + endpoint: subscription.endpoint, + key: key + ? btoa(String.fromCharCode.apply(null, new Uint8Array(key))) + : null, + token: token + ? btoa(String.fromCharCode.apply(null, new Uint8Array(token))) + : null + } +} + +export function push_updateSubscription(stateCallback) { + navigator.serviceWorker.ready + .then(serviceWorkerRegistration => + serviceWorkerRegistration.pushManager.getSubscription() + ) + .then(subscription => { + if (!subscription) { + stateCallback('disabled') + // We aren't subscribed to push, so set UI to allow the user to enable push + return + } + + // Keep your server in sync with the latest endpoint + let body = generateSubscriptionBody(subscription) + + return sendPushToServer('PUT', body).then(() => subscription) + }) + .then( + subscription => + subscription && + stateCallback('enabled', generateSubscriptionBody(subscription)) + ) // Set your UI to show they have subscribed for push messages + .catch(e => { + console.error('Error when updating the subscription', e) + }) +} + +export function push_subscribe(stateCallback) { + stateCallback('computing') + + navigator.serviceWorker.ready + .then(serviceWorkerRegistration => + serviceWorkerRegistration.pushManager.subscribe({ + userVisibleOnly: true, + applicationServerKey: urlBase64ToUint8Array(applicationServerKey) + }) + ) + .then(subscription => { + // Subscription was successful + // create subscription on your server + let body = generateSubscriptionBody(subscription) + + return sendPushToServer('POST', body).then(() => subscription) + }) + .then( + subscription => + subscription && + stateCallback('enabled', generateSubscriptionBody(subscription)) + ) // update your UI + .catch(e => { + if (Notification.permission === 'denied') { + // The user denied the notification permission which + // means we failed to subscribe and the user will need + // to manually change the notification permission to + // subscribe to push messages + console.warn('Notifications are denied by the user :((') + stateCallback('incompatible') + } else { + // A problem occurred with the subscription; common reasons + // include network errors or the user skipped the permission + console.error('Impossible to subscribe to push notifications', e) + stateCallback('disabled') + } + }) +} + +export function sendPushToServer(method, body) { + body.events = require('../index').store.getState().push.events + return callApiChecked(config.apibase + 'pushsub', { + method: method, + body: JSON.stringify(body) + }) +}