Got it working
167
package-lock.json
generated
|
@ -955,12 +955,6 @@
|
|||
"tiny-glob": "^0.2.2"
|
||||
}
|
||||
},
|
||||
"@types/core-js": {
|
||||
"version": "0.9.46",
|
||||
"resolved": "https://registry.npmjs.org/@types/core-js/-/core-js-0.9.46.tgz",
|
||||
"integrity": "sha512-LooLR6XHes9V+kNYRz1Qm8w3atw9QMn7XeZUmIpUelllF9BdryeUKd/u0Wh5ErcjpWfG39NrToU9MF7ngsTFVw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/events": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
|
||||
|
@ -984,16 +978,10 @@
|
|||
"integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/mkdirp": {
|
||||
"version": "0.3.29",
|
||||
"resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-0.3.29.tgz",
|
||||
"integrity": "sha1-fyrX7FX5FEgvybHsS7GuYCjUYGY=",
|
||||
"dev": true
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "9.6.48",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.48.tgz",
|
||||
"integrity": "sha512-velR2CyDrHC1WFheHr5Jm25mdCMs0BXJRp6u0zf8PF9yeOy4Xff5sJeusWS7xOmhAoezlSq8LJ0+9M5H7YkTdw==",
|
||||
"version": "12.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.0.tgz",
|
||||
"integrity": "sha512-Jrb/x3HT4PTJp6a4avhmJCDEVrPdqLfl3e8GGMbpkGGdwAV5UGlIs4vVEfsHHfylZVOKZWpOqmqFH8CbfOZ6kg==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/q": {
|
||||
|
@ -1002,12 +990,6 @@
|
|||
"integrity": "sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/rimraf": {
|
||||
"version": "0.0.28",
|
||||
"resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-0.0.28.tgz",
|
||||
"integrity": "sha1-VWJRm8eWPKyoq/fxKMrjtZTUHQY=",
|
||||
"dev": true
|
||||
},
|
||||
"@webassemblyjs/ast": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz",
|
||||
|
@ -2070,9 +2052,9 @@
|
|||
}
|
||||
},
|
||||
"caniuse-lite": {
|
||||
"version": "1.0.30000963",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000963.tgz",
|
||||
"integrity": "sha512-n4HUiullc7Lw0LyzpeLa2ffP8KxFBGdxqD/8G3bSL6oB758hZ2UE2CVK+tQN958tJIi0/tfpjAc67aAtoHgnrQ==",
|
||||
"version": "1.0.30000966",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000966.tgz",
|
||||
"integrity": "sha512-qqLQ/uYrpZmFhPY96VuBkMEo8NhVFBZ9y/Bh+KnvGzGJ5I8hvpIaWlF2pw5gqe4PLAL+ZjsPgMOvoXSpX21Keg==",
|
||||
"dev": true
|
||||
},
|
||||
"chalk": {
|
||||
|
@ -2125,15 +2107,12 @@
|
|||
"dev": true
|
||||
},
|
||||
"chrome-launcher": {
|
||||
"version": "0.10.5",
|
||||
"resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-0.10.5.tgz",
|
||||
"integrity": "sha512-Gbzg8HlWhyuoVqflhiXwfFXhzNfNWvAkSWv2QR1Yl6mwsMo1oCLAVjp2tIySuS4lrZLEjzVx1fOy584yE76P4g==",
|
||||
"version": "0.10.7",
|
||||
"resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-0.10.7.tgz",
|
||||
"integrity": "sha512-IoQLp64s2n8OQuvKZwt77CscVj3UlV2Dj7yZtd1EBMld9mSdGcsGy9fN5hd/r4vJuWZR09it78n1+A17gB+AIQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/core-js": "^0.9.41",
|
||||
"@types/mkdirp": "^0.3.29",
|
||||
"@types/node": "^9.3.0",
|
||||
"@types/rimraf": "^0.0.28",
|
||||
"@types/node": "*",
|
||||
"is-wsl": "^1.1.0",
|
||||
"lighthouse-logger": "^1.0.0",
|
||||
"mkdirp": "0.5.1",
|
||||
|
@ -3222,9 +3201,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"electron-to-chromium": {
|
||||
"version": "1.3.127",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.127.tgz",
|
||||
"integrity": "sha512-1o25iFRf/dbgauTWalEzmD1EmRN3a2CzP/K7UVpYLEBduk96LF0FyUdCcf4Ry2mAWJ1VxyblFjC93q6qlLwA2A==",
|
||||
"version": "1.3.131",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.131.tgz",
|
||||
"integrity": "sha512-NSO4jLeyGLWrT4mzzfYX8vt1MYCoMI5LxSYAjt0H9+LF/14JyiKJSyyjA6AJTxflZlEM5v3QU33F0ohbPMCAPg==",
|
||||
"dev": true
|
||||
},
|
||||
"elliptic": {
|
||||
|
@ -3891,9 +3870,9 @@
|
|||
}
|
||||
},
|
||||
"eslint-plugin-node": {
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-9.0.0.tgz",
|
||||
"integrity": "sha512-46VIO0apTu0b5Hh+lFsTGeRBG+3XksfVR3CrSrP+Bk+bYVuSQ3JxlCW3RLiJYtC0HxKbn4HFqepj+DT8HRUGGQ==",
|
||||
"version": "9.0.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-9.0.1.tgz",
|
||||
"integrity": "sha512-fljT5Uyy3lkJzuqhxrYanLSsvaILs9I7CmQ31atTtZ0DoIzRbbvInBh4cQ1CrthFHInHYBQxfPmPt6KLHXNXdw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"eslint-plugin-es": "^1.4.0",
|
||||
|
@ -5204,6 +5183,16 @@
|
|||
"integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
|
||||
"dev": true
|
||||
},
|
||||
"git-directory-deploy": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/git-directory-deploy/-/git-directory-deploy-1.5.1.tgz",
|
||||
"integrity": "sha1-xPrYwnDWeNXzCfvd6sHtpgytf9I=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lodash": "^4.14.2",
|
||||
"minimist": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.1.3",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
|
||||
|
@ -5663,6 +5652,14 @@
|
|||
"integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
|
||||
"dev": true
|
||||
},
|
||||
"immutability-helper": {
|
||||
"version": "2.9.1",
|
||||
"resolved": "https://registry.npmjs.org/immutability-helper/-/immutability-helper-2.9.1.tgz",
|
||||
"integrity": "sha512-r/RmRG8xO06s/k+PIaif2r5rGc3j4Yhc01jSBfwPCXDLYZwp/yxralI37Df1mwmuzcCsen/E/ITKcTEvc1PQmQ==",
|
||||
"requires": {
|
||||
"invariant": "^2.2.0"
|
||||
}
|
||||
},
|
||||
"import-cwd": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz",
|
||||
|
@ -5787,7 +5784,6 @@
|
|||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
|
||||
"integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"loose-envify": "^1.0.0"
|
||||
}
|
||||
|
@ -6104,8 +6100,7 @@
|
|||
"js-tokens": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
|
||||
},
|
||||
"js-yaml": {
|
||||
"version": "3.13.1",
|
||||
|
@ -6322,6 +6317,16 @@
|
|||
"integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=",
|
||||
"dev": true
|
||||
},
|
||||
"lodash.omit": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz",
|
||||
"integrity": "sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA="
|
||||
},
|
||||
"lodash.pick": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz",
|
||||
"integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM="
|
||||
},
|
||||
"lodash.uniq": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
|
||||
|
@ -6338,7 +6343,6 @@
|
|||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
||||
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"js-tokens": "^3.0.0 || ^4.0.0"
|
||||
}
|
||||
|
@ -6886,8 +6890,7 @@
|
|||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
|
||||
"dev": true
|
||||
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
|
||||
},
|
||||
"object-copy": {
|
||||
"version": "0.1.0",
|
||||
|
@ -6985,9 +6988,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"offline-plugin": {
|
||||
"version": "5.0.6",
|
||||
"resolved": "https://registry.npmjs.org/offline-plugin/-/offline-plugin-5.0.6.tgz",
|
||||
"integrity": "sha512-qvcDmeI30xmvSlmqjopAj7QCuM1MEzvmDyuMTN2saDReSay5nUqCpKysexH1KUNXv5H/TfmHd+rngNPkRFj3YA==",
|
||||
"version": "5.0.7",
|
||||
"resolved": "https://registry.npmjs.org/offline-plugin/-/offline-plugin-5.0.7.tgz",
|
||||
"integrity": "sha512-ArMFt4QFjK0wg8B5+R/6tt65u6Dk+Pkx4PAcW5O7mgIF3ywMepaQqFOQgfZD4ybanuGwuJihxUwMRgkzd+YGYw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"deep-extend": "^0.5.1",
|
||||
|
@ -7437,9 +7440,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"postcss": {
|
||||
"version": "7.0.14",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.14.tgz",
|
||||
"integrity": "sha512-NsbD6XUUMZvBxtQAJuWDJeeC4QFsmWsfozWxCJPWf3M55K9iu2iMDaKqyoOdTJ1R4usBXuxlVFAIo8rZPQD4Bg==",
|
||||
"version": "7.0.16",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz",
|
||||
"integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chalk": "^2.4.2",
|
||||
|
@ -7969,14 +7972,39 @@
|
|||
"dev": true
|
||||
},
|
||||
"preact": {
|
||||
"version": "10.0.0-beta.1",
|
||||
"resolved": "https://registry.npmjs.org/preact/-/preact-10.0.0-beta.1.tgz",
|
||||
"integrity": "sha512-1uhj3JXOEzEPUof5t/iQW5heEvTOpexwS0FLAjJQfgfT8OCXICyzI2TwkYyFJ+W9q9GsDmhZgFagH2G0akFveQ=="
|
||||
"version": "8.4.2",
|
||||
"resolved": "https://registry.npmjs.org/preact/-/preact-8.4.2.tgz",
|
||||
"integrity": "sha512-TsINETWiisfB6RTk0wh3/mvxbGRvx+ljeBccZ4Z6MPFKgu/KFGyf2Bmw3Z/jlXhL5JlNKY6QAbA9PVyzIy9//A=="
|
||||
},
|
||||
"preact-compat": {
|
||||
"version": "3.18.5",
|
||||
"resolved": "https://registry.npmjs.org/preact-compat/-/preact-compat-3.18.5.tgz",
|
||||
"integrity": "sha512-F174NW6PI5GU+T28B0ZHblhxMsFaPVaSBiaE++xrxdDVunsO0mARYfOSZizTdb/PFLqXDzcQ1IWdnEt/vIiUvw==",
|
||||
"requires": {
|
||||
"immutability-helper": "^2.7.1",
|
||||
"preact-render-to-string": "^3.8.2",
|
||||
"preact-transition-group": "^1.1.1",
|
||||
"prop-types": "^15.6.2",
|
||||
"standalone-react-addons-pure-render-mixin": "^0.1.1"
|
||||
}
|
||||
},
|
||||
"preact-render-to-string": {
|
||||
"version": "3.8.2",
|
||||
"resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-3.8.2.tgz",
|
||||
"integrity": "sha512-przuZPajiurStGgxMoJP0EJeC4xj5CgHv+M7GfF3YxAdhGgEWAkhOSE0xympAFN20uMayntBZpttIZqqLl77fw==",
|
||||
"requires": {
|
||||
"pretty-format": "^3.5.1"
|
||||
}
|
||||
},
|
||||
"preact-router": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/preact-router/-/preact-router-3.0.0.tgz",
|
||||
"integrity": "sha512-v/dTwXa0TAeP2NTf4YFvT+TygejoSxN4Un9y90sNJiM/r6EY6wqBEoxmCdTTz5Yb101iP3Zuwr+4Wby7ZY1S+w=="
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/preact-router/-/preact-router-2.6.1.tgz",
|
||||
"integrity": "sha512-Ql3fptQ8hiioIw5zUcWUq5NShl7yFR4e6KBUzLbGI7+HKMIgBnH+aOITN5IrY1rbr2vhKXBdHdd9nLbbjcJTOQ=="
|
||||
},
|
||||
"preact-transition-group": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/preact-transition-group/-/preact-transition-group-1.1.1.tgz",
|
||||
"integrity": "sha1-8KSTJ+pRXs406ivoZMSn0p5dbhA="
|
||||
},
|
||||
"prelude-ls": {
|
||||
"version": "1.1.2",
|
||||
|
@ -7994,6 +8022,11 @@
|
|||
"utila": "~0.4"
|
||||
}
|
||||
},
|
||||
"pretty-format": {
|
||||
"version": "3.8.0",
|
||||
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-3.8.0.tgz",
|
||||
"integrity": "sha1-v77VbV6ad2ZF9LH/eqGjrE+jw4U="
|
||||
},
|
||||
"private": {
|
||||
"version": "0.1.8",
|
||||
"resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz",
|
||||
|
@ -8038,7 +8071,6 @@
|
|||
"version": "15.7.2",
|
||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz",
|
||||
"integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"loose-envify": "^1.4.0",
|
||||
"object-assign": "^4.1.1",
|
||||
|
@ -8193,11 +8225,19 @@
|
|||
"integrity": "sha1-DD0L6u2KAclm2Xh793goElKpeao=",
|
||||
"dev": true
|
||||
},
|
||||
"react-css-variables": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/react-css-variables/-/react-css-variables-2.0.1.tgz",
|
||||
"integrity": "sha1-Gyq5C961RWhBCMpmk5mIAuKedck=",
|
||||
"requires": {
|
||||
"lodash.omit": "^4.5.0",
|
||||
"lodash.pick": "^4.4.0"
|
||||
}
|
||||
},
|
||||
"react-is": {
|
||||
"version": "16.8.6",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz",
|
||||
"integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA=="
|
||||
},
|
||||
"read-pkg": {
|
||||
"version": "2.0.0",
|
||||
|
@ -9221,6 +9261,11 @@
|
|||
"integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==",
|
||||
"dev": true
|
||||
},
|
||||
"standalone-react-addons-pure-render-mixin": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/standalone-react-addons-pure-render-mixin/-/standalone-react-addons-pure-render-mixin-0.1.1.tgz",
|
||||
"integrity": "sha1-PHQJ9MecQN6axyxhbPZ5qZTzdVE="
|
||||
},
|
||||
"static-extend": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
|
||||
|
@ -10350,9 +10395,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"worker-farm": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.6.0.tgz",
|
||||
"integrity": "sha512-6w+3tHbM87WnSWnENBUvA2pxJPLhQUg5LKwUQHq3r+XPhIM+Gh2R5ycbwPCyuGbNg+lPgdcnQUhuC02kJCvffQ==",
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz",
|
||||
"integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"errno": "~0.1.7"
|
||||
|
|
16
package.json
|
@ -1,18 +1,21 @@
|
|||
{
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "pwa export --routes /about,/blog,/",
|
||||
"build": "pwa build",
|
||||
"start": "sirv build -s",
|
||||
"watch": "pwa watch"
|
||||
"watch": "pwa watch",
|
||||
"deploy": "npm run build && git-directory-deploy --directory build/"
|
||||
},
|
||||
"dependencies": {
|
||||
"deepmerge": "^3.2.0",
|
||||
"preact": "^10.0.0-beta.1",
|
||||
"preact-router": "^3.0.0",
|
||||
"preact": "^8.4.2",
|
||||
"preact-compat": "^3.18.5",
|
||||
"preact-router": "^2.6.1",
|
||||
"react-css-variables": "^2.0.1",
|
||||
"sirv-cli": "^0.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@pwa/cli": "latest",
|
||||
"@pwa/cli": "^0.4.2",
|
||||
"@pwa/plugin-offline": "latest",
|
||||
"@pwa/preset-preact": "latest",
|
||||
"eslint": "^5.16.0",
|
||||
|
@ -22,7 +25,8 @@
|
|||
"eslint-plugin-node": "^9.0.0",
|
||||
"eslint-plugin-promise": "^4.1.1",
|
||||
"eslint-plugin-react": "^7.13.0",
|
||||
"eslint-plugin-standard": "^4.0.0"
|
||||
"eslint-plugin-standard": "^4.0.0",
|
||||
"git-directory-deploy": "^1.5.1"
|
||||
},
|
||||
"browserslist": [
|
||||
">0.25%",
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
const path = require('path');
|
||||
|
||||
exports.routes = ['/operative', '/siren', '/beastmaster', '/bot-jock'];
|
||||
|
||||
exports.webpack = function (config, env) {
|
||||
let { production, webpack } = env;
|
||||
// let { production, webpack } = env;
|
||||
config.resolve.alias['@constants'] = path.resolve(__dirname, 'src/constants');
|
||||
config.resolve.alias['preact-compat'] = 'preact/compact';
|
||||
}
|
||||
// config.resolve.alias['preact-compat'] = 'preact/compact';
|
||||
};
|
||||
|
|
23
src/404.html
Normal file
|
@ -0,0 +1,23 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<title>Borderlands 3 skill calculator</title>
|
||||
|
||||
<script>
|
||||
sessionStorage.redirect = location.href;
|
||||
</script>
|
||||
|
||||
<meta http-equiv="refresh" content="0;URL='/'"></meta>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
|
||||
</html>
|
BIN
src/assets/backgrounds/background.jpg
Normal file
After Width: | Height: | Size: 118 KiB |
Before Width: | Height: | Size: 437 KiB |
Before Width: | Height: | Size: 201 KiB |
Before Width: | Height: | Size: 304 KiB |
Before Width: | Height: | Size: 243 KiB |
Before Width: | Height: | Size: 409 KiB |
Before Width: | Height: | Size: 466 KiB |
Before Width: | Height: | Size: 416 KiB |
Before Width: | Height: | Size: 406 KiB |
Before Width: | Height: | Size: 289 KiB |
Before Width: | Height: | Size: 421 KiB |
Before Width: | Height: | Size: 250 KiB |
Before Width: | Height: | Size: 381 KiB |
|
@ -1,26 +0,0 @@
|
|||
[
|
||||
{
|
||||
"title": "Instant Prototyping",
|
||||
"text": "Quickly scaffold new projects with your preferred view library and toolkit. Kick it off with a perfect Lighthouse score!"
|
||||
},
|
||||
{
|
||||
"title": "Feature Rich",
|
||||
"text": "Supports Babel, Bublé, Browserlist, TypeScript, PostCSS, ESLint, Prettier, and Service Workers out of the box!"
|
||||
},
|
||||
{
|
||||
"title": "Fully Extensible",
|
||||
"text": "Includes a plugin system that allows for easy, fine-grain control of your configuration... when needed."
|
||||
},
|
||||
{
|
||||
"title": "Plug 'n Play",
|
||||
"text": "Don't worry about configuration, unless you want to. Presets and plugins are automatically applied. Just install and go!"
|
||||
},
|
||||
{
|
||||
"title": "Framework Agnostic",
|
||||
"text": "Build with your preferred framework or with none at all! Official presets for Preact, React, Vue, and Svelte."
|
||||
},
|
||||
{
|
||||
"title": "Static Site Generator",
|
||||
"text": "Export your routes as \"pre-rendered\" HTML, which is great for SEO and works on any static hosting service."
|
||||
}
|
||||
]
|
Before Width: | Height: | Size: 14 KiB |
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg>
|
Before Width: | Height: | Size: 442 B |
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 13 12"><path fill="#ED412D" d="M6.5.1C3.4.1.8 2.8.8 6s2.6 5.9 5.7 5.9 5.7-2.7 5.7-5.9S9.7.1 6.5.1zm0 8.7C5 8.8 3.8 7.6 3.8 6S5 3.2 6.5 3.2 9.2 4.4 9.2 6 8 8.8 6.5 8.8z" /></svg>
|
Before Width: | Height: | Size: 231 B |
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12"><path fill="#FDBD00" d="M10.3 4.3H7.7V1.7C7.7.8 7 0 6 0S4.3.8 4.3 1.7v2.5H1.7C.8 4.3 0 5 0 6s.8 1.7 1.7 1.7h2.5v2.5C4.3 11.2 5 12 6 12s1.7-.8 1.7-1.7V7.7h2.5c1 0 1.8-.7 1.8-1.7s-.8-1.7-1.7-1.7z" class="cross"/></svg>
|
Before Width: | Height: | Size: 277 B |
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 561.8 559.4"><path fill="#3E82F7" d="M383.4 559.4h-204l-2.6-.2c-51.3-4.4-94-37-108.8-83l-.2-.6L6 276.7l-.2-.5a119.4 119.4 0 0 1 43.7-131.4L212.1 23A115.7 115.7 0 0 1 351 23l163.5 122.5.4.3c39 30.3 56 82.6 42.2 130.3l-.3 1.1-61.5 198a116.1 116.1 0 0 1-111.9 84.2zm-197.9-120h195.2l61.1-196.8c0-.5-.3-1.6-.7-2.1L281.5 120.9 120.9 241.2l.2 1.2 60.8 195.8c.6.3 1.8.9 3.6 1.2zM441 240.3z"/></svg>
|
Before Width: | Height: | Size: 445 B |
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12"><path fill="#8491A3" d="M6 7.5c-.9 0-1.5-.6-1.5-1.5S5.2 4.5 6 4.5c.9 0 1.5.7 1.5 1.5 0 .9-.6 1.5-1.5 1.5z"/></svg>
|
Before Width: | Height: | Size: 175 B |
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 13 14"><path fill="#2DA94F" stroke="#2DA94F" d="M5.9 1.2L.7 6.5c-.2.2-.2.5 0 .7l5.2 5.4c.2.2.5.2.7 0l5.2-5.4c.2-.2.2-.5 0-.7L6.6 1.2c-.2-.3-.5-.3-.7 0zM3.4 6.5L6 3.9c.2-.2.5-.2.7 0l2.6 2.6c.2.2.2.5 0 .7L6.6 9.9c-.2.2-.5.2-.7 0L3.4 7.3c-.2-.2-.2-.5 0-.8z" /></svg>
|
Before Width: | Height: | Size: 317 B |
Before Width: | Height: | Size: 247 KiB |
|
@ -1,4 +0,0 @@
|
|||
main {
|
||||
padding: 1rem 1rem 3rem;
|
||||
margin: auto;
|
||||
}
|
|
@ -1,25 +1,18 @@
|
|||
import { Router } from 'preact-router';
|
||||
|
||||
import Nav from '@components/Nav';
|
||||
import Footer from '@components/Footer';
|
||||
|
||||
import Home from '@pages/Home';
|
||||
import Operative from '@pages/Operative';
|
||||
import Siren from '@pages/Siren';
|
||||
|
||||
// import style from './index.css';
|
||||
import Beastmaster from '@pages/Beastmaster';
|
||||
import BotJock from '@pages/BotJock';
|
||||
|
||||
const App = () =>
|
||||
[
|
||||
<Nav />,
|
||||
<main>
|
||||
<Router>
|
||||
<Home path='/' />
|
||||
<Operative path='/operative' />
|
||||
<Siren path='/siren' />
|
||||
</Router>
|
||||
</main>,
|
||||
<Footer />
|
||||
];
|
||||
(<Router>
|
||||
<Home path='/' />
|
||||
<Operative path='/operative' />
|
||||
<Siren path='/siren' />
|
||||
<Beastmaster path='/beastmaster' />
|
||||
<BotJock path='/bot-jock' />
|
||||
</Router>);
|
||||
|
||||
export default App;
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
transition: color var(--transition-duration);
|
||||
}
|
||||
|
||||
.footer a:hover {
|
||||
.footer a:hover, .footer a:focus {
|
||||
color: #E2264D;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,13 +29,18 @@
|
|||
list-style: none;
|
||||
}
|
||||
|
||||
.nav a {
|
||||
display: inline-block;
|
||||
.link {
|
||||
color: inherit;
|
||||
background-color: hsla(0, 0%, 0%, 0.25);
|
||||
}
|
||||
|
||||
.link > a {
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.nav a:hover, .nav a:focus {
|
||||
.current, .link:hover, .link:focus {
|
||||
background-color: #FED600;
|
||||
color: black;
|
||||
}
|
||||
|
|
|
@ -1,15 +1,21 @@
|
|||
import { Link } from 'preact-router';
|
||||
import style from './index.css';
|
||||
|
||||
export default function Nav (props) {
|
||||
export default function Nav ({ path }) {
|
||||
const pages = [
|
||||
{ name: 'Zane', path: '/operative' },
|
||||
{ name: 'Amara', path: '/siren' },
|
||||
{ name: 'FL4K', path: '/beastmaster' },
|
||||
{ name: 'Moze', path: '/bot-jock' },
|
||||
];
|
||||
return (
|
||||
<nav class={style.nav}>
|
||||
<ul class={style.links}>
|
||||
<li><Link href='/'>Home</Link></li>
|
||||
<li><Link href='/operative'>Zane</Link></li>
|
||||
<li><Link href='/siren'>Amara</Link></li>
|
||||
<li><Link href='/beastmaster'>FL4K</Link></li>
|
||||
<li><Link href='/bot-jock'>Moze</Link></li>
|
||||
{ pages.map(page => {
|
||||
return (<li class={`${style.link} ${path === page.path ? style.current : ''}`}>
|
||||
<Link href={page.path}>{page.name}</Link>
|
||||
</li>);
|
||||
}) }
|
||||
</ul>
|
||||
</nav>
|
||||
);
|
||||
|
|
|
@ -121,20 +121,31 @@
|
|||
padding: 0.1em;
|
||||
}
|
||||
|
||||
.skillTitle {
|
||||
margin-bottom: 0.5rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.description {
|
||||
display: none;
|
||||
z-index: 10;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.effect {
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
|
||||
.skill:hover .description {
|
||||
pointer-events: none;
|
||||
font-size: 0.8em;
|
||||
background-color: hsla(0, 0%, 0%, 0.6);
|
||||
background-color: hsl(0, 0%, 10%);
|
||||
color: var(--whiteText);
|
||||
border: 0.15rem solid hsla(0,0%,0%,0.8);
|
||||
border: 0.15rem solid black;
|
||||
padding: 0.5rem;
|
||||
display: block;
|
||||
position: absolute;
|
||||
bottom: 110%;
|
||||
width: 20rem;
|
||||
transform: translateX(calc((var(--tree-index) - 1) * -50%));
|
||||
transform: translateX(calc((1 - var(--treeindex)) * 40%));
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ export default function Skill ({
|
|||
effect = rank => `Rank ${rank} effect`,
|
||||
type = null,
|
||||
enabled = true,
|
||||
onChange = (oldValue, newValue) => console.log(`Skill from ${oldValue} to ${newValue}`),
|
||||
onChange = (oldValue, newValue) => null,
|
||||
}) {
|
||||
const isAugment = [
|
||||
SKILLS.AUGMENT_CHEVRON,
|
||||
|
@ -60,7 +60,7 @@ export default function Skill ({
|
|||
<div class={style.image}>{getInitials(name)}</div>
|
||||
{ enabled && ranks > 0 && <div class={style.ranks}>{invested}/{ranks}</div>}
|
||||
<div class={style.description}>
|
||||
<h3>{name}</h3>
|
||||
<h3 class={style.skillTitle}>{name}</h3>
|
||||
{text}
|
||||
<div class={style.effect}>
|
||||
{effect(Math.max(invested, 1))}
|
||||
|
|
32
src/components/VaultHunter/hashHandler.js
Normal file
|
@ -0,0 +1,32 @@
|
|||
export function setHash (skillsState) {
|
||||
const hashparts = [];
|
||||
for (let tree of Object.values(skillsState)) {
|
||||
for (let tier of Object.values(tree)) {
|
||||
for (let skill of Object.values(tier)) {
|
||||
if (skill.type == null) {
|
||||
hashparts.push(skill.invested || 0);
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
const url = window.location.href.split('#')[0] + '#' + hashparts.join('');
|
||||
window.location.replace(url);
|
||||
};
|
||||
|
||||
export function getHash (skillsState) {
|
||||
const hash = window.location.href.split('#')[1] || '';
|
||||
const hashparts = hash.match(/./g) || [];
|
||||
const skills = JSON.parse(JSON.stringify(skillsState));
|
||||
for (let tree of Object.keys(skills)) {
|
||||
for (let tier of Object.keys(skills[tree])) {
|
||||
for (let skill of Object.keys(skills[tree][tier])) {
|
||||
if (skills[tree][tier][skill].type == null) {
|
||||
skills[tree][tier][skill] = { invested: parseInt(hashparts.shift() || 0) };
|
||||
} else {
|
||||
skills[tree][tier][skill] = {};
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
return skills;
|
||||
};
|
|
@ -19,7 +19,7 @@
|
|||
}
|
||||
.subtitle {
|
||||
text-transform: uppercase;
|
||||
font-size: 0.5em;
|
||||
font-size: 0.4em;
|
||||
}
|
||||
|
||||
.trees, .tier {
|
||||
|
@ -50,6 +50,7 @@
|
|||
.skills {
|
||||
position: relative;
|
||||
user-select: none;
|
||||
height: calc(3.5rem * 7)
|
||||
}
|
||||
|
||||
.skills:before {
|
||||
|
@ -84,3 +85,7 @@
|
|||
.red {
|
||||
--themeHue: 18;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
}
|
||||
|
|
|
@ -1,99 +1,91 @@
|
|||
import { useReducer } from 'preact/hooks';
|
||||
import deepmerge from 'deepmerge';
|
||||
// import { useReducer } from 'preact/hooks'; // Downgraded from Preact 10 for compat with @pwa/cli
|
||||
import { Component } from 'preact';
|
||||
import Skill from '@components/Skill';
|
||||
import investmentValidator from './investmentValidator';
|
||||
import Nav from '@components/Nav';
|
||||
import Footer from '@components/Footer';
|
||||
import { getHash } from './hashHandler';
|
||||
import reducer from './reducer';
|
||||
import style from './index.css';
|
||||
|
||||
function reducer (state, action) {
|
||||
switch (action.type) {
|
||||
case 'skillChange':
|
||||
var newInvested = state.invested.slice(0);
|
||||
newInvested[action.treeIndex] += action.newValue - action.oldValue;
|
||||
var newSkills = deepmerge(state.skills, {
|
||||
[action.treeName]: {
|
||||
[action.tierIndex + '']: {
|
||||
[action.skillName]: {
|
||||
invested: action.newValue,
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
if (investmentValidator(newSkills)) {
|
||||
return {
|
||||
...state,
|
||||
invested: newInvested,
|
||||
skills: newSkills,
|
||||
};
|
||||
} else {
|
||||
return state;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function contextKiller (event) {
|
||||
event.preventDefault();
|
||||
return false;
|
||||
}
|
||||
|
||||
export default function VaultHunter ({
|
||||
name = 'Unnamed',
|
||||
discipline = 'Classless',
|
||||
skills = {},
|
||||
}) {
|
||||
const initialState = {
|
||||
invested: [0, 0, 0],
|
||||
skills,
|
||||
};
|
||||
const [state, dispatch] = useReducer(reducer, initialState);
|
||||
const trees =
|
||||
Object.keys(state.skills).map((treeName, treeIndex) =>
|
||||
<div
|
||||
class={`${style.tree} ${[style.green, style.blue, style.red][treeIndex]}`}
|
||||
style={{
|
||||
'--invested': state.invested[treeIndex],
|
||||
'--tree-index': treeIndex,
|
||||
}}
|
||||
>
|
||||
<h2 class={style.treeName}>{ treeName }</h2>
|
||||
<div class={style.skills}>
|
||||
{ Object.keys(state.skills[treeName]).map((tier, tierIndex) =>
|
||||
<div class={style.tier}>
|
||||
{ Object.keys(state.skills[treeName][tier]).map(skillName =>
|
||||
<Skill
|
||||
{...state.skills[treeName][tier][skillName]}
|
||||
name={skillName}
|
||||
enabled={state.invested[treeIndex] >= 5 * tierIndex - 5}
|
||||
onChange={skillChangeListenerFactory(skillName, treeIndex, treeName, tierIndex)}
|
||||
/>
|
||||
) }
|
||||
</div>
|
||||
) }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
function skillChangeListenerFactory (skillName, treeIndex, treeName, tierIndex) {
|
||||
return (oldValue, newValue) => {
|
||||
dispatch({
|
||||
type: 'skillChange',
|
||||
skillName,
|
||||
treeIndex,
|
||||
treeName,
|
||||
tierIndex,
|
||||
newValue,
|
||||
oldValue,
|
||||
});
|
||||
export default class VaultHunter extends Component {
|
||||
constructor (props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
invested: [0, 0, 0],
|
||||
skills: props.skills || {},
|
||||
};
|
||||
}
|
||||
|
||||
return (
|
||||
<div class={style.VaultHunter} onContextMenu={contextKiller}>
|
||||
<h1 class={style.title}>{ name }
|
||||
<div class={style.subtitle}>the { discipline }</div>
|
||||
</h1>
|
||||
<div class={style.trees}>
|
||||
{ trees }
|
||||
componentDidMount () {
|
||||
this.setState(reducer(this.state, {
|
||||
type: 'loadSkills',
|
||||
skills: getHash(this.state.skills),
|
||||
}));
|
||||
}
|
||||
|
||||
render ({
|
||||
name = 'Unnamed',
|
||||
discipline = 'Classless',
|
||||
path
|
||||
}) {
|
||||
const skillChangeListenerFactory = (skillName, treeIndex, treeName, tierIndex) => {
|
||||
return (oldValue, newValue) => {
|
||||
this.setState(reducer(this.state, {
|
||||
type: 'skillChange',
|
||||
skillName,
|
||||
treeIndex,
|
||||
treeName,
|
||||
tierIndex,
|
||||
newValue,
|
||||
oldValue,
|
||||
}));
|
||||
};
|
||||
};
|
||||
|
||||
const trees =
|
||||
Object.keys(this.state.skills).map((treeName, treeIndex) => {
|
||||
return (
|
||||
<div class={`${style.tree} ${[style.green, style.blue, style.red][treeIndex]}`}>
|
||||
<style>{`.${style.tree}:nth-child(${treeIndex + 1}) { --invested: ${this.state.invested[treeIndex]}; --treeindex: ${treeIndex};}`}</style>
|
||||
<h2 class={style.treeName}>{ treeName }</h2>
|
||||
<div class={style.skills}>
|
||||
{ Object.keys(this.state.skills[treeName]).map((tier, tierIndex) =>
|
||||
<div class={style.tier}>
|
||||
{ Object.keys(this.state.skills[treeName][tier]).map(skillName =>
|
||||
<Skill
|
||||
{...this.state.skills[treeName][tier][skillName]}
|
||||
name={skillName}
|
||||
enabled={this.state.invested[treeIndex] >= 5 * tierIndex - 5}
|
||||
onChange={skillChangeListenerFactory(skillName, treeIndex, treeName, tierIndex)}
|
||||
/>
|
||||
) }
|
||||
</div>
|
||||
) }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Nav path={path} />
|
||||
<main>
|
||||
<div class={style.VaultHunter} onContextMenu={contextKiller}>
|
||||
<h1 class={style.title}>{ name }
|
||||
<div class={style.subtitle}>the { discipline }</div>
|
||||
</h1>
|
||||
<div class={style.trees}>
|
||||
{ trees }
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<Footer />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
export default function investmentValidator (skills) {
|
||||
// ok &= (
|
||||
// (level == thisLevel && total == 0 && treeTotal >= invested + total) ||
|
||||
// (level != thisLevel && total == 0) ||
|
||||
// (total > 0 && (level * 5 <= invested))
|
||||
// );
|
||||
console.log('----------------------');
|
||||
let totalSpent = 0;
|
||||
let treeTotals = [0, 0, 0];
|
||||
let treeIndex = 0;
|
||||
for (let tree of Object.values(skills)) {
|
||||
let treeTotal = 0;
|
||||
let tierIndex = 0;
|
||||
|
@ -15,13 +11,14 @@ export default function investmentValidator (skills) {
|
|||
if (skill.invested < 0 || skill.invested > skill.ranks) { return false; }
|
||||
tierTotal += skill.invested || 0;
|
||||
};
|
||||
// console.log(`${tierTotal} > 0 && ${treeTotal} + 5 < ${tierIndex} * 5 = ${!(tierTotal > 0 && treeTotal + 5 < tierIndex * 5)}`);
|
||||
if (tierTotal > 0 && treeTotal + 5 < tierIndex * 5) { return false; }
|
||||
treeTotal += tierTotal;
|
||||
tierIndex += 1;
|
||||
};
|
||||
treeTotals[treeIndex] = treeTotal;
|
||||
totalSpent += treeTotal;
|
||||
treeIndex += 1;
|
||||
};
|
||||
if (totalSpent > 47) { return false; }
|
||||
return true;
|
||||
if (totalSpent > 48) { return false; }
|
||||
return treeTotals;
|
||||
}
|
||||
|
|
40
src/components/VaultHunter/reducer.js
Normal file
|
@ -0,0 +1,40 @@
|
|||
import deepmerge from 'deepmerge';
|
||||
import investmentValidator from './investmentValidator';
|
||||
import { setHash } from './hashHandler';
|
||||
|
||||
export default function reducer (state, action) {
|
||||
switch (action.type) {
|
||||
case 'skillChange':
|
||||
var newSkills = deepmerge(state.skills, {
|
||||
[action.treeName]: {
|
||||
[action.tierIndex + '']: {
|
||||
[action.skillName]: {
|
||||
invested: action.newValue,
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
const skillChangeTotals = investmentValidator(newSkills);
|
||||
if (skillChangeTotals) {
|
||||
setHash(newSkills);
|
||||
return {
|
||||
...state,
|
||||
invested: skillChangeTotals,
|
||||
skills: newSkills,
|
||||
};
|
||||
} else {
|
||||
return state;
|
||||
}
|
||||
case 'loadSkills':
|
||||
const loadSkillsTotals = investmentValidator(action.skills);
|
||||
if (loadSkillsTotals) {
|
||||
return {
|
||||
...state,
|
||||
invested: loadSkillsTotals,
|
||||
skills: deepmerge(state.skills, action.skills),
|
||||
};
|
||||
} else {
|
||||
return state;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -27,29 +27,22 @@
|
|||
body {
|
||||
position: relative;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
color: #F8F8FA;
|
||||
font-family: var(--font-list);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
background-color: #333;
|
||||
background-image: url('@assets/backgrounds/background2.jpg');
|
||||
background-image: url('@assets/backgrounds/background.jpg');
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
a {
|
||||
color: rgb(0,100,200);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #E2264D;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
a:visited {
|
||||
color: inherit;
|
||||
body > * {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
|
3
src/pages/Beastmaster/index.css
Normal file
|
@ -0,0 +1,3 @@
|
|||
VaultHunter {
|
||||
opacity: 0.5;
|
||||
}
|
14
src/pages/Beastmaster/index.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
import VaultHunter from '@components/VaultHunter';
|
||||
|
||||
import skills from './skills.js';
|
||||
|
||||
export default function Beastmaster ({ path }) {
|
||||
return (
|
||||
<VaultHunter
|
||||
name='FL4K'
|
||||
discipline='Beastmaster'
|
||||
skills={skills}
|
||||
path={path}
|
||||
/>
|
||||
);
|
||||
}
|
34
src/pages/Beastmaster/skills.js
Normal file
|
@ -0,0 +1,34 @@
|
|||
import SKILLS from '@constants/skills';
|
||||
|
||||
const skills = {
|
||||
"Tree One": {
|
||||
"0": {
|
||||
"?": {
|
||||
text: "?",
|
||||
type: SKILLS.ACTION_SKILL,
|
||||
ranks: 0,
|
||||
effect: rank => `?`,
|
||||
},
|
||||
},
|
||||
},
|
||||
"Tree Two": {
|
||||
"0": {
|
||||
"?": {
|
||||
text: "?",
|
||||
type: SKILLS.ACTION_SKILL,
|
||||
effect: rank => `?`,
|
||||
},
|
||||
},
|
||||
},
|
||||
"Tree Three": {
|
||||
"0": {
|
||||
"?": {
|
||||
text: "?",
|
||||
type: SKILLS.ACTION_SKILL,
|
||||
effect: rank => `?`,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default skills;
|
3
src/pages/BotJock/index.css
Normal file
|
@ -0,0 +1,3 @@
|
|||
VaultHunter {
|
||||
opacity: 0.5;
|
||||
}
|
14
src/pages/BotJock/index.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
import VaultHunter from '@components/VaultHunter';
|
||||
|
||||
import skills from './skills.js';
|
||||
|
||||
export default function BotJock ({ path }) {
|
||||
return (
|
||||
<VaultHunter
|
||||
name='Moze'
|
||||
discipline='Bot Jock'
|
||||
skills={skills}
|
||||
path={path}
|
||||
/>
|
||||
);
|
||||
}
|
34
src/pages/BotJock/skills.js
Normal file
|
@ -0,0 +1,34 @@
|
|||
import SKILLS from '@constants/skills';
|
||||
|
||||
const skills = {
|
||||
"Tree One": {
|
||||
"0": {
|
||||
"?": {
|
||||
text: "?",
|
||||
type: SKILLS.ACTION_SKILL,
|
||||
ranks: 0,
|
||||
effect: rank => `?`,
|
||||
},
|
||||
},
|
||||
},
|
||||
"Tree Two": {
|
||||
"0": {
|
||||
"?": {
|
||||
text: "?",
|
||||
type: SKILLS.ACTION_SKILL,
|
||||
effect: rank => `?`,
|
||||
},
|
||||
},
|
||||
},
|
||||
"Tree Three": {
|
||||
"0": {
|
||||
"?": {
|
||||
text: "?",
|
||||
type: SKILLS.ACTION_SKILL,
|
||||
effect: rank => `?`,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default skills;
|
|
@ -0,0 +1,34 @@
|
|||
.splash {
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
text-align: center;
|
||||
padding: 1rem;
|
||||
background-color: hsla(0, 0%, 0%, 0.5);
|
||||
}
|
||||
|
||||
.link {
|
||||
display: inline-block;
|
||||
margin: 0.5rem;
|
||||
background-color: black;
|
||||
color: hsl(51, 100%, 50%);
|
||||
padding: 0.25em;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
font-size: 3rem;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.link:hover, .link:focus {
|
||||
color: black;
|
||||
background-color: hsl(51, 100%, 50%);
|
||||
}
|
||||
|
||||
.name, .job {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.job {
|
||||
font-size: 0.4em;
|
||||
}
|
|
@ -1,9 +1,34 @@
|
|||
// import style from './index.css';
|
||||
import { Link } from 'preact-router';
|
||||
import Footer from '@components/Footer';
|
||||
import style from './index.css';
|
||||
|
||||
export default function () {
|
||||
const pages = [
|
||||
{ name: 'Zane', job: 'the Operative', path: '/operative' },
|
||||
{ name: 'Amara', job: 'the Siren', path: '/siren' },
|
||||
{ name: 'FL4K', job: 'the Beastmaster', path: '/beastmaster' },
|
||||
{ name: 'Moze', job: 'the Bot Jock', path: '/bot-jock' },
|
||||
];
|
||||
return (
|
||||
<div>
|
||||
Home
|
||||
<div class={style.splash}>
|
||||
<div class={style.wrapper}>
|
||||
<h1>Borderlands 3 skill calculator</h1>
|
||||
{ pages.map(page => {
|
||||
return (
|
||||
<Link class={style.link} href={page.path}>
|
||||
<div class={style.name}>
|
||||
{page.name}
|
||||
<div class={style.job}>
|
||||
{page.job}
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
);
|
||||
}) }
|
||||
</div>
|
||||
</div>
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -2,12 +2,13 @@ import VaultHunter from '@components/VaultHunter';
|
|||
|
||||
import skills from './skills.js';
|
||||
|
||||
export default function Operative () {
|
||||
export default function Operative ({ path }) {
|
||||
return (
|
||||
<VaultHunter
|
||||
name='Zane'
|
||||
discipline='Operative'
|
||||
skills={skills}
|
||||
path={path}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -2,12 +2,13 @@ import VaultHunter from '@components/VaultHunter';
|
|||
|
||||
import skills from './skills.js';
|
||||
|
||||
export default function Siren () {
|
||||
export default function Siren ({ path }) {
|
||||
return (
|
||||
<VaultHunter
|
||||
name='Amara'
|
||||
discipline='Siren'
|
||||
skills={skills}
|
||||
path={path}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|