diff --git a/.eslintignore b/.eslintignore index f0da1ec30..7cb0ed0e8 100644 --- a/.eslintignore +++ b/.eslintignore @@ -2,3 +2,7 @@ node_modules/ doc/build/ dist/ tests/*.bundle.* +src/ThirdParty/* +src/ScriptEditor/CodeMirrorNetscriptMode.js +src/ScriptEditor/CodeMirrorNetscriptLint.js +src/JSInterpreter.js \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js index 507680fb0..2812ebcbf 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -76,7 +76,7 @@ module.exports = { "imports": "always-multiline", "exports": "always-multiline", "functions": "always-multiline", - } + }, ], "comma-spacing": [ "off", @@ -102,14 +102,14 @@ module.exports = { "error", ], "curly": [ - "off" + "off", ], "default-case": [ - "off" + "off", ], "dot-location": [ "error", - "property" + "property", ], "dot-notation": [ "off", @@ -310,104 +310,104 @@ module.exports = { "error", ], "no-div-regex": [ - "error" + "error", ], "no-dupe-args": [ - "error" + "error", ], "no-dupe-class-members": [ - "error" + "error", ], "no-dupe-keys": [ - "error" + "error", ], "no-duplicate-case": [ - "error" + "error", ], "no-duplicate-imports": [ "error", { - "includeExports": true - } + "includeExports": true, + }, ], "no-else-return": [ - "off" + "off", ], "no-empty": [ "off", { - "allowEmptyCatch": false - } + "allowEmptyCatch": false, + }, ], "no-empty-character-class": [ - "error" + "error", ], "no-empty-function": [ - "off" + "off", ], "no-empty-pattern": [ - "error" + "error", ], "no-eq-null": [ - "off" + "off", ], "no-ex-assign": [ - "off" + "off", ], "no-extra-boolean-cast": [ - "error" + "error", ], "no-extra-parens": [ - "off" + "off", ], "no-extra-semi": [ - "off" + "off", ], "no-eval": [ - "off" + "off", ], "no-extend-native": [ - "off" + "off", ], "no-extra-bind": [ - "error" + "error", ], "no-extra-label": [ - "error" + "error", ], "no-fallthrough": [ - "off" + "off", ], "no-floating-decimal": [ - "off" + "off", ], "no-func-assign": [ - "error" + "error", ], "no-global-assign": [ - "error" + "error", ], "no-implicit-coercion": [ - "off" + "off", ], "no-implicit-globals": [ - "error" + "error", ], "no-implied-eval": [ - "error" + "error", ], "no-inline-comments": [ - "off" + "off", ], "no-inner-declarations": [ "off", - "both" + "both", ], "no-invalid-regexp": [ - "error" + "error", ], "no-invalid-this": [ - "off" + "off", ], "no-irregular-whitespace": [ "error", @@ -415,451 +415,461 @@ module.exports = { "skipStrings": false, "skipComments": false, "skipRegExps": false, - "skipTemplates": false - } + "skipTemplates": false, + }, ], "no-iterator": [ - "error" + "error", ], "no-label-var": [ - "error" + "error", ], "no-labels": [ - "off" + "off", ], "no-lone-blocks": [ - "error" + "error", ], "no-lonely-if": [ - "off" + "off", ], "no-loop-func": [ - "off" + "off", ], "no-magic-numbers": [ - "off" + "off", ], "no-mixed-operators": [ - "off" + "off", ], "no-mixed-requires": [ - "error" + "error", ], "no-mixed-spaces-and-tabs": [ - "off" + "off", ], "no-multi-assign": [ - "off" + "off", ], "no-multi-spaces": [ - "off" + "off", ], "no-multi-str": [ - "error" + "error", ], "no-multiple-empty-lines": [ "off", { - "max": 1 - } + "max": 1, + }, ], "no-native-reassign": [ - "error" + "error", ], "no-negated-condition": [ - "off" + "off", ], "no-negated-in-lhs": [ - "error" + "error", ], "no-nested-ternary": [ - "off" + "off", ], "no-new": [ - "error" + "error", ], "no-new-func": [ - "error" + "error", ], "no-new-object": [ - "error" + "error", ], "no-new-require": [ - "error" + "error", ], "no-new-symbol": [ - "error" + "error", ], "no-new-wrappers": [ - "error" + "error", ], "no-octal": [ - "error" + "error", ], "no-octal-escape": [ - "error" + "error", ], "no-obj-calls": [ - "error" + "error", ], "no-param-reassign": [ - "off" + "off", ], "no-path-concat": [ - "error" + "error", ], "no-plusplus": [ - "off" + "off", ], "no-process-env": [ - "off" + "off", ], "no-process-exit": [ - "error" + "error", ], "no-proto": [ - "error" + "error", ], "no-prototype-builtins": [ - "off" + "off", ], "no-redeclare": [ - "off" + "off", ], "no-regex-spaces": [ - "error" + "error", ], "no-restricted-globals": [ - "error" + "error", ], "no-restricted-imports": [ - "error" + "error", ], "no-restricted-modules": [ - "error" + "error", ], "no-restricted-properties": [ "off", { "object": "console", "property": "log", - "message": "'log' is too general, use an appropriate level when logging." - } + "message": "'log' is too general, use an appropriate level when logging.", + }, ], "no-restricted-syntax": [ - "error" + "error", ], "no-return-assign": [ - "off" + "off", ], "no-return-await": [ - "error" + "error", ], "no-script-url": [ - "error" + "error", ], "no-self-assign": [ "error", { - "props": false - } + "props": false, + }, ], "no-self-compare": [ - "error" + "error", ], "no-sequences": [ - "error" + "error", ], "no-shadow": [ - "off" + "off", ], "no-shadow-restricted-names": [ - "error" + "error", ], "no-spaced-func": [ - "off" + "off", ], "no-sparse-arrays": [ - "error" + "error", ], "no-sync": [ - "error" + "error", ], "no-tabs": [ - "off" + "off", ], "no-template-curly-in-string": [ - "error" + "error", ], "no-ternary": [ - "off" + "off", ], "no-this-before-super": [ - "off" + "off", ], "no-throw-literal": [ - "error" + "error", ], "no-trailing-spaces": [ - "off" + "off", ], "no-undef": [ - "off" + "off", ], "no-undef-init": [ - "error" + "error", ], "no-undefined": [ - "off" + "off", ], "no-underscore-dangle": [ - "off" + "off", ], "no-unexpected-multiline": [ - "error" + "error", ], "no-unmodified-loop-condition": [ - "error" + "error", ], "no-unneeded-ternary": [ - "off" + "off", ], "no-unreachable": [ - "off" + "off", ], "no-unsafe-finally": [ - "error" + "error", ], "no-unsafe-negation": [ - "error" + "error", ], "no-unused-expressions": [ - "off" + "off", ], "no-unused-labels": [ - "error" + "error", ], "no-unused-vars": [ - "off" + "off", ], "no-use-before-define": [ - "off" + "off", ], "no-useless-call": [ - "off" + "off", ], "no-useless-computed-key": [ - "error" + "error", ], "no-useless-concat": [ - "off" + "off", ], "no-useless-constructor": [ - "error" + "error", ], "no-useless-escape": [ - "off" + "off", ], "no-useless-rename": [ "error", { "ignoreDestructuring": false, "ignoreExport": false, - "ignoreImport": false - } + "ignoreImport": false, + }, ], "no-useless-return": [ - "off" + "off", ], "no-var": [ - "off" + "off", ], "no-void": [ - "off" + "off", ], "no-warning-comments": [ - "off" + "off", ], "no-whitespace-before-property": [ - "error" + "error", ], "no-with": [ - "error" + "error", ], "nonblock-statement-body-position": [ "off", - "below" + "below", ], "object-curly-newline": [ - "off" + "off", ], "object-curly-spacing": [ - "off" + "off", ], "object-property-newline": [ - "off" + "off", ], "object-shorthand": [ - "off" + "off", ], "one-var": [ - "off" + "off", ], "one-var-declaration-per-line": [ - "off" + "off", ], "operator-assignment": [ - "off" + "off", ], "operator-linebreak": [ "off", - "none" + "none", ], "padded-blocks": [ - "off" + "off", ], "padding-line-between-statements": [ - "error" + "error", ], "prefer-arrow-callback": [ - "off" + "off", ], "prefer-const": [ - "off" + "off", ], "prefer-destructuring": [ - "off" + "off", ], "prefer-numeric-literals": [ - "error" + "error", ], "prefer-promise-reject-errors": [ - "off" + "off", ], "prefer-reflect": [ - "off" + "off", ], "prefer-rest-params": [ - "off" + "off", ], "prefer-spread": [ - "off" + "off", ], "prefer-template": [ - "off" + "off", ], "quote-props": [ - "off" + "off", ], "quotes": [ - "off" + "off", ], "radix": [ "off", - "as-needed" + "as-needed", ], "require-await": [ - "off" + "off", ], "require-jsdoc": [ - "off" + "off", ], "require-yield": [ - "error" + "error", ], "rest-spread-spacing": [ "error", - "never" + "never", ], "semi": [ - "off" + "off", ], "semi-spacing": [ - "off" + "off", ], "semi-style": [ "error", - "last" + "last", ], "sort-imports": [ - "off" + "off", ], "sort-keys": [ - "off" + "off", ], "sort-vars": [ - "off" + "off", ], "space-before-blocks": [ - "off" + "off", ], "space-before-function-paren": [ - "off" + "off", ], "space-in-parens": [ - "off" + "off", ], "space-infix-ops": [ - "off" + "off", ], "space-unary-ops": [ - "off" + "off", ], "spaced-comment": [ - "off" + "off", ], "strict": [ - "off" + "off", ], "switch-colon-spacing": [ "error", { "after": true, - "before": false - } + "before": false, + }, ], "symbol-description": [ - "error" + "error", ], "template-curly-spacing": [ - "error" + "error", ], "template-tag-spacing": [ - "error" + "error", ], "unicode-bom": [ "error", - "never" + "never", ], "use-isnan": [ - "error" + "error", ], "valid-jsdoc": [ - "off" + "off", ], "valid-typeof": [ - "error" + "error", ], "vars-on-top": [ - "off" + "off", ], "wrap-iife": [ "error", - "any" + "any", ], "wrap-regex": [ - "off" + "off", ], "yield-star-spacing": [ "error", - "before" + "before", ], "yoda": [ "error", - "never" - ] + "never", + ], + "@typescript-eslint/explicit-module-boundary-types": "off", + "@typescript-eslint/explicit-function-return-type": "off", }, "overrides": [ + { + // enable the rule specifically for TypeScript files + "files": ["*.ts", "*.tsx"], + "rules": { + "@typescript-eslint/explicit-function-return-type": ["error"], + "@typescript-eslint/explicit-module-boundary-types": ["error"], + }, + }, { // TypeScript configuration "files": [ "**/*.ts", "**/*.tsx" ], @@ -888,7 +898,7 @@ module.exports = { "singleline": { "delimiter": "semi", "requireLast": false, - } + }, }], "@typescript-eslint/member-ordering": ["error", { "default": [ @@ -900,11 +910,11 @@ module.exports = { "instance-method", "abstract-method", "static-method", - ] + ], }], "@typescript-eslint/no-explicit-any": "off", "@typescript-eslint/no-use-before-define": "off", - } - } - ] + }, + }, + ], }; \ No newline at end of file diff --git a/css/casino.scss b/css/casino.scss index d4bc6be6f..c7cd6280a 100644 --- a/css/casino.scss +++ b/css/casino.scss @@ -1,24 +1,24 @@ .casino-card { - padding: 10px; - border: solid 1px #808080; - background-color: white; - display: inline-block; - border-radius: 10px; - font-size: 14pt; - text-align: center; - margin: 3px; - font-weight: bold; + padding: 10px; + border: solid 1px #808080; + background-color: white; + display: inline-block; + border-radius: 10px; + font-size: 14pt; + text-align: center; + margin: 3px; + font-weight: bold; } .casino-card .value { - font-size:15pt; - font-family: sans-serif; + font-size:15pt; + font-family: sans-serif; } .casino-card.red { - color: red; + color: red; } .casino-card.black { - color: black; -} \ No newline at end of file + color: black; +} diff --git a/css/characteroverview.scss b/css/characteroverview.scss index d23a8e587..ea48f9085 100644 --- a/css/characteroverview.scss +++ b/css/characteroverview.scss @@ -43,9 +43,9 @@ background-color: #444; } - .character-stat-cell { - text-align: right; - } +.character-stat-cell { + text-align: right; +} #character-hack-wrapper td, #character-agi-wrapper td { diff --git a/css/codemirror-overrides.scss b/css/codemirror-overrides.scss index 0c286d53a..193e0a3f1 100644 --- a/css/codemirror-overrides.scss +++ b/css/codemirror-overrides.scss @@ -6,7 +6,7 @@ #codemirror-form-wrapper { height: 80%; - margin: 10px 0px 0px 6px; + margin: 10px 0 0 6px; } .CodeMirror { @@ -22,11 +22,11 @@ * Highlight matches */ .cm-matchhighlight { - background-color: #8F908A; + background-color: #8f908a; } .CodeMirror-selection-highlight-scrollbar { - background-color: #8F908A; + background-color: #8f908a; } /** @@ -35,7 +35,7 @@ .cm-whitespace::before { position: absolute; pointer-events: none; - color: #404F7D; + color: #404f7d; } /** diff --git a/css/dev-menu.css b/css/dev-menu.css index 21a93e78b..10e7c058c 100644 --- a/css/dev-menu.css +++ b/css/dev-menu.css @@ -1,36 +1,36 @@ .add-exp-button { - margin-right: 0px; + margin-right: 0; } .remove-exp-button { - margin-left:0px; + margin-left:0; } .exp-input { - margin-right: 0px; - margin-left:0px; + margin-right: 0; + margin-left:0; - margin-top: 5px; - margin-bottom: 5px; + margin-top: 5px; + margin-bottom: 5px; - padding: 2px 5px; + padding: 2px 5px; } .text-center { - margin: auto; - text-align: center; - vertical-align: middle; + margin: auto; + text-align: center; + vertical-align: middle; } .touch-right { - margin-right: 0px; + margin-right: 0; } .touch-left { - margin-left: 0px; + margin-left: 0; } .touch-sides { - margin-left: 0px; - margin-right: 0px; -} \ No newline at end of file + margin-left: 0; + margin-right: 0; +} diff --git a/css/grid.min.css b/css/grid.min.css index d617299c5..c32112cbb 100644 --- a/css/grid.min.css +++ b/css/grid.min.css @@ -3,4 +3,4 @@ * Copyright 2011-2018 The Bootstrap Authors * Copyright 2011-2018 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - */@-ms-viewport{width:device-width}html{-webkit-box-sizing:border-box;box-sizing:border-box;-ms-overflow-style:scrollbar}*,*::before,*::after{-webkit-box-sizing:inherit;box-sizing:inherit}.container{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width: 576px){.container{max-width:540px}}@media (min-width: 768px){.container{max-width:720px}}@media (min-width: 992px){.container{max-width:960px}}@media (min-width: 1200px){.container{max-width:1140px}}.container-fluid{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*="col-"]{padding-right:0;padding-left:0}.col-1,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-10,.col-11,.col-12,.col,.col-auto,.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm,.col-sm-auto,.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12,.col-md,.col-md-auto,.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg,.col-lg-auto,.col-xl-1,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl,.col-xl-auto{position:relative;width:100%;min-height:1px;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-1{-webkit-box-flex:0;-ms-flex:0 0 8.3333333333%;flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-2{-webkit-box-flex:0;-ms-flex:0 0 16.6666666667%;flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-webkit-box-flex:0;-ms-flex:0 0 33.3333333333%;flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-5{-webkit-box-flex:0;-ms-flex:0 0 41.6666666667%;flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-webkit-box-flex:0;-ms-flex:0 0 58.3333333333%;flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-8{-webkit-box-flex:0;-ms-flex:0 0 66.6666666667%;flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-webkit-box-flex:0;-ms-flex:0 0 83.3333333333%;flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-11{-webkit-box-flex:0;-ms-flex:0 0 91.6666666667%;flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-last{-webkit-box-ordinal-group:14;-ms-flex-order:13;order:13}.order-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-9{-webkit-box-ordinal-group:10;-ms-flex-order:9;order:9}.order-10{-webkit-box-ordinal-group:11;-ms-flex-order:10;order:10}.order-11{-webkit-box-ordinal-group:12;-ms-flex-order:11;order:11}.order-12{-webkit-box-ordinal-group:13;-ms-flex-order:12;order:12}.offset-1{margin-left:8.3333333333%}.offset-2{margin-left:16.6666666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.3333333333%}.offset-5{margin-left:41.6666666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.3333333333%}.offset-8{margin-left:66.6666666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.3333333333%}.offset-11{margin-left:91.6666666667%}@media (min-width: 576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-sm-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-sm-1{-webkit-box-flex:0;-ms-flex:0 0 8.3333333333%;flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-sm-2{-webkit-box-flex:0;-ms-flex:0 0 16.6666666667%;flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-sm-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-webkit-box-flex:0;-ms-flex:0 0 33.3333333333%;flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-sm-5{-webkit-box-flex:0;-ms-flex:0 0 41.6666666667%;flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-sm-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-webkit-box-flex:0;-ms-flex:0 0 58.3333333333%;flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-sm-8{-webkit-box-flex:0;-ms-flex:0 0 66.6666666667%;flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-sm-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-webkit-box-flex:0;-ms-flex:0 0 83.3333333333%;flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-sm-11{-webkit-box-flex:0;-ms-flex:0 0 91.6666666667%;flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-sm-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-sm-last{-webkit-box-ordinal-group:14;-ms-flex-order:13;order:13}.order-sm-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-sm-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-sm-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-sm-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-sm-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-sm-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-sm-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-sm-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-sm-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-sm-9{-webkit-box-ordinal-group:10;-ms-flex-order:9;order:9}.order-sm-10{-webkit-box-ordinal-group:11;-ms-flex-order:10;order:10}.order-sm-11{-webkit-box-ordinal-group:12;-ms-flex-order:11;order:11}.order-sm-12{-webkit-box-ordinal-group:13;-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.3333333333%}.offset-sm-2{margin-left:16.6666666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.3333333333%}.offset-sm-5{margin-left:41.6666666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.3333333333%}.offset-sm-8{margin-left:66.6666666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.3333333333%}.offset-sm-11{margin-left:91.6666666667%}}@media (min-width: 768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-md-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-md-1{-webkit-box-flex:0;-ms-flex:0 0 8.3333333333%;flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-md-2{-webkit-box-flex:0;-ms-flex:0 0 16.6666666667%;flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-md-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-webkit-box-flex:0;-ms-flex:0 0 33.3333333333%;flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-md-5{-webkit-box-flex:0;-ms-flex:0 0 41.6666666667%;flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-md-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-webkit-box-flex:0;-ms-flex:0 0 58.3333333333%;flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-md-8{-webkit-box-flex:0;-ms-flex:0 0 66.6666666667%;flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-md-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-webkit-box-flex:0;-ms-flex:0 0 83.3333333333%;flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-md-11{-webkit-box-flex:0;-ms-flex:0 0 91.6666666667%;flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-md-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-md-last{-webkit-box-ordinal-group:14;-ms-flex-order:13;order:13}.order-md-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-md-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-md-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-md-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-md-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-md-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-md-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-md-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-md-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-md-9{-webkit-box-ordinal-group:10;-ms-flex-order:9;order:9}.order-md-10{-webkit-box-ordinal-group:11;-ms-flex-order:10;order:10}.order-md-11{-webkit-box-ordinal-group:12;-ms-flex-order:11;order:11}.order-md-12{-webkit-box-ordinal-group:13;-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.3333333333%}.offset-md-2{margin-left:16.6666666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.3333333333%}.offset-md-5{margin-left:41.6666666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.3333333333%}.offset-md-8{margin-left:66.6666666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.3333333333%}.offset-md-11{margin-left:91.6666666667%}}@media (min-width: 992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-lg-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-lg-1{-webkit-box-flex:0;-ms-flex:0 0 8.3333333333%;flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-lg-2{-webkit-box-flex:0;-ms-flex:0 0 16.6666666667%;flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-lg-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-webkit-box-flex:0;-ms-flex:0 0 33.3333333333%;flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-lg-5{-webkit-box-flex:0;-ms-flex:0 0 41.6666666667%;flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-lg-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-webkit-box-flex:0;-ms-flex:0 0 58.3333333333%;flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-lg-8{-webkit-box-flex:0;-ms-flex:0 0 66.6666666667%;flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-lg-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-webkit-box-flex:0;-ms-flex:0 0 83.3333333333%;flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-lg-11{-webkit-box-flex:0;-ms-flex:0 0 91.6666666667%;flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-lg-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-lg-last{-webkit-box-ordinal-group:14;-ms-flex-order:13;order:13}.order-lg-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-lg-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-lg-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-lg-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-lg-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-lg-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-lg-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-lg-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-lg-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-lg-9{-webkit-box-ordinal-group:10;-ms-flex-order:9;order:9}.order-lg-10{-webkit-box-ordinal-group:11;-ms-flex-order:10;order:10}.order-lg-11{-webkit-box-ordinal-group:12;-ms-flex-order:11;order:11}.order-lg-12{-webkit-box-ordinal-group:13;-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.3333333333%}.offset-lg-2{margin-left:16.6666666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.3333333333%}.offset-lg-5{margin-left:41.6666666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.3333333333%}.offset-lg-8{margin-left:66.6666666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.3333333333%}.offset-lg-11{margin-left:91.6666666667%}}@media (min-width: 1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-xl-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-xl-1{-webkit-box-flex:0;-ms-flex:0 0 8.3333333333%;flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-xl-2{-webkit-box-flex:0;-ms-flex:0 0 16.6666666667%;flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-xl-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-webkit-box-flex:0;-ms-flex:0 0 33.3333333333%;flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-xl-5{-webkit-box-flex:0;-ms-flex:0 0 41.6666666667%;flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-xl-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-webkit-box-flex:0;-ms-flex:0 0 58.3333333333%;flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-xl-8{-webkit-box-flex:0;-ms-flex:0 0 66.6666666667%;flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-xl-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-webkit-box-flex:0;-ms-flex:0 0 83.3333333333%;flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-xl-11{-webkit-box-flex:0;-ms-flex:0 0 91.6666666667%;flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-xl-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-xl-last{-webkit-box-ordinal-group:14;-ms-flex-order:13;order:13}.order-xl-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-xl-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-xl-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-xl-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-xl-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-xl-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-xl-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-xl-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-xl-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-xl-9{-webkit-box-ordinal-group:10;-ms-flex-order:9;order:9}.order-xl-10{-webkit-box-ordinal-group:11;-ms-flex-order:10;order:10}.order-xl-11{-webkit-box-ordinal-group:12;-ms-flex-order:11;order:11}.order-xl-12{-webkit-box-ordinal-group:13;-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.3333333333%}.offset-xl-2{margin-left:16.6666666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.3333333333%}.offset-xl-5{margin-left:41.6666666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.3333333333%}.offset-xl-8{margin-left:66.6666666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.3333333333%}.offset-xl-11{margin-left:91.6666666667%}}.d-none{display:none !important}.d-inline{display:inline !important}.d-inline-block{display:inline-block !important}.d-block{display:block !important}.d-table{display:table !important}.d-table-row{display:table-row !important}.d-table-cell{display:table-cell !important}.d-flex{display:-webkit-box !important;display:-ms-flexbox !important;display:flex !important}.d-inline-flex{display:-webkit-inline-box !important;display:-ms-inline-flexbox !important;display:inline-flex !important}@media (min-width: 576px){.d-sm-none{display:none !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-block{display:block !important}.d-sm-table{display:table !important}.d-sm-table-row{display:table-row !important}.d-sm-table-cell{display:table-cell !important}.d-sm-flex{display:-webkit-box !important;display:-ms-flexbox !important;display:flex !important}.d-sm-inline-flex{display:-webkit-inline-box !important;display:-ms-inline-flexbox !important;display:inline-flex !important}}@media (min-width: 768px){.d-md-none{display:none !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-block{display:block !important}.d-md-table{display:table !important}.d-md-table-row{display:table-row !important}.d-md-table-cell{display:table-cell !important}.d-md-flex{display:-webkit-box !important;display:-ms-flexbox !important;display:flex !important}.d-md-inline-flex{display:-webkit-inline-box !important;display:-ms-inline-flexbox !important;display:inline-flex !important}}@media (min-width: 992px){.d-lg-none{display:none !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-block{display:block !important}.d-lg-table{display:table !important}.d-lg-table-row{display:table-row !important}.d-lg-table-cell{display:table-cell !important}.d-lg-flex{display:-webkit-box !important;display:-ms-flexbox !important;display:flex !important}.d-lg-inline-flex{display:-webkit-inline-box !important;display:-ms-inline-flexbox !important;display:inline-flex !important}}@media (min-width: 1200px){.d-xl-none{display:none !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-block{display:block !important}.d-xl-table{display:table !important}.d-xl-table-row{display:table-row !important}.d-xl-table-cell{display:table-cell !important}.d-xl-flex{display:-webkit-box !important;display:-ms-flexbox !important;display:flex !important}.d-xl-inline-flex{display:-webkit-inline-box !important;display:-ms-inline-flexbox !important;display:inline-flex !important}}@media print{.d-print-none{display:none !important}.d-print-inline{display:inline !important}.d-print-inline-block{display:inline-block !important}.d-print-block{display:block !important}.d-print-table{display:table !important}.d-print-table-row{display:table-row !important}.d-print-table-cell{display:table-cell !important}.d-print-flex{display:-webkit-box !important;display:-ms-flexbox !important;display:flex !important}.d-print-inline-flex{display:-webkit-inline-box !important;display:-ms-inline-flexbox !important;display:inline-flex !important}}.flex-row{-webkit-box-orient:horizontal !important;-webkit-box-direction:normal !important;-ms-flex-direction:row !important;flex-direction:row !important}.flex-column{-webkit-box-orient:vertical !important;-webkit-box-direction:normal !important;-ms-flex-direction:column !important;flex-direction:column !important}.flex-row-reverse{-webkit-box-orient:horizontal !important;-webkit-box-direction:reverse !important;-ms-flex-direction:row-reverse !important;flex-direction:row-reverse !important}.flex-column-reverse{-webkit-box-orient:vertical !important;-webkit-box-direction:reverse !important;-ms-flex-direction:column-reverse !important;flex-direction:column-reverse !important}.flex-wrap{-ms-flex-wrap:wrap !important;flex-wrap:wrap !important}.flex-nowrap{-ms-flex-wrap:nowrap !important;flex-wrap:nowrap !important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse !important;flex-wrap:wrap-reverse !important}.flex-fill{-webkit-box-flex:1 !important;-ms-flex:1 1 auto !important;flex:1 1 auto !important}.flex-grow-0{-webkit-box-flex:0 !important;-ms-flex-positive:0 !important;flex-grow:0 !important}.flex-grow-1{-webkit-box-flex:1 !important;-ms-flex-positive:1 !important;flex-grow:1 !important}.flex-shrink-0{-ms-flex-negative:0 !important;flex-shrink:0 !important}.flex-shrink-1{-ms-flex-negative:1 !important;flex-shrink:1 !important}.justify-content-start{-webkit-box-pack:start !important;-ms-flex-pack:start !important;justify-content:flex-start !important}.justify-content-end{-webkit-box-pack:end !important;-ms-flex-pack:end !important;justify-content:flex-end !important}.justify-content-center{-webkit-box-pack:center !important;-ms-flex-pack:center !important;justify-content:center !important}.justify-content-between{-webkit-box-pack:justify !important;-ms-flex-pack:justify !important;justify-content:space-between !important}.justify-content-around{-ms-flex-pack:distribute !important;justify-content:space-around !important}.align-items-start{-webkit-box-align:start !important;-ms-flex-align:start !important;align-items:flex-start !important}.align-items-end{-webkit-box-align:end !important;-ms-flex-align:end !important;align-items:flex-end !important}.align-items-center{-webkit-box-align:center !important;-ms-flex-align:center !important;align-items:center !important}.align-items-baseline{-webkit-box-align:baseline !important;-ms-flex-align:baseline !important;align-items:baseline !important}.align-items-stretch{-webkit-box-align:stretch !important;-ms-flex-align:stretch !important;align-items:stretch !important}.align-content-start{-ms-flex-line-pack:start !important;align-content:flex-start !important}.align-content-end{-ms-flex-line-pack:end !important;align-content:flex-end !important}.align-content-center{-ms-flex-line-pack:center !important;align-content:center !important}.align-content-between{-ms-flex-line-pack:justify !important;align-content:space-between !important}.align-content-around{-ms-flex-line-pack:distribute !important;align-content:space-around !important}.align-content-stretch{-ms-flex-line-pack:stretch !important;align-content:stretch !important}.align-self-auto{-ms-flex-item-align:auto !important;align-self:auto !important}.align-self-start{-ms-flex-item-align:start !important;align-self:flex-start !important}.align-self-end{-ms-flex-item-align:end !important;align-self:flex-end !important}.align-self-center{-ms-flex-item-align:center !important;align-self:center !important}.align-self-baseline{-ms-flex-item-align:baseline !important;align-self:baseline !important}.align-self-stretch{-ms-flex-item-align:stretch !important;align-self:stretch !important}@media (min-width: 576px){.flex-sm-row{-webkit-box-orient:horizontal !important;-webkit-box-direction:normal !important;-ms-flex-direction:row !important;flex-direction:row !important}.flex-sm-column{-webkit-box-orient:vertical !important;-webkit-box-direction:normal !important;-ms-flex-direction:column !important;flex-direction:column !important}.flex-sm-row-reverse{-webkit-box-orient:horizontal !important;-webkit-box-direction:reverse !important;-ms-flex-direction:row-reverse !important;flex-direction:row-reverse !important}.flex-sm-column-reverse{-webkit-box-orient:vertical !important;-webkit-box-direction:reverse !important;-ms-flex-direction:column-reverse !important;flex-direction:column-reverse !important}.flex-sm-wrap{-ms-flex-wrap:wrap !important;flex-wrap:wrap !important}.flex-sm-nowrap{-ms-flex-wrap:nowrap !important;flex-wrap:nowrap !important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse !important;flex-wrap:wrap-reverse !important}.flex-sm-fill{-webkit-box-flex:1 !important;-ms-flex:1 1 auto !important;flex:1 1 auto !important}.flex-sm-grow-0{-webkit-box-flex:0 !important;-ms-flex-positive:0 !important;flex-grow:0 !important}.flex-sm-grow-1{-webkit-box-flex:1 !important;-ms-flex-positive:1 !important;flex-grow:1 !important}.flex-sm-shrink-0{-ms-flex-negative:0 !important;flex-shrink:0 !important}.flex-sm-shrink-1{-ms-flex-negative:1 !important;flex-shrink:1 !important}.justify-content-sm-start{-webkit-box-pack:start !important;-ms-flex-pack:start !important;justify-content:flex-start !important}.justify-content-sm-end{-webkit-box-pack:end !important;-ms-flex-pack:end !important;justify-content:flex-end !important}.justify-content-sm-center{-webkit-box-pack:center !important;-ms-flex-pack:center !important;justify-content:center !important}.justify-content-sm-between{-webkit-box-pack:justify !important;-ms-flex-pack:justify !important;justify-content:space-between !important}.justify-content-sm-around{-ms-flex-pack:distribute !important;justify-content:space-around !important}.align-items-sm-start{-webkit-box-align:start !important;-ms-flex-align:start !important;align-items:flex-start !important}.align-items-sm-end{-webkit-box-align:end !important;-ms-flex-align:end !important;align-items:flex-end !important}.align-items-sm-center{-webkit-box-align:center !important;-ms-flex-align:center !important;align-items:center !important}.align-items-sm-baseline{-webkit-box-align:baseline !important;-ms-flex-align:baseline !important;align-items:baseline !important}.align-items-sm-stretch{-webkit-box-align:stretch !important;-ms-flex-align:stretch !important;align-items:stretch !important}.align-content-sm-start{-ms-flex-line-pack:start !important;align-content:flex-start !important}.align-content-sm-end{-ms-flex-line-pack:end !important;align-content:flex-end !important}.align-content-sm-center{-ms-flex-line-pack:center !important;align-content:center !important}.align-content-sm-between{-ms-flex-line-pack:justify !important;align-content:space-between !important}.align-content-sm-around{-ms-flex-line-pack:distribute !important;align-content:space-around !important}.align-content-sm-stretch{-ms-flex-line-pack:stretch !important;align-content:stretch !important}.align-self-sm-auto{-ms-flex-item-align:auto !important;align-self:auto !important}.align-self-sm-start{-ms-flex-item-align:start !important;align-self:flex-start !important}.align-self-sm-end{-ms-flex-item-align:end !important;align-self:flex-end !important}.align-self-sm-center{-ms-flex-item-align:center !important;align-self:center !important}.align-self-sm-baseline{-ms-flex-item-align:baseline !important;align-self:baseline !important}.align-self-sm-stretch{-ms-flex-item-align:stretch !important;align-self:stretch !important}}@media (min-width: 768px){.flex-md-row{-webkit-box-orient:horizontal !important;-webkit-box-direction:normal !important;-ms-flex-direction:row !important;flex-direction:row !important}.flex-md-column{-webkit-box-orient:vertical !important;-webkit-box-direction:normal !important;-ms-flex-direction:column !important;flex-direction:column !important}.flex-md-row-reverse{-webkit-box-orient:horizontal !important;-webkit-box-direction:reverse !important;-ms-flex-direction:row-reverse !important;flex-direction:row-reverse !important}.flex-md-column-reverse{-webkit-box-orient:vertical !important;-webkit-box-direction:reverse !important;-ms-flex-direction:column-reverse !important;flex-direction:column-reverse !important}.flex-md-wrap{-ms-flex-wrap:wrap !important;flex-wrap:wrap !important}.flex-md-nowrap{-ms-flex-wrap:nowrap !important;flex-wrap:nowrap !important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse !important;flex-wrap:wrap-reverse !important}.flex-md-fill{-webkit-box-flex:1 !important;-ms-flex:1 1 auto !important;flex:1 1 auto !important}.flex-md-grow-0{-webkit-box-flex:0 !important;-ms-flex-positive:0 !important;flex-grow:0 !important}.flex-md-grow-1{-webkit-box-flex:1 !important;-ms-flex-positive:1 !important;flex-grow:1 !important}.flex-md-shrink-0{-ms-flex-negative:0 !important;flex-shrink:0 !important}.flex-md-shrink-1{-ms-flex-negative:1 !important;flex-shrink:1 !important}.justify-content-md-start{-webkit-box-pack:start !important;-ms-flex-pack:start !important;justify-content:flex-start !important}.justify-content-md-end{-webkit-box-pack:end !important;-ms-flex-pack:end !important;justify-content:flex-end !important}.justify-content-md-center{-webkit-box-pack:center !important;-ms-flex-pack:center !important;justify-content:center !important}.justify-content-md-between{-webkit-box-pack:justify !important;-ms-flex-pack:justify !important;justify-content:space-between !important}.justify-content-md-around{-ms-flex-pack:distribute !important;justify-content:space-around !important}.align-items-md-start{-webkit-box-align:start !important;-ms-flex-align:start !important;align-items:flex-start !important}.align-items-md-end{-webkit-box-align:end !important;-ms-flex-align:end !important;align-items:flex-end !important}.align-items-md-center{-webkit-box-align:center !important;-ms-flex-align:center !important;align-items:center !important}.align-items-md-baseline{-webkit-box-align:baseline !important;-ms-flex-align:baseline !important;align-items:baseline !important}.align-items-md-stretch{-webkit-box-align:stretch !important;-ms-flex-align:stretch !important;align-items:stretch !important}.align-content-md-start{-ms-flex-line-pack:start !important;align-content:flex-start !important}.align-content-md-end{-ms-flex-line-pack:end !important;align-content:flex-end !important}.align-content-md-center{-ms-flex-line-pack:center !important;align-content:center !important}.align-content-md-between{-ms-flex-line-pack:justify !important;align-content:space-between !important}.align-content-md-around{-ms-flex-line-pack:distribute !important;align-content:space-around !important}.align-content-md-stretch{-ms-flex-line-pack:stretch !important;align-content:stretch !important}.align-self-md-auto{-ms-flex-item-align:auto !important;align-self:auto !important}.align-self-md-start{-ms-flex-item-align:start !important;align-self:flex-start !important}.align-self-md-end{-ms-flex-item-align:end !important;align-self:flex-end !important}.align-self-md-center{-ms-flex-item-align:center !important;align-self:center !important}.align-self-md-baseline{-ms-flex-item-align:baseline !important;align-self:baseline !important}.align-self-md-stretch{-ms-flex-item-align:stretch !important;align-self:stretch !important}}@media (min-width: 992px){.flex-lg-row{-webkit-box-orient:horizontal !important;-webkit-box-direction:normal !important;-ms-flex-direction:row !important;flex-direction:row !important}.flex-lg-column{-webkit-box-orient:vertical !important;-webkit-box-direction:normal !important;-ms-flex-direction:column !important;flex-direction:column !important}.flex-lg-row-reverse{-webkit-box-orient:horizontal !important;-webkit-box-direction:reverse !important;-ms-flex-direction:row-reverse !important;flex-direction:row-reverse !important}.flex-lg-column-reverse{-webkit-box-orient:vertical !important;-webkit-box-direction:reverse !important;-ms-flex-direction:column-reverse !important;flex-direction:column-reverse !important}.flex-lg-wrap{-ms-flex-wrap:wrap !important;flex-wrap:wrap !important}.flex-lg-nowrap{-ms-flex-wrap:nowrap !important;flex-wrap:nowrap !important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse !important;flex-wrap:wrap-reverse !important}.flex-lg-fill{-webkit-box-flex:1 !important;-ms-flex:1 1 auto !important;flex:1 1 auto !important}.flex-lg-grow-0{-webkit-box-flex:0 !important;-ms-flex-positive:0 !important;flex-grow:0 !important}.flex-lg-grow-1{-webkit-box-flex:1 !important;-ms-flex-positive:1 !important;flex-grow:1 !important}.flex-lg-shrink-0{-ms-flex-negative:0 !important;flex-shrink:0 !important}.flex-lg-shrink-1{-ms-flex-negative:1 !important;flex-shrink:1 !important}.justify-content-lg-start{-webkit-box-pack:start !important;-ms-flex-pack:start !important;justify-content:flex-start !important}.justify-content-lg-end{-webkit-box-pack:end !important;-ms-flex-pack:end !important;justify-content:flex-end !important}.justify-content-lg-center{-webkit-box-pack:center !important;-ms-flex-pack:center !important;justify-content:center !important}.justify-content-lg-between{-webkit-box-pack:justify !important;-ms-flex-pack:justify !important;justify-content:space-between !important}.justify-content-lg-around{-ms-flex-pack:distribute !important;justify-content:space-around !important}.align-items-lg-start{-webkit-box-align:start !important;-ms-flex-align:start !important;align-items:flex-start !important}.align-items-lg-end{-webkit-box-align:end !important;-ms-flex-align:end !important;align-items:flex-end !important}.align-items-lg-center{-webkit-box-align:center !important;-ms-flex-align:center !important;align-items:center !important}.align-items-lg-baseline{-webkit-box-align:baseline !important;-ms-flex-align:baseline !important;align-items:baseline !important}.align-items-lg-stretch{-webkit-box-align:stretch !important;-ms-flex-align:stretch !important;align-items:stretch !important}.align-content-lg-start{-ms-flex-line-pack:start !important;align-content:flex-start !important}.align-content-lg-end{-ms-flex-line-pack:end !important;align-content:flex-end !important}.align-content-lg-center{-ms-flex-line-pack:center !important;align-content:center !important}.align-content-lg-between{-ms-flex-line-pack:justify !important;align-content:space-between !important}.align-content-lg-around{-ms-flex-line-pack:distribute !important;align-content:space-around !important}.align-content-lg-stretch{-ms-flex-line-pack:stretch !important;align-content:stretch !important}.align-self-lg-auto{-ms-flex-item-align:auto !important;align-self:auto !important}.align-self-lg-start{-ms-flex-item-align:start !important;align-self:flex-start !important}.align-self-lg-end{-ms-flex-item-align:end !important;align-self:flex-end !important}.align-self-lg-center{-ms-flex-item-align:center !important;align-self:center !important}.align-self-lg-baseline{-ms-flex-item-align:baseline !important;align-self:baseline !important}.align-self-lg-stretch{-ms-flex-item-align:stretch !important;align-self:stretch !important}}@media (min-width: 1200px){.flex-xl-row{-webkit-box-orient:horizontal !important;-webkit-box-direction:normal !important;-ms-flex-direction:row !important;flex-direction:row !important}.flex-xl-column{-webkit-box-orient:vertical !important;-webkit-box-direction:normal !important;-ms-flex-direction:column !important;flex-direction:column !important}.flex-xl-row-reverse{-webkit-box-orient:horizontal !important;-webkit-box-direction:reverse !important;-ms-flex-direction:row-reverse !important;flex-direction:row-reverse !important}.flex-xl-column-reverse{-webkit-box-orient:vertical !important;-webkit-box-direction:reverse !important;-ms-flex-direction:column-reverse !important;flex-direction:column-reverse !important}.flex-xl-wrap{-ms-flex-wrap:wrap !important;flex-wrap:wrap !important}.flex-xl-nowrap{-ms-flex-wrap:nowrap !important;flex-wrap:nowrap !important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse !important;flex-wrap:wrap-reverse !important}.flex-xl-fill{-webkit-box-flex:1 !important;-ms-flex:1 1 auto !important;flex:1 1 auto !important}.flex-xl-grow-0{-webkit-box-flex:0 !important;-ms-flex-positive:0 !important;flex-grow:0 !important}.flex-xl-grow-1{-webkit-box-flex:1 !important;-ms-flex-positive:1 !important;flex-grow:1 !important}.flex-xl-shrink-0{-ms-flex-negative:0 !important;flex-shrink:0 !important}.flex-xl-shrink-1{-ms-flex-negative:1 !important;flex-shrink:1 !important}.justify-content-xl-start{-webkit-box-pack:start !important;-ms-flex-pack:start !important;justify-content:flex-start !important}.justify-content-xl-end{-webkit-box-pack:end !important;-ms-flex-pack:end !important;justify-content:flex-end !important}.justify-content-xl-center{-webkit-box-pack:center !important;-ms-flex-pack:center !important;justify-content:center !important}.justify-content-xl-between{-webkit-box-pack:justify !important;-ms-flex-pack:justify !important;justify-content:space-between !important}.justify-content-xl-around{-ms-flex-pack:distribute !important;justify-content:space-around !important}.align-items-xl-start{-webkit-box-align:start !important;-ms-flex-align:start !important;align-items:flex-start !important}.align-items-xl-end{-webkit-box-align:end !important;-ms-flex-align:end !important;align-items:flex-end !important}.align-items-xl-center{-webkit-box-align:center !important;-ms-flex-align:center !important;align-items:center !important}.align-items-xl-baseline{-webkit-box-align:baseline !important;-ms-flex-align:baseline !important;align-items:baseline !important}.align-items-xl-stretch{-webkit-box-align:stretch !important;-ms-flex-align:stretch !important;align-items:stretch !important}.align-content-xl-start{-ms-flex-line-pack:start !important;align-content:flex-start !important}.align-content-xl-end{-ms-flex-line-pack:end !important;align-content:flex-end !important}.align-content-xl-center{-ms-flex-line-pack:center !important;align-content:center !important}.align-content-xl-between{-ms-flex-line-pack:justify !important;align-content:space-between !important}.align-content-xl-around{-ms-flex-line-pack:distribute !important;align-content:space-around !important}.align-content-xl-stretch{-ms-flex-line-pack:stretch !important;align-content:stretch !important}.align-self-xl-auto{-ms-flex-item-align:auto !important;align-self:auto !important}.align-self-xl-start{-ms-flex-item-align:start !important;align-self:flex-start !important}.align-self-xl-end{-ms-flex-item-align:end !important;align-self:flex-end !important}.align-self-xl-center{-ms-flex-item-align:center !important;align-self:center !important}.align-self-xl-baseline{-ms-flex-item-align:baseline !important;align-self:baseline !important}.align-self-xl-stretch{-ms-flex-item-align:stretch !important;align-self:stretch !important}}.w-25{width:25% !important}.w-50{width:50% !important}.w-75{width:75% !important}.w-100{width:100% !important}.w-auto{width:auto !important}.h-25{height:25% !important}.h-50{height:50% !important}.h-75{height:75% !important}.h-100{height:100% !important}.h-auto{height:auto !important}.mw-100{max-width:100% !important}.mh-100{max-height:100% !important}.m-0{margin:0 !important}.mt-0,.my-0{margin-top:0 !important}.mr-0,.mx-0{margin-right:0 !important}.mb-0,.my-0{margin-bottom:0 !important}.ml-0,.mx-0{margin-left:0 !important}.m-1{margin:.25rem !important}.mt-1,.my-1{margin-top:.25rem !important}.mr-1,.mx-1{margin-right:.25rem !important}.mb-1,.my-1{margin-bottom:.25rem !important}.ml-1,.mx-1{margin-left:.25rem !important}.m-2{margin:.5rem !important}.mt-2,.my-2{margin-top:.5rem !important}.mr-2,.mx-2{margin-right:.5rem !important}.mb-2,.my-2{margin-bottom:.5rem !important}.ml-2,.mx-2{margin-left:.5rem !important}.m-3{margin:1rem !important}.mt-3,.my-3{margin-top:1rem !important}.mr-3,.mx-3{margin-right:1rem !important}.mb-3,.my-3{margin-bottom:1rem !important}.ml-3,.mx-3{margin-left:1rem !important}.m-4{margin:1.5rem !important}.mt-4,.my-4{margin-top:1.5rem !important}.mr-4,.mx-4{margin-right:1.5rem !important}.mb-4,.my-4{margin-bottom:1.5rem !important}.ml-4,.mx-4{margin-left:1.5rem !important}.m-5{margin:3rem !important}.mt-5,.my-5{margin-top:3rem !important}.mr-5,.mx-5{margin-right:3rem !important}.mb-5,.my-5{margin-bottom:3rem !important}.ml-5,.mx-5{margin-left:3rem !important}.p-0{padding:0 !important}.pt-0,.py-0{padding-top:0 !important}.pr-0,.px-0{padding-right:0 !important}.pb-0,.py-0{padding-bottom:0 !important}.pl-0,.px-0{padding-left:0 !important}.p-1{padding:.25rem !important}.pt-1,.py-1{padding-top:.25rem !important}.pr-1,.px-1{padding-right:.25rem !important}.pb-1,.py-1{padding-bottom:.25rem !important}.pl-1,.px-1{padding-left:.25rem !important}.p-2{padding:.5rem !important}.pt-2,.py-2{padding-top:.5rem !important}.pr-2,.px-2{padding-right:.5rem !important}.pb-2,.py-2{padding-bottom:.5rem !important}.pl-2,.px-2{padding-left:.5rem !important}.p-3{padding:1rem !important}.pt-3,.py-3{padding-top:1rem !important}.pr-3,.px-3{padding-right:1rem !important}.pb-3,.py-3{padding-bottom:1rem !important}.pl-3,.px-3{padding-left:1rem !important}.p-4{padding:1.5rem !important}.pt-4,.py-4{padding-top:1.5rem !important}.pr-4,.px-4{padding-right:1.5rem !important}.pb-4,.py-4{padding-bottom:1.5rem !important}.pl-4,.px-4{padding-left:1.5rem !important}.p-5{padding:3rem !important}.pt-5,.py-5{padding-top:3rem !important}.pr-5,.px-5{padding-right:3rem !important}.pb-5,.py-5{padding-bottom:3rem !important}.pl-5,.px-5{padding-left:3rem !important}.m-auto{margin:auto !important}.mt-auto,.my-auto{margin-top:auto !important}.mr-auto,.mx-auto{margin-right:auto !important}.mb-auto,.my-auto{margin-bottom:auto !important}.ml-auto,.mx-auto{margin-left:auto !important}@media (min-width: 576px){.m-sm-0{margin:0 !important}.mt-sm-0,.my-sm-0{margin-top:0 !important}.mr-sm-0,.mx-sm-0{margin-right:0 !important}.mb-sm-0,.my-sm-0{margin-bottom:0 !important}.ml-sm-0,.mx-sm-0{margin-left:0 !important}.m-sm-1{margin:.25rem !important}.mt-sm-1,.my-sm-1{margin-top:.25rem !important}.mr-sm-1,.mx-sm-1{margin-right:.25rem !important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem !important}.ml-sm-1,.mx-sm-1{margin-left:.25rem !important}.m-sm-2{margin:.5rem !important}.mt-sm-2,.my-sm-2{margin-top:.5rem !important}.mr-sm-2,.mx-sm-2{margin-right:.5rem !important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem !important}.ml-sm-2,.mx-sm-2{margin-left:.5rem !important}.m-sm-3{margin:1rem !important}.mt-sm-3,.my-sm-3{margin-top:1rem !important}.mr-sm-3,.mx-sm-3{margin-right:1rem !important}.mb-sm-3,.my-sm-3{margin-bottom:1rem !important}.ml-sm-3,.mx-sm-3{margin-left:1rem !important}.m-sm-4{margin:1.5rem !important}.mt-sm-4,.my-sm-4{margin-top:1.5rem !important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem !important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem !important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem !important}.m-sm-5{margin:3rem !important}.mt-sm-5,.my-sm-5{margin-top:3rem !important}.mr-sm-5,.mx-sm-5{margin-right:3rem !important}.mb-sm-5,.my-sm-5{margin-bottom:3rem !important}.ml-sm-5,.mx-sm-5{margin-left:3rem !important}.p-sm-0{padding:0 !important}.pt-sm-0,.py-sm-0{padding-top:0 !important}.pr-sm-0,.px-sm-0{padding-right:0 !important}.pb-sm-0,.py-sm-0{padding-bottom:0 !important}.pl-sm-0,.px-sm-0{padding-left:0 !important}.p-sm-1{padding:.25rem !important}.pt-sm-1,.py-sm-1{padding-top:.25rem !important}.pr-sm-1,.px-sm-1{padding-right:.25rem !important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem !important}.pl-sm-1,.px-sm-1{padding-left:.25rem !important}.p-sm-2{padding:.5rem !important}.pt-sm-2,.py-sm-2{padding-top:.5rem !important}.pr-sm-2,.px-sm-2{padding-right:.5rem !important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem !important}.pl-sm-2,.px-sm-2{padding-left:.5rem !important}.p-sm-3{padding:1rem !important}.pt-sm-3,.py-sm-3{padding-top:1rem !important}.pr-sm-3,.px-sm-3{padding-right:1rem !important}.pb-sm-3,.py-sm-3{padding-bottom:1rem !important}.pl-sm-3,.px-sm-3{padding-left:1rem !important}.p-sm-4{padding:1.5rem !important}.pt-sm-4,.py-sm-4{padding-top:1.5rem !important}.pr-sm-4,.px-sm-4{padding-right:1.5rem !important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem !important}.pl-sm-4,.px-sm-4{padding-left:1.5rem !important}.p-sm-5{padding:3rem !important}.pt-sm-5,.py-sm-5{padding-top:3rem !important}.pr-sm-5,.px-sm-5{padding-right:3rem !important}.pb-sm-5,.py-sm-5{padding-bottom:3rem !important}.pl-sm-5,.px-sm-5{padding-left:3rem !important}.m-sm-auto{margin:auto !important}.mt-sm-auto,.my-sm-auto{margin-top:auto !important}.mr-sm-auto,.mx-sm-auto{margin-right:auto !important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto !important}.ml-sm-auto,.mx-sm-auto{margin-left:auto !important}}@media (min-width: 768px){.m-md-0{margin:0 !important}.mt-md-0,.my-md-0{margin-top:0 !important}.mr-md-0,.mx-md-0{margin-right:0 !important}.mb-md-0,.my-md-0{margin-bottom:0 !important}.ml-md-0,.mx-md-0{margin-left:0 !important}.m-md-1{margin:.25rem !important}.mt-md-1,.my-md-1{margin-top:.25rem !important}.mr-md-1,.mx-md-1{margin-right:.25rem !important}.mb-md-1,.my-md-1{margin-bottom:.25rem !important}.ml-md-1,.mx-md-1{margin-left:.25rem !important}.m-md-2{margin:.5rem !important}.mt-md-2,.my-md-2{margin-top:.5rem !important}.mr-md-2,.mx-md-2{margin-right:.5rem !important}.mb-md-2,.my-md-2{margin-bottom:.5rem !important}.ml-md-2,.mx-md-2{margin-left:.5rem !important}.m-md-3{margin:1rem !important}.mt-md-3,.my-md-3{margin-top:1rem !important}.mr-md-3,.mx-md-3{margin-right:1rem !important}.mb-md-3,.my-md-3{margin-bottom:1rem !important}.ml-md-3,.mx-md-3{margin-left:1rem !important}.m-md-4{margin:1.5rem !important}.mt-md-4,.my-md-4{margin-top:1.5rem !important}.mr-md-4,.mx-md-4{margin-right:1.5rem !important}.mb-md-4,.my-md-4{margin-bottom:1.5rem !important}.ml-md-4,.mx-md-4{margin-left:1.5rem !important}.m-md-5{margin:3rem !important}.mt-md-5,.my-md-5{margin-top:3rem !important}.mr-md-5,.mx-md-5{margin-right:3rem !important}.mb-md-5,.my-md-5{margin-bottom:3rem !important}.ml-md-5,.mx-md-5{margin-left:3rem !important}.p-md-0{padding:0 !important}.pt-md-0,.py-md-0{padding-top:0 !important}.pr-md-0,.px-md-0{padding-right:0 !important}.pb-md-0,.py-md-0{padding-bottom:0 !important}.pl-md-0,.px-md-0{padding-left:0 !important}.p-md-1{padding:.25rem !important}.pt-md-1,.py-md-1{padding-top:.25rem !important}.pr-md-1,.px-md-1{padding-right:.25rem !important}.pb-md-1,.py-md-1{padding-bottom:.25rem !important}.pl-md-1,.px-md-1{padding-left:.25rem !important}.p-md-2{padding:.5rem !important}.pt-md-2,.py-md-2{padding-top:.5rem !important}.pr-md-2,.px-md-2{padding-right:.5rem !important}.pb-md-2,.py-md-2{padding-bottom:.5rem !important}.pl-md-2,.px-md-2{padding-left:.5rem !important}.p-md-3{padding:1rem !important}.pt-md-3,.py-md-3{padding-top:1rem !important}.pr-md-3,.px-md-3{padding-right:1rem !important}.pb-md-3,.py-md-3{padding-bottom:1rem !important}.pl-md-3,.px-md-3{padding-left:1rem !important}.p-md-4{padding:1.5rem !important}.pt-md-4,.py-md-4{padding-top:1.5rem !important}.pr-md-4,.px-md-4{padding-right:1.5rem !important}.pb-md-4,.py-md-4{padding-bottom:1.5rem !important}.pl-md-4,.px-md-4{padding-left:1.5rem !important}.p-md-5{padding:3rem !important}.pt-md-5,.py-md-5{padding-top:3rem !important}.pr-md-5,.px-md-5{padding-right:3rem !important}.pb-md-5,.py-md-5{padding-bottom:3rem !important}.pl-md-5,.px-md-5{padding-left:3rem !important}.m-md-auto{margin:auto !important}.mt-md-auto,.my-md-auto{margin-top:auto !important}.mr-md-auto,.mx-md-auto{margin-right:auto !important}.mb-md-auto,.my-md-auto{margin-bottom:auto !important}.ml-md-auto,.mx-md-auto{margin-left:auto !important}}@media (min-width: 992px){.m-lg-0{margin:0 !important}.mt-lg-0,.my-lg-0{margin-top:0 !important}.mr-lg-0,.mx-lg-0{margin-right:0 !important}.mb-lg-0,.my-lg-0{margin-bottom:0 !important}.ml-lg-0,.mx-lg-0{margin-left:0 !important}.m-lg-1{margin:.25rem !important}.mt-lg-1,.my-lg-1{margin-top:.25rem !important}.mr-lg-1,.mx-lg-1{margin-right:.25rem !important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem !important}.ml-lg-1,.mx-lg-1{margin-left:.25rem !important}.m-lg-2{margin:.5rem !important}.mt-lg-2,.my-lg-2{margin-top:.5rem !important}.mr-lg-2,.mx-lg-2{margin-right:.5rem !important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem !important}.ml-lg-2,.mx-lg-2{margin-left:.5rem !important}.m-lg-3{margin:1rem !important}.mt-lg-3,.my-lg-3{margin-top:1rem !important}.mr-lg-3,.mx-lg-3{margin-right:1rem !important}.mb-lg-3,.my-lg-3{margin-bottom:1rem !important}.ml-lg-3,.mx-lg-3{margin-left:1rem !important}.m-lg-4{margin:1.5rem !important}.mt-lg-4,.my-lg-4{margin-top:1.5rem !important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem !important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem !important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem !important}.m-lg-5{margin:3rem !important}.mt-lg-5,.my-lg-5{margin-top:3rem !important}.mr-lg-5,.mx-lg-5{margin-right:3rem !important}.mb-lg-5,.my-lg-5{margin-bottom:3rem !important}.ml-lg-5,.mx-lg-5{margin-left:3rem !important}.p-lg-0{padding:0 !important}.pt-lg-0,.py-lg-0{padding-top:0 !important}.pr-lg-0,.px-lg-0{padding-right:0 !important}.pb-lg-0,.py-lg-0{padding-bottom:0 !important}.pl-lg-0,.px-lg-0{padding-left:0 !important}.p-lg-1{padding:.25rem !important}.pt-lg-1,.py-lg-1{padding-top:.25rem !important}.pr-lg-1,.px-lg-1{padding-right:.25rem !important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem !important}.pl-lg-1,.px-lg-1{padding-left:.25rem !important}.p-lg-2{padding:.5rem !important}.pt-lg-2,.py-lg-2{padding-top:.5rem !important}.pr-lg-2,.px-lg-2{padding-right:.5rem !important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem !important}.pl-lg-2,.px-lg-2{padding-left:.5rem !important}.p-lg-3{padding:1rem !important}.pt-lg-3,.py-lg-3{padding-top:1rem !important}.pr-lg-3,.px-lg-3{padding-right:1rem !important}.pb-lg-3,.py-lg-3{padding-bottom:1rem !important}.pl-lg-3,.px-lg-3{padding-left:1rem !important}.p-lg-4{padding:1.5rem !important}.pt-lg-4,.py-lg-4{padding-top:1.5rem !important}.pr-lg-4,.px-lg-4{padding-right:1.5rem !important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem !important}.pl-lg-4,.px-lg-4{padding-left:1.5rem !important}.p-lg-5{padding:3rem !important}.pt-lg-5,.py-lg-5{padding-top:3rem !important}.pr-lg-5,.px-lg-5{padding-right:3rem !important}.pb-lg-5,.py-lg-5{padding-bottom:3rem !important}.pl-lg-5,.px-lg-5{padding-left:3rem !important}.m-lg-auto{margin:auto !important}.mt-lg-auto,.my-lg-auto{margin-top:auto !important}.mr-lg-auto,.mx-lg-auto{margin-right:auto !important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto !important}.ml-lg-auto,.mx-lg-auto{margin-left:auto !important}}@media (min-width: 1200px){.m-xl-0{margin:0 !important}.mt-xl-0,.my-xl-0{margin-top:0 !important}.mr-xl-0,.mx-xl-0{margin-right:0 !important}.mb-xl-0,.my-xl-0{margin-bottom:0 !important}.ml-xl-0,.mx-xl-0{margin-left:0 !important}.m-xl-1{margin:.25rem !important}.mt-xl-1,.my-xl-1{margin-top:.25rem !important}.mr-xl-1,.mx-xl-1{margin-right:.25rem !important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem !important}.ml-xl-1,.mx-xl-1{margin-left:.25rem !important}.m-xl-2{margin:.5rem !important}.mt-xl-2,.my-xl-2{margin-top:.5rem !important}.mr-xl-2,.mx-xl-2{margin-right:.5rem !important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem !important}.ml-xl-2,.mx-xl-2{margin-left:.5rem !important}.m-xl-3{margin:1rem !important}.mt-xl-3,.my-xl-3{margin-top:1rem !important}.mr-xl-3,.mx-xl-3{margin-right:1rem !important}.mb-xl-3,.my-xl-3{margin-bottom:1rem !important}.ml-xl-3,.mx-xl-3{margin-left:1rem !important}.m-xl-4{margin:1.5rem !important}.mt-xl-4,.my-xl-4{margin-top:1.5rem !important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem !important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem !important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem !important}.m-xl-5{margin:3rem !important}.mt-xl-5,.my-xl-5{margin-top:3rem !important}.mr-xl-5,.mx-xl-5{margin-right:3rem !important}.mb-xl-5,.my-xl-5{margin-bottom:3rem !important}.ml-xl-5,.mx-xl-5{margin-left:3rem !important}.p-xl-0{padding:0 !important}.pt-xl-0,.py-xl-0{padding-top:0 !important}.pr-xl-0,.px-xl-0{padding-right:0 !important}.pb-xl-0,.py-xl-0{padding-bottom:0 !important}.pl-xl-0,.px-xl-0{padding-left:0 !important}.p-xl-1{padding:.25rem !important}.pt-xl-1,.py-xl-1{padding-top:.25rem !important}.pr-xl-1,.px-xl-1{padding-right:.25rem !important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem !important}.pl-xl-1,.px-xl-1{padding-left:.25rem !important}.p-xl-2{padding:.5rem !important}.pt-xl-2,.py-xl-2{padding-top:.5rem !important}.pr-xl-2,.px-xl-2{padding-right:.5rem !important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem !important}.pl-xl-2,.px-xl-2{padding-left:.5rem !important}.p-xl-3{padding:1rem !important}.pt-xl-3,.py-xl-3{padding-top:1rem !important}.pr-xl-3,.px-xl-3{padding-right:1rem !important}.pb-xl-3,.py-xl-3{padding-bottom:1rem !important}.pl-xl-3,.px-xl-3{padding-left:1rem !important}.p-xl-4{padding:1.5rem !important}.pt-xl-4,.py-xl-4{padding-top:1.5rem !important}.pr-xl-4,.px-xl-4{padding-right:1.5rem !important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem !important}.pl-xl-4,.px-xl-4{padding-left:1.5rem !important}.p-xl-5{padding:3rem !important}.pt-xl-5,.py-xl-5{padding-top:3rem !important}.pr-xl-5,.px-xl-5{padding-right:3rem !important}.pb-xl-5,.py-xl-5{padding-bottom:3rem !important}.pl-xl-5,.px-xl-5{padding-left:3rem !important}.m-xl-auto{margin:auto !important}.mt-xl-auto,.my-xl-auto{margin-top:auto !important}.mr-xl-auto,.mx-xl-auto{margin-right:auto !important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto !important}.ml-xl-auto,.mx-xl-auto{margin-left:auto !important}}.visible{visibility:visible !important}.invisible{visibility:hidden !important} \ No newline at end of file + */@-ms-viewport{width:device-width}html{-webkit-box-sizing:border-box;box-sizing:border-box;-ms-overflow-style:scrollbar}*,*::before,*::after{-webkit-box-sizing:inherit;box-sizing:inherit}.container{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width: 576px){.container{max-width:540px}}@media (min-width: 768px){.container{max-width:720px}}@media (min-width: 992px){.container{max-width:960px}}@media (min-width: 1200px){.container{max-width:1140px}}.container-fluid{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*="col-"]{padding-right:0;padding-left:0}.col-1,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-10,.col-11,.col-12,.col,.col-auto,.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm,.col-sm-auto,.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12,.col-md,.col-md-auto,.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg,.col-lg-auto,.col-xl-1,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl,.col-xl-auto{position:relative;width:100%;min-height:1px;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-1{-webkit-box-flex:0;-ms-flex:0 0 8.3333333333%;flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-2{-webkit-box-flex:0;-ms-flex:0 0 16.6666666667%;flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-webkit-box-flex:0;-ms-flex:0 0 33.3333333333%;flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-5{-webkit-box-flex:0;-ms-flex:0 0 41.6666666667%;flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-webkit-box-flex:0;-ms-flex:0 0 58.3333333333%;flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-8{-webkit-box-flex:0;-ms-flex:0 0 66.6666666667%;flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-webkit-box-flex:0;-ms-flex:0 0 83.3333333333%;flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-11{-webkit-box-flex:0;-ms-flex:0 0 91.6666666667%;flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-last{-webkit-box-ordinal-group:14;-ms-flex-order:13;order:13}.order-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-9{-webkit-box-ordinal-group:10;-ms-flex-order:9;order:9}.order-10{-webkit-box-ordinal-group:11;-ms-flex-order:10;order:10}.order-11{-webkit-box-ordinal-group:12;-ms-flex-order:11;order:11}.order-12{-webkit-box-ordinal-group:13;-ms-flex-order:12;order:12}.offset-1{margin-left:8.3333333333%}.offset-2{margin-left:16.6666666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.3333333333%}.offset-5{margin-left:41.6666666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.3333333333%}.offset-8{margin-left:66.6666666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.3333333333%}.offset-11{margin-left:91.6666666667%}@media (min-width: 576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-sm-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-sm-1{-webkit-box-flex:0;-ms-flex:0 0 8.3333333333%;flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-sm-2{-webkit-box-flex:0;-ms-flex:0 0 16.6666666667%;flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-sm-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-webkit-box-flex:0;-ms-flex:0 0 33.3333333333%;flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-sm-5{-webkit-box-flex:0;-ms-flex:0 0 41.6666666667%;flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-sm-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-webkit-box-flex:0;-ms-flex:0 0 58.3333333333%;flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-sm-8{-webkit-box-flex:0;-ms-flex:0 0 66.6666666667%;flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-sm-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-webkit-box-flex:0;-ms-flex:0 0 83.3333333333%;flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-sm-11{-webkit-box-flex:0;-ms-flex:0 0 91.6666666667%;flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-sm-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-sm-last{-webkit-box-ordinal-group:14;-ms-flex-order:13;order:13}.order-sm-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-sm-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-sm-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-sm-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-sm-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-sm-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-sm-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-sm-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-sm-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-sm-9{-webkit-box-ordinal-group:10;-ms-flex-order:9;order:9}.order-sm-10{-webkit-box-ordinal-group:11;-ms-flex-order:10;order:10}.order-sm-11{-webkit-box-ordinal-group:12;-ms-flex-order:11;order:11}.order-sm-12{-webkit-box-ordinal-group:13;-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.3333333333%}.offset-sm-2{margin-left:16.6666666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.3333333333%}.offset-sm-5{margin-left:41.6666666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.3333333333%}.offset-sm-8{margin-left:66.6666666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.3333333333%}.offset-sm-11{margin-left:91.6666666667%}}@media (min-width: 768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-md-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-md-1{-webkit-box-flex:0;-ms-flex:0 0 8.3333333333%;flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-md-2{-webkit-box-flex:0;-ms-flex:0 0 16.6666666667%;flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-md-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-webkit-box-flex:0;-ms-flex:0 0 33.3333333333%;flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-md-5{-webkit-box-flex:0;-ms-flex:0 0 41.6666666667%;flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-md-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-webkit-box-flex:0;-ms-flex:0 0 58.3333333333%;flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-md-8{-webkit-box-flex:0;-ms-flex:0 0 66.6666666667%;flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-md-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-webkit-box-flex:0;-ms-flex:0 0 83.3333333333%;flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-md-11{-webkit-box-flex:0;-ms-flex:0 0 91.6666666667%;flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-md-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-md-last{-webkit-box-ordinal-group:14;-ms-flex-order:13;order:13}.order-md-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-md-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-md-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-md-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-md-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-md-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-md-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-md-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-md-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-md-9{-webkit-box-ordinal-group:10;-ms-flex-order:9;order:9}.order-md-10{-webkit-box-ordinal-group:11;-ms-flex-order:10;order:10}.order-md-11{-webkit-box-ordinal-group:12;-ms-flex-order:11;order:11}.order-md-12{-webkit-box-ordinal-group:13;-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.3333333333%}.offset-md-2{margin-left:16.6666666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.3333333333%}.offset-md-5{margin-left:41.6666666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.3333333333%}.offset-md-8{margin-left:66.6666666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.3333333333%}.offset-md-11{margin-left:91.6666666667%}}@media (min-width: 992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-lg-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-lg-1{-webkit-box-flex:0;-ms-flex:0 0 8.3333333333%;flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-lg-2{-webkit-box-flex:0;-ms-flex:0 0 16.6666666667%;flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-lg-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-webkit-box-flex:0;-ms-flex:0 0 33.3333333333%;flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-lg-5{-webkit-box-flex:0;-ms-flex:0 0 41.6666666667%;flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-lg-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-webkit-box-flex:0;-ms-flex:0 0 58.3333333333%;flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-lg-8{-webkit-box-flex:0;-ms-flex:0 0 66.6666666667%;flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-lg-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-webkit-box-flex:0;-ms-flex:0 0 83.3333333333%;flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-lg-11{-webkit-box-flex:0;-ms-flex:0 0 91.6666666667%;flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-lg-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-lg-last{-webkit-box-ordinal-group:14;-ms-flex-order:13;order:13}.order-lg-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-lg-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-lg-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-lg-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-lg-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-lg-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-lg-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-lg-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-lg-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-lg-9{-webkit-box-ordinal-group:10;-ms-flex-order:9;order:9}.order-lg-10{-webkit-box-ordinal-group:11;-ms-flex-order:10;order:10}.order-lg-11{-webkit-box-ordinal-group:12;-ms-flex-order:11;order:11}.order-lg-12{-webkit-box-ordinal-group:13;-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.3333333333%}.offset-lg-2{margin-left:16.6666666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.3333333333%}.offset-lg-5{margin-left:41.6666666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.3333333333%}.offset-lg-8{margin-left:66.6666666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.3333333333%}.offset-lg-11{margin-left:91.6666666667%}}@media (min-width: 1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-xl-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-xl-1{-webkit-box-flex:0;-ms-flex:0 0 8.3333333333%;flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-xl-2{-webkit-box-flex:0;-ms-flex:0 0 16.6666666667%;flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-xl-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-webkit-box-flex:0;-ms-flex:0 0 33.3333333333%;flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-xl-5{-webkit-box-flex:0;-ms-flex:0 0 41.6666666667%;flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-xl-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-webkit-box-flex:0;-ms-flex:0 0 58.3333333333%;flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-xl-8{-webkit-box-flex:0;-ms-flex:0 0 66.6666666667%;flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-xl-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-webkit-box-flex:0;-ms-flex:0 0 83.3333333333%;flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-xl-11{-webkit-box-flex:0;-ms-flex:0 0 91.6666666667%;flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-xl-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-xl-last{-webkit-box-ordinal-group:14;-ms-flex-order:13;order:13}.order-xl-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-xl-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-xl-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-xl-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-xl-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-xl-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-xl-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-xl-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-xl-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-xl-9{-webkit-box-ordinal-group:10;-ms-flex-order:9;order:9}.order-xl-10{-webkit-box-ordinal-group:11;-ms-flex-order:10;order:10}.order-xl-11{-webkit-box-ordinal-group:12;-ms-flex-order:11;order:11}.order-xl-12{-webkit-box-ordinal-group:13;-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.3333333333%}.offset-xl-2{margin-left:16.6666666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.3333333333%}.offset-xl-5{margin-left:41.6666666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.3333333333%}.offset-xl-8{margin-left:66.6666666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.3333333333%}.offset-xl-11{margin-left:91.6666666667%}}.d-none{display:none !important}.d-inline{display:inline !important}.d-inline-block{display:inline-block !important}.d-block{display:block !important}.d-table{display:table !important}.d-table-row{display:table-row !important}.d-table-cell{display:table-cell !important}.d-flex{display:-webkit-box !important;display:-ms-flexbox !important;display:flex !important}.d-inline-flex{display:-webkit-inline-box !important;display:-ms-inline-flexbox !important;display:inline-flex !important}@media (min-width: 576px){.d-sm-none{display:none !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-block{display:block !important}.d-sm-table{display:table !important}.d-sm-table-row{display:table-row !important}.d-sm-table-cell{display:table-cell !important}.d-sm-flex{display:-webkit-box !important;display:-ms-flexbox !important;display:flex !important}.d-sm-inline-flex{display:-webkit-inline-box !important;display:-ms-inline-flexbox !important;display:inline-flex !important}}@media (min-width: 768px){.d-md-none{display:none !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-block{display:block !important}.d-md-table{display:table !important}.d-md-table-row{display:table-row !important}.d-md-table-cell{display:table-cell !important}.d-md-flex{display:-webkit-box !important;display:-ms-flexbox !important;display:flex !important}.d-md-inline-flex{display:-webkit-inline-box !important;display:-ms-inline-flexbox !important;display:inline-flex !important}}@media (min-width: 992px){.d-lg-none{display:none !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-block{display:block !important}.d-lg-table{display:table !important}.d-lg-table-row{display:table-row !important}.d-lg-table-cell{display:table-cell !important}.d-lg-flex{display:-webkit-box !important;display:-ms-flexbox !important;display:flex !important}.d-lg-inline-flex{display:-webkit-inline-box !important;display:-ms-inline-flexbox !important;display:inline-flex !important}}@media (min-width: 1200px){.d-xl-none{display:none !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-block{display:block !important}.d-xl-table{display:table !important}.d-xl-table-row{display:table-row !important}.d-xl-table-cell{display:table-cell !important}.d-xl-flex{display:-webkit-box !important;display:-ms-flexbox !important;display:flex !important}.d-xl-inline-flex{display:-webkit-inline-box !important;display:-ms-inline-flexbox !important;display:inline-flex !important}}@media print{.d-print-none{display:none !important}.d-print-inline{display:inline !important}.d-print-inline-block{display:inline-block !important}.d-print-block{display:block !important}.d-print-table{display:table !important}.d-print-table-row{display:table-row !important}.d-print-table-cell{display:table-cell !important}.d-print-flex{display:-webkit-box !important;display:-ms-flexbox !important;display:flex !important}.d-print-inline-flex{display:-webkit-inline-box !important;display:-ms-inline-flexbox !important;display:inline-flex !important}}.flex-row{-webkit-box-orient:horizontal !important;-webkit-box-direction:normal !important;-ms-flex-direction:row !important;flex-direction:row !important}.flex-column{-webkit-box-orient:vertical !important;-webkit-box-direction:normal !important;-ms-flex-direction:column !important;flex-direction:column !important}.flex-row-reverse{-webkit-box-orient:horizontal !important;-webkit-box-direction:reverse !important;-ms-flex-direction:row-reverse !important;flex-direction:row-reverse !important}.flex-column-reverse{-webkit-box-orient:vertical !important;-webkit-box-direction:reverse !important;-ms-flex-direction:column-reverse !important;flex-direction:column-reverse !important}.flex-wrap{-ms-flex-wrap:wrap !important;flex-wrap:wrap !important}.flex-nowrap{-ms-flex-wrap:nowrap !important;flex-wrap:nowrap !important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse !important;flex-wrap:wrap-reverse !important}.flex-fill{-webkit-box-flex:1 !important;-ms-flex:1 1 auto !important;flex:1 1 auto !important}.flex-grow-0{-webkit-box-flex:0 !important;-ms-flex-positive:0 !important;flex-grow:0 !important}.flex-grow-1{-webkit-box-flex:1 !important;-ms-flex-positive:1 !important;flex-grow:1 !important}.flex-shrink-0{-ms-flex-negative:0 !important;flex-shrink:0 !important}.flex-shrink-1{-ms-flex-negative:1 !important;flex-shrink:1 !important}.justify-content-start{-webkit-box-pack:start !important;-ms-flex-pack:start !important;justify-content:flex-start !important}.justify-content-end{-webkit-box-pack:end !important;-ms-flex-pack:end !important;justify-content:flex-end !important}.justify-content-center{-webkit-box-pack:center !important;-ms-flex-pack:center !important;justify-content:center !important}.justify-content-between{-webkit-box-pack:justify !important;-ms-flex-pack:justify !important;justify-content:space-between !important}.justify-content-around{-ms-flex-pack:distribute !important;justify-content:space-around !important}.align-items-start{-webkit-box-align:start !important;-ms-flex-align:start !important;align-items:flex-start !important}.align-items-end{-webkit-box-align:end !important;-ms-flex-align:end !important;align-items:flex-end !important}.align-items-center{-webkit-box-align:center !important;-ms-flex-align:center !important;align-items:center !important}.align-items-baseline{-webkit-box-align:baseline !important;-ms-flex-align:baseline !important;align-items:baseline !important}.align-items-stretch{-webkit-box-align:stretch !important;-ms-flex-align:stretch !important;align-items:stretch !important}.align-content-start{-ms-flex-line-pack:start !important;align-content:flex-start !important}.align-content-end{-ms-flex-line-pack:end !important;align-content:flex-end !important}.align-content-center{-ms-flex-line-pack:center !important;align-content:center !important}.align-content-between{-ms-flex-line-pack:justify !important;align-content:space-between !important}.align-content-around{-ms-flex-line-pack:distribute !important;align-content:space-around !important}.align-content-stretch{-ms-flex-line-pack:stretch !important;align-content:stretch !important}.align-self-auto{-ms-flex-item-align:auto !important;align-self:auto !important}.align-self-start{-ms-flex-item-align:start !important;align-self:flex-start !important}.align-self-end{-ms-flex-item-align:end !important;align-self:flex-end !important}.align-self-center{-ms-flex-item-align:center !important;align-self:center !important}.align-self-baseline{-ms-flex-item-align:baseline !important;align-self:baseline !important}.align-self-stretch{-ms-flex-item-align:stretch !important;align-self:stretch !important}@media (min-width: 576px){.flex-sm-row{-webkit-box-orient:horizontal !important;-webkit-box-direction:normal !important;-ms-flex-direction:row !important;flex-direction:row !important}.flex-sm-column{-webkit-box-orient:vertical !important;-webkit-box-direction:normal !important;-ms-flex-direction:column !important;flex-direction:column !important}.flex-sm-row-reverse{-webkit-box-orient:horizontal !important;-webkit-box-direction:reverse !important;-ms-flex-direction:row-reverse !important;flex-direction:row-reverse !important}.flex-sm-column-reverse{-webkit-box-orient:vertical !important;-webkit-box-direction:reverse !important;-ms-flex-direction:column-reverse !important;flex-direction:column-reverse !important}.flex-sm-wrap{-ms-flex-wrap:wrap !important;flex-wrap:wrap !important}.flex-sm-nowrap{-ms-flex-wrap:nowrap !important;flex-wrap:nowrap !important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse !important;flex-wrap:wrap-reverse !important}.flex-sm-fill{-webkit-box-flex:1 !important;-ms-flex:1 1 auto !important;flex:1 1 auto !important}.flex-sm-grow-0{-webkit-box-flex:0 !important;-ms-flex-positive:0 !important;flex-grow:0 !important}.flex-sm-grow-1{-webkit-box-flex:1 !important;-ms-flex-positive:1 !important;flex-grow:1 !important}.flex-sm-shrink-0{-ms-flex-negative:0 !important;flex-shrink:0 !important}.flex-sm-shrink-1{-ms-flex-negative:1 !important;flex-shrink:1 !important}.justify-content-sm-start{-webkit-box-pack:start !important;-ms-flex-pack:start !important;justify-content:flex-start !important}.justify-content-sm-end{-webkit-box-pack:end !important;-ms-flex-pack:end !important;justify-content:flex-end !important}.justify-content-sm-center{-webkit-box-pack:center !important;-ms-flex-pack:center !important;justify-content:center !important}.justify-content-sm-between{-webkit-box-pack:justify !important;-ms-flex-pack:justify !important;justify-content:space-between !important}.justify-content-sm-around{-ms-flex-pack:distribute !important;justify-content:space-around !important}.align-items-sm-start{-webkit-box-align:start !important;-ms-flex-align:start !important;align-items:flex-start !important}.align-items-sm-end{-webkit-box-align:end !important;-ms-flex-align:end !important;align-items:flex-end !important}.align-items-sm-center{-webkit-box-align:center !important;-ms-flex-align:center !important;align-items:center !important}.align-items-sm-baseline{-webkit-box-align:baseline !important;-ms-flex-align:baseline !important;align-items:baseline !important}.align-items-sm-stretch{-webkit-box-align:stretch !important;-ms-flex-align:stretch !important;align-items:stretch !important}.align-content-sm-start{-ms-flex-line-pack:start !important;align-content:flex-start !important}.align-content-sm-end{-ms-flex-line-pack:end !important;align-content:flex-end !important}.align-content-sm-center{-ms-flex-line-pack:center !important;align-content:center !important}.align-content-sm-between{-ms-flex-line-pack:justify !important;align-content:space-between !important}.align-content-sm-around{-ms-flex-line-pack:distribute !important;align-content:space-around !important}.align-content-sm-stretch{-ms-flex-line-pack:stretch !important;align-content:stretch !important}.align-self-sm-auto{-ms-flex-item-align:auto !important;align-self:auto !important}.align-self-sm-start{-ms-flex-item-align:start !important;align-self:flex-start !important}.align-self-sm-end{-ms-flex-item-align:end !important;align-self:flex-end !important}.align-self-sm-center{-ms-flex-item-align:center !important;align-self:center !important}.align-self-sm-baseline{-ms-flex-item-align:baseline !important;align-self:baseline !important}.align-self-sm-stretch{-ms-flex-item-align:stretch !important;align-self:stretch !important}}@media (min-width: 768px){.flex-md-row{-webkit-box-orient:horizontal !important;-webkit-box-direction:normal !important;-ms-flex-direction:row !important;flex-direction:row !important}.flex-md-column{-webkit-box-orient:vertical !important;-webkit-box-direction:normal !important;-ms-flex-direction:column !important;flex-direction:column !important}.flex-md-row-reverse{-webkit-box-orient:horizontal !important;-webkit-box-direction:reverse !important;-ms-flex-direction:row-reverse !important;flex-direction:row-reverse !important}.flex-md-column-reverse{-webkit-box-orient:vertical !important;-webkit-box-direction:reverse !important;-ms-flex-direction:column-reverse !important;flex-direction:column-reverse !important}.flex-md-wrap{-ms-flex-wrap:wrap !important;flex-wrap:wrap !important}.flex-md-nowrap{-ms-flex-wrap:nowrap !important;flex-wrap:nowrap !important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse !important;flex-wrap:wrap-reverse !important}.flex-md-fill{-webkit-box-flex:1 !important;-ms-flex:1 1 auto !important;flex:1 1 auto !important}.flex-md-grow-0{-webkit-box-flex:0 !important;-ms-flex-positive:0 !important;flex-grow:0 !important}.flex-md-grow-1{-webkit-box-flex:1 !important;-ms-flex-positive:1 !important;flex-grow:1 !important}.flex-md-shrink-0{-ms-flex-negative:0 !important;flex-shrink:0 !important}.flex-md-shrink-1{-ms-flex-negative:1 !important;flex-shrink:1 !important}.justify-content-md-start{-webkit-box-pack:start !important;-ms-flex-pack:start !important;justify-content:flex-start !important}.justify-content-md-end{-webkit-box-pack:end !important;-ms-flex-pack:end !important;justify-content:flex-end !important}.justify-content-md-center{-webkit-box-pack:center !important;-ms-flex-pack:center !important;justify-content:center !important}.justify-content-md-between{-webkit-box-pack:justify !important;-ms-flex-pack:justify !important;justify-content:space-between !important}.justify-content-md-around{-ms-flex-pack:distribute !important;justify-content:space-around !important}.align-items-md-start{-webkit-box-align:start !important;-ms-flex-align:start !important;align-items:flex-start !important}.align-items-md-end{-webkit-box-align:end !important;-ms-flex-align:end !important;align-items:flex-end !important}.align-items-md-center{-webkit-box-align:center !important;-ms-flex-align:center !important;align-items:center !important}.align-items-md-baseline{-webkit-box-align:baseline !important;-ms-flex-align:baseline !important;align-items:baseline !important}.align-items-md-stretch{-webkit-box-align:stretch !important;-ms-flex-align:stretch !important;align-items:stretch !important}.align-content-md-start{-ms-flex-line-pack:start !important;align-content:flex-start !important}.align-content-md-end{-ms-flex-line-pack:end !important;align-content:flex-end !important}.align-content-md-center{-ms-flex-line-pack:center !important;align-content:center !important}.align-content-md-between{-ms-flex-line-pack:justify !important;align-content:space-between !important}.align-content-md-around{-ms-flex-line-pack:distribute !important;align-content:space-around !important}.align-content-md-stretch{-ms-flex-line-pack:stretch !important;align-content:stretch !important}.align-self-md-auto{-ms-flex-item-align:auto !important;align-self:auto !important}.align-self-md-start{-ms-flex-item-align:start !important;align-self:flex-start !important}.align-self-md-end{-ms-flex-item-align:end !important;align-self:flex-end !important}.align-self-md-center{-ms-flex-item-align:center !important;align-self:center !important}.align-self-md-baseline{-ms-flex-item-align:baseline !important;align-self:baseline !important}.align-self-md-stretch{-ms-flex-item-align:stretch !important;align-self:stretch !important}}@media (min-width: 992px){.flex-lg-row{-webkit-box-orient:horizontal !important;-webkit-box-direction:normal !important;-ms-flex-direction:row !important;flex-direction:row !important}.flex-lg-column{-webkit-box-orient:vertical !important;-webkit-box-direction:normal !important;-ms-flex-direction:column !important;flex-direction:column !important}.flex-lg-row-reverse{-webkit-box-orient:horizontal !important;-webkit-box-direction:reverse !important;-ms-flex-direction:row-reverse !important;flex-direction:row-reverse !important}.flex-lg-column-reverse{-webkit-box-orient:vertical !important;-webkit-box-direction:reverse !important;-ms-flex-direction:column-reverse !important;flex-direction:column-reverse !important}.flex-lg-wrap{-ms-flex-wrap:wrap !important;flex-wrap:wrap !important}.flex-lg-nowrap{-ms-flex-wrap:nowrap !important;flex-wrap:nowrap !important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse !important;flex-wrap:wrap-reverse !important}.flex-lg-fill{-webkit-box-flex:1 !important;-ms-flex:1 1 auto !important;flex:1 1 auto !important}.flex-lg-grow-0{-webkit-box-flex:0 !important;-ms-flex-positive:0 !important;flex-grow:0 !important}.flex-lg-grow-1{-webkit-box-flex:1 !important;-ms-flex-positive:1 !important;flex-grow:1 !important}.flex-lg-shrink-0{-ms-flex-negative:0 !important;flex-shrink:0 !important}.flex-lg-shrink-1{-ms-flex-negative:1 !important;flex-shrink:1 !important}.justify-content-lg-start{-webkit-box-pack:start !important;-ms-flex-pack:start !important;justify-content:flex-start !important}.justify-content-lg-end{-webkit-box-pack:end !important;-ms-flex-pack:end !important;justify-content:flex-end !important}.justify-content-lg-center{-webkit-box-pack:center !important;-ms-flex-pack:center !important;justify-content:center !important}.justify-content-lg-between{-webkit-box-pack:justify !important;-ms-flex-pack:justify !important;justify-content:space-between !important}.justify-content-lg-around{-ms-flex-pack:distribute !important;justify-content:space-around !important}.align-items-lg-start{-webkit-box-align:start !important;-ms-flex-align:start !important;align-items:flex-start !important}.align-items-lg-end{-webkit-box-align:end !important;-ms-flex-align:end !important;align-items:flex-end !important}.align-items-lg-center{-webkit-box-align:center !important;-ms-flex-align:center !important;align-items:center !important}.align-items-lg-baseline{-webkit-box-align:baseline !important;-ms-flex-align:baseline !important;align-items:baseline !important}.align-items-lg-stretch{-webkit-box-align:stretch !important;-ms-flex-align:stretch !important;align-items:stretch !important}.align-content-lg-start{-ms-flex-line-pack:start !important;align-content:flex-start !important}.align-content-lg-end{-ms-flex-line-pack:end !important;align-content:flex-end !important}.align-content-lg-center{-ms-flex-line-pack:center !important;align-content:center !important}.align-content-lg-between{-ms-flex-line-pack:justify !important;align-content:space-between !important}.align-content-lg-around{-ms-flex-line-pack:distribute !important;align-content:space-around !important}.align-content-lg-stretch{-ms-flex-line-pack:stretch !important;align-content:stretch !important}.align-self-lg-auto{-ms-flex-item-align:auto !important;align-self:auto !important}.align-self-lg-start{-ms-flex-item-align:start !important;align-self:flex-start !important}.align-self-lg-end{-ms-flex-item-align:end !important;align-self:flex-end !important}.align-self-lg-center{-ms-flex-item-align:center !important;align-self:center !important}.align-self-lg-baseline{-ms-flex-item-align:baseline !important;align-self:baseline !important}.align-self-lg-stretch{-ms-flex-item-align:stretch !important;align-self:stretch !important}}@media (min-width: 1200px){.flex-xl-row{-webkit-box-orient:horizontal !important;-webkit-box-direction:normal !important;-ms-flex-direction:row !important;flex-direction:row !important}.flex-xl-column{-webkit-box-orient:vertical !important;-webkit-box-direction:normal !important;-ms-flex-direction:column !important;flex-direction:column !important}.flex-xl-row-reverse{-webkit-box-orient:horizontal !important;-webkit-box-direction:reverse !important;-ms-flex-direction:row-reverse !important;flex-direction:row-reverse !important}.flex-xl-column-reverse{-webkit-box-orient:vertical !important;-webkit-box-direction:reverse !important;-ms-flex-direction:column-reverse !important;flex-direction:column-reverse !important}.flex-xl-wrap{-ms-flex-wrap:wrap !important;flex-wrap:wrap !important}.flex-xl-nowrap{-ms-flex-wrap:nowrap !important;flex-wrap:nowrap !important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse !important;flex-wrap:wrap-reverse !important}.flex-xl-fill{-webkit-box-flex:1 !important;-ms-flex:1 1 auto !important;flex:1 1 auto !important}.flex-xl-grow-0{-webkit-box-flex:0 !important;-ms-flex-positive:0 !important;flex-grow:0 !important}.flex-xl-grow-1{-webkit-box-flex:1 !important;-ms-flex-positive:1 !important;flex-grow:1 !important}.flex-xl-shrink-0{-ms-flex-negative:0 !important;flex-shrink:0 !important}.flex-xl-shrink-1{-ms-flex-negative:1 !important;flex-shrink:1 !important}.justify-content-xl-start{-webkit-box-pack:start !important;-ms-flex-pack:start !important;justify-content:flex-start !important}.justify-content-xl-end{-webkit-box-pack:end !important;-ms-flex-pack:end !important;justify-content:flex-end !important}.justify-content-xl-center{-webkit-box-pack:center !important;-ms-flex-pack:center !important;justify-content:center !important}.justify-content-xl-between{-webkit-box-pack:justify !important;-ms-flex-pack:justify !important;justify-content:space-between !important}.justify-content-xl-around{-ms-flex-pack:distribute !important;justify-content:space-around !important}.align-items-xl-start{-webkit-box-align:start !important;-ms-flex-align:start !important;align-items:flex-start !important}.align-items-xl-end{-webkit-box-align:end !important;-ms-flex-align:end !important;align-items:flex-end !important}.align-items-xl-center{-webkit-box-align:center !important;-ms-flex-align:center !important;align-items:center !important}.align-items-xl-baseline{-webkit-box-align:baseline !important;-ms-flex-align:baseline !important;align-items:baseline !important}.align-items-xl-stretch{-webkit-box-align:stretch !important;-ms-flex-align:stretch !important;align-items:stretch !important}.align-content-xl-start{-ms-flex-line-pack:start !important;align-content:flex-start !important}.align-content-xl-end{-ms-flex-line-pack:end !important;align-content:flex-end !important}.align-content-xl-center{-ms-flex-line-pack:center !important;align-content:center !important}.align-content-xl-between{-ms-flex-line-pack:justify !important;align-content:space-between !important}.align-content-xl-around{-ms-flex-line-pack:distribute !important;align-content:space-around !important}.align-content-xl-stretch{-ms-flex-line-pack:stretch !important;align-content:stretch !important}.align-self-xl-auto{-ms-flex-item-align:auto !important;align-self:auto !important}.align-self-xl-start{-ms-flex-item-align:start !important;align-self:flex-start !important}.align-self-xl-end{-ms-flex-item-align:end !important;align-self:flex-end !important}.align-self-xl-center{-ms-flex-item-align:center !important;align-self:center !important}.align-self-xl-baseline{-ms-flex-item-align:baseline !important;align-self:baseline !important}.align-self-xl-stretch{-ms-flex-item-align:stretch !important;align-self:stretch !important}}.w-25{width:25% !important}.w-50{width:50% !important}.w-75{width:75% !important}.w-100{width:100% !important}.w-auto{width:auto !important}.h-25{height:25% !important}.h-50{height:50% !important}.h-75{height:75% !important}.h-100{height:100% !important}.h-auto{height:auto !important}.mw-100{max-width:100% !important}.mh-100{max-height:100% !important}.m-0{margin:0 !important}.mt-0,.my-0{margin-top:0 !important}.mr-0,.mx-0{margin-right:0 !important}.mb-0,.my-0{margin-bottom:0 !important}.ml-0,.mx-0{margin-left:0 !important}.m-1{margin:0.25rem !important}.mt-1,.my-1{margin-top:0.25rem !important}.mr-1,.mx-1{margin-right:0.25rem !important}.mb-1,.my-1{margin-bottom:0.25rem !important}.ml-1,.mx-1{margin-left:0.25rem !important}.m-2{margin:0.5rem !important}.mt-2,.my-2{margin-top:0.5rem !important}.mr-2,.mx-2{margin-right:0.5rem !important}.mb-2,.my-2{margin-bottom:0.5rem !important}.ml-2,.mx-2{margin-left:0.5rem !important}.m-3{margin:1rem !important}.mt-3,.my-3{margin-top:1rem !important}.mr-3,.mx-3{margin-right:1rem !important}.mb-3,.my-3{margin-bottom:1rem !important}.ml-3,.mx-3{margin-left:1rem !important}.m-4{margin:1.5rem !important}.mt-4,.my-4{margin-top:1.5rem !important}.mr-4,.mx-4{margin-right:1.5rem !important}.mb-4,.my-4{margin-bottom:1.5rem !important}.ml-4,.mx-4{margin-left:1.5rem !important}.m-5{margin:3rem !important}.mt-5,.my-5{margin-top:3rem !important}.mr-5,.mx-5{margin-right:3rem !important}.mb-5,.my-5{margin-bottom:3rem !important}.ml-5,.mx-5{margin-left:3rem !important}.p-0{padding:0 !important}.pt-0,.py-0{padding-top:0 !important}.pr-0,.px-0{padding-right:0 !important}.pb-0,.py-0{padding-bottom:0 !important}.pl-0,.px-0{padding-left:0 !important}.p-1{padding:0.25rem !important}.pt-1,.py-1{padding-top:0.25rem !important}.pr-1,.px-1{padding-right:0.25rem !important}.pb-1,.py-1{padding-bottom:0.25rem !important}.pl-1,.px-1{padding-left:0.25rem !important}.p-2{padding:0.5rem !important}.pt-2,.py-2{padding-top:0.5rem !important}.pr-2,.px-2{padding-right:0.5rem !important}.pb-2,.py-2{padding-bottom:0.5rem !important}.pl-2,.px-2{padding-left:0.5rem !important}.p-3{padding:1rem !important}.pt-3,.py-3{padding-top:1rem !important}.pr-3,.px-3{padding-right:1rem !important}.pb-3,.py-3{padding-bottom:1rem !important}.pl-3,.px-3{padding-left:1rem !important}.p-4{padding:1.5rem !important}.pt-4,.py-4{padding-top:1.5rem !important}.pr-4,.px-4{padding-right:1.5rem !important}.pb-4,.py-4{padding-bottom:1.5rem !important}.pl-4,.px-4{padding-left:1.5rem !important}.p-5{padding:3rem !important}.pt-5,.py-5{padding-top:3rem !important}.pr-5,.px-5{padding-right:3rem !important}.pb-5,.py-5{padding-bottom:3rem !important}.pl-5,.px-5{padding-left:3rem !important}.m-auto{margin:auto !important}.mt-auto,.my-auto{margin-top:auto !important}.mr-auto,.mx-auto{margin-right:auto !important}.mb-auto,.my-auto{margin-bottom:auto !important}.ml-auto,.mx-auto{margin-left:auto !important}@media (min-width: 576px){.m-sm-0{margin:0 !important}.mt-sm-0,.my-sm-0{margin-top:0 !important}.mr-sm-0,.mx-sm-0{margin-right:0 !important}.mb-sm-0,.my-sm-0{margin-bottom:0 !important}.ml-sm-0,.mx-sm-0{margin-left:0 !important}.m-sm-1{margin:0.25rem !important}.mt-sm-1,.my-sm-1{margin-top:0.25rem !important}.mr-sm-1,.mx-sm-1{margin-right:0.25rem !important}.mb-sm-1,.my-sm-1{margin-bottom:0.25rem !important}.ml-sm-1,.mx-sm-1{margin-left:0.25rem !important}.m-sm-2{margin:0.5rem !important}.mt-sm-2,.my-sm-2{margin-top:0.5rem !important}.mr-sm-2,.mx-sm-2{margin-right:0.5rem !important}.mb-sm-2,.my-sm-2{margin-bottom:0.5rem !important}.ml-sm-2,.mx-sm-2{margin-left:0.5rem !important}.m-sm-3{margin:1rem !important}.mt-sm-3,.my-sm-3{margin-top:1rem !important}.mr-sm-3,.mx-sm-3{margin-right:1rem !important}.mb-sm-3,.my-sm-3{margin-bottom:1rem !important}.ml-sm-3,.mx-sm-3{margin-left:1rem !important}.m-sm-4{margin:1.5rem !important}.mt-sm-4,.my-sm-4{margin-top:1.5rem !important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem !important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem !important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem !important}.m-sm-5{margin:3rem !important}.mt-sm-5,.my-sm-5{margin-top:3rem !important}.mr-sm-5,.mx-sm-5{margin-right:3rem !important}.mb-sm-5,.my-sm-5{margin-bottom:3rem !important}.ml-sm-5,.mx-sm-5{margin-left:3rem !important}.p-sm-0{padding:0 !important}.pt-sm-0,.py-sm-0{padding-top:0 !important}.pr-sm-0,.px-sm-0{padding-right:0 !important}.pb-sm-0,.py-sm-0{padding-bottom:0 !important}.pl-sm-0,.px-sm-0{padding-left:0 !important}.p-sm-1{padding:0.25rem !important}.pt-sm-1,.py-sm-1{padding-top:0.25rem !important}.pr-sm-1,.px-sm-1{padding-right:0.25rem !important}.pb-sm-1,.py-sm-1{padding-bottom:0.25rem !important}.pl-sm-1,.px-sm-1{padding-left:0.25rem !important}.p-sm-2{padding:0.5rem !important}.pt-sm-2,.py-sm-2{padding-top:0.5rem !important}.pr-sm-2,.px-sm-2{padding-right:0.5rem !important}.pb-sm-2,.py-sm-2{padding-bottom:0.5rem !important}.pl-sm-2,.px-sm-2{padding-left:0.5rem !important}.p-sm-3{padding:1rem !important}.pt-sm-3,.py-sm-3{padding-top:1rem !important}.pr-sm-3,.px-sm-3{padding-right:1rem !important}.pb-sm-3,.py-sm-3{padding-bottom:1rem !important}.pl-sm-3,.px-sm-3{padding-left:1rem !important}.p-sm-4{padding:1.5rem !important}.pt-sm-4,.py-sm-4{padding-top:1.5rem !important}.pr-sm-4,.px-sm-4{padding-right:1.5rem !important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem !important}.pl-sm-4,.px-sm-4{padding-left:1.5rem !important}.p-sm-5{padding:3rem !important}.pt-sm-5,.py-sm-5{padding-top:3rem !important}.pr-sm-5,.px-sm-5{padding-right:3rem !important}.pb-sm-5,.py-sm-5{padding-bottom:3rem !important}.pl-sm-5,.px-sm-5{padding-left:3rem !important}.m-sm-auto{margin:auto !important}.mt-sm-auto,.my-sm-auto{margin-top:auto !important}.mr-sm-auto,.mx-sm-auto{margin-right:auto !important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto !important}.ml-sm-auto,.mx-sm-auto{margin-left:auto !important}}@media (min-width: 768px){.m-md-0{margin:0 !important}.mt-md-0,.my-md-0{margin-top:0 !important}.mr-md-0,.mx-md-0{margin-right:0 !important}.mb-md-0,.my-md-0{margin-bottom:0 !important}.ml-md-0,.mx-md-0{margin-left:0 !important}.m-md-1{margin:0.25rem !important}.mt-md-1,.my-md-1{margin-top:0.25rem !important}.mr-md-1,.mx-md-1{margin-right:0.25rem !important}.mb-md-1,.my-md-1{margin-bottom:0.25rem !important}.ml-md-1,.mx-md-1{margin-left:0.25rem !important}.m-md-2{margin:0.5rem !important}.mt-md-2,.my-md-2{margin-top:0.5rem !important}.mr-md-2,.mx-md-2{margin-right:0.5rem !important}.mb-md-2,.my-md-2{margin-bottom:0.5rem !important}.ml-md-2,.mx-md-2{margin-left:0.5rem !important}.m-md-3{margin:1rem !important}.mt-md-3,.my-md-3{margin-top:1rem !important}.mr-md-3,.mx-md-3{margin-right:1rem !important}.mb-md-3,.my-md-3{margin-bottom:1rem !important}.ml-md-3,.mx-md-3{margin-left:1rem !important}.m-md-4{margin:1.5rem !important}.mt-md-4,.my-md-4{margin-top:1.5rem !important}.mr-md-4,.mx-md-4{margin-right:1.5rem !important}.mb-md-4,.my-md-4{margin-bottom:1.5rem !important}.ml-md-4,.mx-md-4{margin-left:1.5rem !important}.m-md-5{margin:3rem !important}.mt-md-5,.my-md-5{margin-top:3rem !important}.mr-md-5,.mx-md-5{margin-right:3rem !important}.mb-md-5,.my-md-5{margin-bottom:3rem !important}.ml-md-5,.mx-md-5{margin-left:3rem !important}.p-md-0{padding:0 !important}.pt-md-0,.py-md-0{padding-top:0 !important}.pr-md-0,.px-md-0{padding-right:0 !important}.pb-md-0,.py-md-0{padding-bottom:0 !important}.pl-md-0,.px-md-0{padding-left:0 !important}.p-md-1{padding:0.25rem !important}.pt-md-1,.py-md-1{padding-top:0.25rem !important}.pr-md-1,.px-md-1{padding-right:0.25rem !important}.pb-md-1,.py-md-1{padding-bottom:0.25rem !important}.pl-md-1,.px-md-1{padding-left:0.25rem !important}.p-md-2{padding:0.5rem !important}.pt-md-2,.py-md-2{padding-top:0.5rem !important}.pr-md-2,.px-md-2{padding-right:0.5rem !important}.pb-md-2,.py-md-2{padding-bottom:0.5rem !important}.pl-md-2,.px-md-2{padding-left:0.5rem !important}.p-md-3{padding:1rem !important}.pt-md-3,.py-md-3{padding-top:1rem !important}.pr-md-3,.px-md-3{padding-right:1rem !important}.pb-md-3,.py-md-3{padding-bottom:1rem !important}.pl-md-3,.px-md-3{padding-left:1rem !important}.p-md-4{padding:1.5rem !important}.pt-md-4,.py-md-4{padding-top:1.5rem !important}.pr-md-4,.px-md-4{padding-right:1.5rem !important}.pb-md-4,.py-md-4{padding-bottom:1.5rem !important}.pl-md-4,.px-md-4{padding-left:1.5rem !important}.p-md-5{padding:3rem !important}.pt-md-5,.py-md-5{padding-top:3rem !important}.pr-md-5,.px-md-5{padding-right:3rem !important}.pb-md-5,.py-md-5{padding-bottom:3rem !important}.pl-md-5,.px-md-5{padding-left:3rem !important}.m-md-auto{margin:auto !important}.mt-md-auto,.my-md-auto{margin-top:auto !important}.mr-md-auto,.mx-md-auto{margin-right:auto !important}.mb-md-auto,.my-md-auto{margin-bottom:auto !important}.ml-md-auto,.mx-md-auto{margin-left:auto !important}}@media (min-width: 992px){.m-lg-0{margin:0 !important}.mt-lg-0,.my-lg-0{margin-top:0 !important}.mr-lg-0,.mx-lg-0{margin-right:0 !important}.mb-lg-0,.my-lg-0{margin-bottom:0 !important}.ml-lg-0,.mx-lg-0{margin-left:0 !important}.m-lg-1{margin:0.25rem !important}.mt-lg-1,.my-lg-1{margin-top:0.25rem !important}.mr-lg-1,.mx-lg-1{margin-right:0.25rem !important}.mb-lg-1,.my-lg-1{margin-bottom:0.25rem !important}.ml-lg-1,.mx-lg-1{margin-left:0.25rem !important}.m-lg-2{margin:0.5rem !important}.mt-lg-2,.my-lg-2{margin-top:0.5rem !important}.mr-lg-2,.mx-lg-2{margin-right:0.5rem !important}.mb-lg-2,.my-lg-2{margin-bottom:0.5rem !important}.ml-lg-2,.mx-lg-2{margin-left:0.5rem !important}.m-lg-3{margin:1rem !important}.mt-lg-3,.my-lg-3{margin-top:1rem !important}.mr-lg-3,.mx-lg-3{margin-right:1rem !important}.mb-lg-3,.my-lg-3{margin-bottom:1rem !important}.ml-lg-3,.mx-lg-3{margin-left:1rem !important}.m-lg-4{margin:1.5rem !important}.mt-lg-4,.my-lg-4{margin-top:1.5rem !important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem !important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem !important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem !important}.m-lg-5{margin:3rem !important}.mt-lg-5,.my-lg-5{margin-top:3rem !important}.mr-lg-5,.mx-lg-5{margin-right:3rem !important}.mb-lg-5,.my-lg-5{margin-bottom:3rem !important}.ml-lg-5,.mx-lg-5{margin-left:3rem !important}.p-lg-0{padding:0 !important}.pt-lg-0,.py-lg-0{padding-top:0 !important}.pr-lg-0,.px-lg-0{padding-right:0 !important}.pb-lg-0,.py-lg-0{padding-bottom:0 !important}.pl-lg-0,.px-lg-0{padding-left:0 !important}.p-lg-1{padding:0.25rem !important}.pt-lg-1,.py-lg-1{padding-top:0.25rem !important}.pr-lg-1,.px-lg-1{padding-right:0.25rem !important}.pb-lg-1,.py-lg-1{padding-bottom:0.25rem !important}.pl-lg-1,.px-lg-1{padding-left:0.25rem !important}.p-lg-2{padding:0.5rem !important}.pt-lg-2,.py-lg-2{padding-top:0.5rem !important}.pr-lg-2,.px-lg-2{padding-right:0.5rem !important}.pb-lg-2,.py-lg-2{padding-bottom:0.5rem !important}.pl-lg-2,.px-lg-2{padding-left:0.5rem !important}.p-lg-3{padding:1rem !important}.pt-lg-3,.py-lg-3{padding-top:1rem !important}.pr-lg-3,.px-lg-3{padding-right:1rem !important}.pb-lg-3,.py-lg-3{padding-bottom:1rem !important}.pl-lg-3,.px-lg-3{padding-left:1rem !important}.p-lg-4{padding:1.5rem !important}.pt-lg-4,.py-lg-4{padding-top:1.5rem !important}.pr-lg-4,.px-lg-4{padding-right:1.5rem !important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem !important}.pl-lg-4,.px-lg-4{padding-left:1.5rem !important}.p-lg-5{padding:3rem !important}.pt-lg-5,.py-lg-5{padding-top:3rem !important}.pr-lg-5,.px-lg-5{padding-right:3rem !important}.pb-lg-5,.py-lg-5{padding-bottom:3rem !important}.pl-lg-5,.px-lg-5{padding-left:3rem !important}.m-lg-auto{margin:auto !important}.mt-lg-auto,.my-lg-auto{margin-top:auto !important}.mr-lg-auto,.mx-lg-auto{margin-right:auto !important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto !important}.ml-lg-auto,.mx-lg-auto{margin-left:auto !important}}@media (min-width: 1200px){.m-xl-0{margin:0 !important}.mt-xl-0,.my-xl-0{margin-top:0 !important}.mr-xl-0,.mx-xl-0{margin-right:0 !important}.mb-xl-0,.my-xl-0{margin-bottom:0 !important}.ml-xl-0,.mx-xl-0{margin-left:0 !important}.m-xl-1{margin:0.25rem !important}.mt-xl-1,.my-xl-1{margin-top:0.25rem !important}.mr-xl-1,.mx-xl-1{margin-right:0.25rem !important}.mb-xl-1,.my-xl-1{margin-bottom:0.25rem !important}.ml-xl-1,.mx-xl-1{margin-left:0.25rem !important}.m-xl-2{margin:0.5rem !important}.mt-xl-2,.my-xl-2{margin-top:0.5rem !important}.mr-xl-2,.mx-xl-2{margin-right:0.5rem !important}.mb-xl-2,.my-xl-2{margin-bottom:0.5rem !important}.ml-xl-2,.mx-xl-2{margin-left:0.5rem !important}.m-xl-3{margin:1rem !important}.mt-xl-3,.my-xl-3{margin-top:1rem !important}.mr-xl-3,.mx-xl-3{margin-right:1rem !important}.mb-xl-3,.my-xl-3{margin-bottom:1rem !important}.ml-xl-3,.mx-xl-3{margin-left:1rem !important}.m-xl-4{margin:1.5rem !important}.mt-xl-4,.my-xl-4{margin-top:1.5rem !important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem !important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem !important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem !important}.m-xl-5{margin:3rem !important}.mt-xl-5,.my-xl-5{margin-top:3rem !important}.mr-xl-5,.mx-xl-5{margin-right:3rem !important}.mb-xl-5,.my-xl-5{margin-bottom:3rem !important}.ml-xl-5,.mx-xl-5{margin-left:3rem !important}.p-xl-0{padding:0 !important}.pt-xl-0,.py-xl-0{padding-top:0 !important}.pr-xl-0,.px-xl-0{padding-right:0 !important}.pb-xl-0,.py-xl-0{padding-bottom:0 !important}.pl-xl-0,.px-xl-0{padding-left:0 !important}.p-xl-1{padding:0.25rem !important}.pt-xl-1,.py-xl-1{padding-top:0.25rem !important}.pr-xl-1,.px-xl-1{padding-right:0.25rem !important}.pb-xl-1,.py-xl-1{padding-bottom:0.25rem !important}.pl-xl-1,.px-xl-1{padding-left:0.25rem !important}.p-xl-2{padding:0.5rem !important}.pt-xl-2,.py-xl-2{padding-top:0.5rem !important}.pr-xl-2,.px-xl-2{padding-right:0.5rem !important}.pb-xl-2,.py-xl-2{padding-bottom:0.5rem !important}.pl-xl-2,.px-xl-2{padding-left:0.5rem !important}.p-xl-3{padding:1rem !important}.pt-xl-3,.py-xl-3{padding-top:1rem !important}.pr-xl-3,.px-xl-3{padding-right:1rem !important}.pb-xl-3,.py-xl-3{padding-bottom:1rem !important}.pl-xl-3,.px-xl-3{padding-left:1rem !important}.p-xl-4{padding:1.5rem !important}.pt-xl-4,.py-xl-4{padding-top:1.5rem !important}.pr-xl-4,.px-xl-4{padding-right:1.5rem !important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem !important}.pl-xl-4,.px-xl-4{padding-left:1.5rem !important}.p-xl-5{padding:3rem !important}.pt-xl-5,.py-xl-5{padding-top:3rem !important}.pr-xl-5,.px-xl-5{padding-right:3rem !important}.pb-xl-5,.py-xl-5{padding-bottom:3rem !important}.pl-xl-5,.px-xl-5{padding-left:3rem !important}.m-xl-auto{margin:auto !important}.mt-xl-auto,.my-xl-auto{margin-top:auto !important}.mr-xl-auto,.mx-xl-auto{margin-right:auto !important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto !important}.ml-xl-auto,.mx-xl-auto{margin-left:auto !important}}.visible{visibility:visible !important}.invisible{visibility:hidden !important} diff --git a/css/milestones.scss b/css/milestones.scss index d76c6557b..74c8c11e3 100644 --- a/css/milestones.scss +++ b/css/milestones.scss @@ -2,4 +2,4 @@ position: fixed; padding: 6px; width: 60%; -} \ No newline at end of file +} diff --git a/css/redpill.scss b/css/redpill.scss index 1811b8b91..7bcedc6a6 100644 --- a/css/redpill.scss +++ b/css/redpill.scss @@ -17,7 +17,7 @@ } &.level-2 { - color: #48D1CC; + color: #48d1cc; } &.level-3 { diff --git a/css/resleeving.scss b/css/resleeving.scss index d728013cf..37873377a 100644 --- a/css/resleeving.scss +++ b/css/resleeving.scss @@ -1,4 +1,4 @@ - /** +/** * Styling for the Re-Sleeving Page */ @import "theme"; @@ -15,7 +15,7 @@ .resleeve-panel { display: inline-block; - margin: 0px; + margin: 0; padding: 2px; } diff --git a/css/sleeves.scss b/css/sleeves.scss index 9ef3d601c..ffea27ba9 100644 --- a/css/sleeves.scss +++ b/css/sleeves.scss @@ -20,7 +20,7 @@ .sleeve-panel { display: inline-block; - margin: 0px; + margin: 0; padding: 2px; select { diff --git a/css/styles.scss b/css/styles.scss index c093908f5..a6c98b897 100644 --- a/css/styles.scss +++ b/css/styles.scss @@ -375,7 +375,7 @@ a:visited { } .noscrollbar::-webkit-scrollbar { - display: none; + display: none; } input[type=checkbox] { @@ -383,42 +383,42 @@ input[type=checkbox] { } .optionCheckbox { - margin: 5px; - float: right; + margin: 5px; + float: right; } .optionRange { - -webkit-appearance: none; - background: #777; - outline: none; - opacity: 0.7; - height: 10px; - -webkit-transition: .2s; - transition: opacity .2s; - margin: 3px; + -webkit-appearance: none; + background: #777; + outline: none; + opacity: 0.7; + height: 10px; + -webkit-transition: 0.2s; + transition: opacity 0.2s; + margin: 3px; } .optionRange::-webkit-slider-thumb { - -webkit-appearance: none; - appearance: none; - width: 10px; - height: 10px; - background: var(--my-font-color); - cursor: pointer; + -webkit-appearance: none; + appearance: none; + width: 10px; + height: 10px; + background: var(--my-font-color); + cursor: pointer; } .optionRange::-moz-range-thumb { - width: 10px; - height: 10px; - background: var(--my-font-color); - cursor: pointer; + width: 10px; + height: 10px; + background: var(--my-font-color); + cursor: pointer; } .noselect { - -moz-user-select: -moz-none; - -khtml-user-select: none; - -webkit-user-select: none; - -ms-user-select: none; - user-select: none; -} \ No newline at end of file + -moz-user-select: -moz-none; + -khtml-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; +} diff --git a/css/tooltips.scss b/css/tooltips.scss index 4f58842d5..8a5971918 100644 --- a/css/tooltips.scss +++ b/css/tooltips.scss @@ -35,7 +35,7 @@ left: 50%; transform: translate(-100%, -100%); - /* Backwards compatibility */ + /* Backwards compatibility */ -webkit-transform: translate(-100%, -100%); -moz-transform: translate(-100%, -100%); -o-transform: translate(-100%, -100%); @@ -126,4 +126,4 @@ visibility: visible; opacity: 1; transition: opacity 0.3s; -} \ No newline at end of file +} diff --git a/css/treant.css b/css/treant.css index d4e6c73dc..38917ce34 100644 --- a/css/treant.css +++ b/css/treant.css @@ -7,16 +7,16 @@ .Treant.Treant-loaded .pseudo { visibility: visible; } .Treant > .pseudo { width: 0; height: 0; border: none; padding: 0; } .Treant .collapse-switch { width: 3px; height: 3px; display: block; border: 1px solid black; position: absolute; top: 1px; right: 1px; cursor: pointer; } -.Treant .collapsed .collapse-switch { background-color: #868DEE; } +.Treant .collapsed .collapse-switch { background-color: #868dee; } .Treant > .node img { border: none; float: left; } .Treant > .node { cursor: pointer; - padding: 4px; - min-width: 60px; - text-align: center; - border: 2px solid #E8E8E3; - border-radius: 2px; - box-shadow: 1px 1px 1px rgba(0,0,0,.5); + padding: 4px; + min-width: 60px; + text-align: center; + border: 2px solid #e8e8e3; + border-radius: 2px; + box-shadow: 1px 1px 1px rgba(0,0,0,0.5); font-size: 12px; } diff --git a/package.json b/package.json index c424d5095..44b6b16ea 100644 --- a/package.json +++ b/package.json @@ -117,8 +117,8 @@ "build:dev": "webpack --mode development", "build:test": "webpack --config webpack.config-test.js", "lint": "npm run lint:jsts & npm run lint:style", - "lint:jsts": "eslint '*.{js,jsx,ts,tsx}' './src/**/*.{js,jsx,ts,tsx}' './test/**/*.{js,jsx,ts,tsx}' './utils/**/*.{js,jsx,ts,tsx}'", - "lint:style": "stylelint ./css/*", + "lint:jsts": "eslint --fix '*.{js,jsx,ts,tsx}' './src/**/*.{js,jsx,ts,tsx}' './test/**/*.{js,jsx,ts,tsx}' './utils/**/*.{js,jsx,ts,tsx}'", + "lint:style": "stylelint --fix ./css/*", "preinstall": "node ./scripts/engines-check.js", "test": "mochapack --webpack-config webpack.config-test.js -r jsdom-global/register ./test/index.js", "watch": "webpack --watch --mode production", diff --git a/src/Alias.ts b/src/Alias.ts index 5d1b11357..91c5dd96d 100644 --- a/src/Alias.ts +++ b/src/Alias.ts @@ -22,12 +22,12 @@ export function loadGlobalAliases(saveString: string): void { // Prints all aliases to terminal export function printAliases(): void { - for (var name in Aliases) { + for (const name in Aliases) { if (Aliases.hasOwnProperty(name)) { post("alias " + name + "=" + Aliases[name]); } } - for (var name in GlobalAliases) { + for (const name in GlobalAliases) { if (GlobalAliases.hasOwnProperty(name)) { post("global alias " + name + "=" + GlobalAliases[name]); } @@ -36,8 +36,8 @@ export function printAliases(): void { // Returns true if successful, false otherwise export function parseAliasDeclaration(dec: string, global = false): boolean { - var re = /^([_|\w|!|%|,|@]+)="(.+)"$/; - var matches = dec.match(re); + const re = /^([_|\w|!|%|,|@]+)="(.+)"$/; + const matches = dec.match(re); if (matches == null || matches.length != 3) {return false;} if (global){ addGlobalAlias(matches[1],matches[2]); @@ -100,17 +100,17 @@ export function substituteAliases(origCommand: string): string { // For the unalias command, dont substite if (commandArray[0] === "unalias") { return commandArray.join(" "); } - var alias = getAlias(commandArray[0]); + const alias = getAlias(commandArray[0]); if (alias != null) { commandArray[0] = alias; } else { - var alias = getGlobalAlias(commandArray[0]); + const alias = getGlobalAlias(commandArray[0]); if (alias != null) { commandArray[0] = alias; } } - for (var i = 0; i < commandArray.length; ++i) { - var alias = getGlobalAlias(commandArray[i]); + for (let i = 0; i < commandArray.length; ++i) { + const alias = getGlobalAlias(commandArray[i]); if (alias != null) { commandArray[i] = alias; } diff --git a/src/Augmentation/Augmentation.ts b/src/Augmentation/Augmentation.ts index 509a61475..e1597038f 100644 --- a/src/Augmentation/Augmentation.ts +++ b/src/Augmentation/Augmentation.ts @@ -49,31 +49,27 @@ interface IConstructorParams { } export class Augmentation { - // Initiatizes a Augmentation object from a JSON save state. - static fromJSON(value: any): Augmentation { - return Generic_fromJSON(Augmentation, value.data); - } // How much money this costs to buy - baseCost: number = 0; + baseCost = 0; // How much faction reputation is required to unlock this - baseRepRequirement: number = 0; + baseRepRequirement = 0; // Description of what this Aug is and what it does - info: string = ""; + info = ""; // Any Augmentation not immediately available in BitNode-1 is special (e.g. Bladeburner augs) - isSpecial: boolean = false; + isSpecial = false; // Augmentation level - for repeatable Augs like NeuroFlux Governor - level: number = 0; + level = 0; // Name of Augmentation - name: string = ""; + name = ""; // Whether the player owns this Augmentation - owned: boolean = false; + owned = false; // Array of names of all prerequisites prereqs: string[] = []; @@ -83,7 +79,7 @@ export class Augmentation { mults: IMap = {} // Initial cost. Doesn't change when you purchase multiple Augmentation - startingCost: number = 0; + startingCost = 0; constructor(params: IConstructorParams={ info: "", moneyCost: 0, name: "", repCost: 0 }) { this.name = params.name; @@ -141,7 +137,7 @@ export class Augmentation { console.warn(`In Augmentation.addToFactions(), could not find faction with this name: ${factionList[i]}`); continue; } - faction!.augmentations.push(this.name); + faction.augmentations.push(this.name); } } @@ -154,7 +150,7 @@ export class Augmentation { console.warn(`Invalid Faction object in addToAllFactions(). Key value: ${fac}`); continue; } - facObj!.augmentations.push(this.name); + facObj.augmentations.push(this.name); } } } @@ -163,6 +159,12 @@ export class Augmentation { toJSON(): any { return Generic_toJSON("Augmentation", this); } + + // Initiatizes a Augmentation object from a JSON save state. + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types + static fromJSON(value: any): Augmentation { + return Generic_fromJSON(Augmentation, value.data); + } } Reviver.constructors.Augmentation = Augmentation; diff --git a/src/Augmentation/AugmentationHelpers.jsx b/src/Augmentation/AugmentationHelpers.jsx index 0fc8cd6bc..3db94a334 100644 --- a/src/Augmentation/AugmentationHelpers.jsx +++ b/src/Augmentation/AugmentationHelpers.jsx @@ -8,29 +8,13 @@ import { AugmentationsRoot } from "./ui/Root"; import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; import { CONSTANTS } from "../Constants"; import { Factions, factionExists } from "../Faction/Factions"; -import { startWorkerScript } from "../NetscriptWorker"; import { Player } from "../Player"; import { prestigeAugmentation } from "../Prestige"; import { saveObject } from "../SaveObject"; -import { RunningScript } from "../Script/RunningScript"; -import { Script } from "../Script/Script"; -import { Server } from "../Server/Server"; -import { OwnedAugmentationsOrderSetting } from "../Settings/SettingEnums"; -import { Settings } from "../Settings/Settings"; import { Page, routing } from "../ui/navigationTracking"; import { dialogBoxCreate } from "../../utils/DialogBox"; -import { createAccordionElement } from "../../utils/uiHelpers/createAccordionElement"; -import { - Reviver, - Generic_toJSON, - Generic_fromJSON -} from "../../utils/JSONReviver"; -import { formatNumber } from "../../utils/StringHelperFunctions"; import { clearObject } from "../../utils/helpers/clearObject"; -import { createElement } from "../../utils/uiHelpers/createElement"; -import { isString } from "../../utils/helpers/isString"; -import { removeChildrenFromElement } from "../../utils/uiHelpers/removeChildrenFromElement"; import { Money } from "../ui/React/Money"; import React from "react"; @@ -1256,7 +1240,7 @@ function initAugmentations() { // Daedalus const RedPill = new Augmentation({ name:AugmentationNames.TheRedPill, repCost:1e6, moneyCost:0, - info:"It's time to leave the cave." + info:"It's time to leave the cave.", }); RedPill.addToFactions(["Daedalus"]); if (augmentationExists(AugmentationNames.TheRedPill)) { @@ -1556,7 +1540,7 @@ function initAugmentations() { and upload the assets.

This augmentation:
Lets the player start with {Money(1e6)} after a reset.
- Lets the player start with the BruteSSH.exe program after a reset. + Lets the player start with the BruteSSH.exe program after a reset., }); CashRoot.addToFactions(["Sector-12"]); if (augmentationExists(AugmentationNames.CashRoot)) { @@ -2098,7 +2082,7 @@ export function displayAugmentationsContent(contentEl) { exportGameFn={saveObject.exportGame.bind(saveObject)} installAugmentationsFn={installAugmentations} />, - contentEl + contentEl, ); } diff --git a/src/Augmentation/Augmentations.ts b/src/Augmentation/Augmentations.ts index 229a17443..ed2eab639 100644 --- a/src/Augmentation/Augmentations.ts +++ b/src/Augmentation/Augmentations.ts @@ -1,4 +1,4 @@ import { Augmentation } from "./Augmentation"; import { IMap } from "../types"; -export let Augmentations: IMap = {}; +export const Augmentations: IMap = {}; diff --git a/src/Augmentation/PlayerOwnedAugmentation.ts b/src/Augmentation/PlayerOwnedAugmentation.ts index 2455c09f8..635c9f5b2 100644 --- a/src/Augmentation/PlayerOwnedAugmentation.ts +++ b/src/Augmentation/PlayerOwnedAugmentation.ts @@ -1,8 +1,8 @@ export class PlayerOwnedAugmentation { - level: number = 1; - name: string = ""; + level = 1; + name = ""; - constructor(name: string = "") { + constructor(name = "") { this.name = name; } } diff --git a/src/Augmentation/data/AugmentationNames.ts b/src/Augmentation/data/AugmentationNames.ts index ef8c6252c..2c681008d 100644 --- a/src/Augmentation/data/AugmentationNames.ts +++ b/src/Augmentation/data/AugmentationNames.ts @@ -1,6 +1,6 @@ import { IMap } from "../../types"; -export let AugmentationNames: IMap = { +export const AugmentationNames: IMap = { Targeting1: "Augmented Targeting I", Targeting2: "Augmented Targeting II", Targeting3: "Augmented Targeting III", diff --git a/src/Augmentation/ui/InstalledAugmentationsAndSourceFiles.tsx b/src/Augmentation/ui/InstalledAugmentationsAndSourceFiles.tsx index 35bf07ba8..a10783a49 100644 --- a/src/Augmentation/ui/InstalledAugmentationsAndSourceFiles.tsx +++ b/src/Augmentation/ui/InstalledAugmentationsAndSourceFiles.tsx @@ -15,7 +15,9 @@ import { SourceFileMinus1 } from "./SourceFileMinus1"; import { Settings } from "../../Settings/Settings"; import { OwnedAugmentationsOrderSetting } from "../../Settings/SettingEnums"; -type IProps = {} +type IProps = { + // nothing special. +} type IState = { rerenderFlag: boolean; @@ -39,7 +41,7 @@ export class InstalledAugmentationsAndSourceFiles extends React.Component { return { rerenderFlag: !prevState.rerenderFlag, @@ -79,17 +81,17 @@ export class InstalledAugmentationsAndSourceFiles extends React.Component  {"=>"} , - {numeralWrapper.formatPercentage(r)} + {numeralWrapper.formatPercentage(r)}, ]; } return elems; @@ -51,38 +51,38 @@ export function PlayerMultipliers(): React.ReactElement { ['Hacking Chance ', Player.hacking_chance_mult, Player.hacking_chance_mult*mults.hacking_chance_mult], ['Hacking Speed ', Player.hacking_speed_mult, Player.hacking_speed_mult*mults.hacking_speed_mult], ['Hacking Money ', Player.hacking_money_mult, Player.hacking_money_mult*mults.hacking_money_mult], - ['Hacking Growth ', Player.hacking_grow_mult, Player.hacking_grow_mult*mults.hacking_grow_mult] + ['Hacking Growth ', Player.hacking_grow_mult, Player.hacking_grow_mult*mults.hacking_grow_mult], ])}
{MultiplierTable([ ['Hacking Level ', Player.hacking_mult, Player.hacking_mult*mults.hacking_mult], - ['Hacking Experience ', Player.hacking_exp_mult, Player.hacking_exp_mult*mults.hacking_exp_mult] + ['Hacking Experience ', Player.hacking_exp_mult, Player.hacking_exp_mult*mults.hacking_exp_mult], ])}
{MultiplierTable([ ['Strength Level ', Player.strength_mult, Player.strength_mult*mults.strength_mult], - ['Strength Experience ', Player.strength_exp_mult, Player.strength_exp_mult*mults.strength_exp_mult] + ['Strength Experience ', Player.strength_exp_mult, Player.strength_exp_mult*mults.strength_exp_mult], ])}
{MultiplierTable([ ['Defense Level ', Player.defense_mult, Player.defense_mult*mults.defense_mult], - ['Defense Experience ', Player.defense_exp_mult, Player.defense_exp_mult*mults.defense_exp_mult] + ['Defense Experience ', Player.defense_exp_mult, Player.defense_exp_mult*mults.defense_exp_mult], ])}
{MultiplierTable([ ['Dexterity Level ', Player.dexterity_mult, Player.dexterity_mult*mults.dexterity_mult], - ['Dexterity Experience ', Player.dexterity_exp_mult, Player.dexterity_exp_mult*mults.dexterity_exp_mult] + ['Dexterity Experience ', Player.dexterity_exp_mult, Player.dexterity_exp_mult*mults.dexterity_exp_mult], ])}
{MultiplierTable([ ['Agility Level ', Player.agility_mult, Player.agility_mult*mults.agility_mult], - ['Agility Experience ', Player.agility_exp_mult, Player.agility_exp_mult*mults.agility_exp_mult] + ['Agility Experience ', Player.agility_exp_mult, Player.agility_exp_mult*mults.agility_exp_mult], ])}
{MultiplierTable([ ['Charisma Level ', Player.charisma_mult, Player.charisma_mult*mults.charisma_mult], - ['Charisma Experience ', Player.charisma_exp_mult, Player.charisma_exp_mult*mults.charisma_exp_mult] + ['Charisma Experience ', Player.charisma_exp_mult, Player.charisma_exp_mult*mults.charisma_exp_mult], ])}
{MultiplierTable([ @@ -90,13 +90,13 @@ export function PlayerMultipliers(): React.ReactElement { ['Hacknet Node purchase cost ', Player.hacknet_node_purchase_cost_mult, Player.hacknet_node_purchase_cost_mult*mults.hacknet_node_purchase_cost_mult], ['Hacknet Node RAM upgrade cost ', Player.hacknet_node_ram_cost_mult, Player.hacknet_node_ram_cost_mult*mults.hacknet_node_ram_cost_mult], ['Hacknet Node Core purchase cost ', Player.hacknet_node_core_cost_mult, Player.hacknet_node_core_cost_mult*mults.hacknet_node_core_cost_mult], - ['Hacknet Node level upgrade cost ', Player.hacknet_node_level_cost_mult, Player.hacknet_node_level_cost_mult*mults.hacknet_node_level_cost_mult] + ['Hacknet Node level upgrade cost ', Player.hacknet_node_level_cost_mult, Player.hacknet_node_level_cost_mult*mults.hacknet_node_level_cost_mult], ])}
{MultiplierTable([ ['Company reputation gain ', Player.company_rep_mult, Player.company_rep_mult*mults.company_rep_mult], ['Faction reputation gain ', Player.faction_rep_mult, Player.faction_rep_mult*mults.faction_rep_mult], - ['Salary ', Player.work_money_mult, Player.work_money_mult*mults.work_money_mult] + ['Salary ', Player.work_money_mult, Player.work_money_mult*mults.work_money_mult], ])}
{MultiplierTable([ diff --git a/src/Augmentation/ui/PurchasedAugmentations.tsx b/src/Augmentation/ui/PurchasedAugmentations.tsx index 3bc54d837..ab0854e9a 100644 --- a/src/Augmentation/ui/PurchasedAugmentations.tsx +++ b/src/Augmentation/ui/PurchasedAugmentations.tsx @@ -22,7 +22,7 @@ export function PurchasedAugmentations(): React.ReactElement { augs.push(
  • -
  • + , ) } diff --git a/src/Augmentation/ui/Root.tsx b/src/Augmentation/ui/Root.tsx index 10e733556..d9350836c 100644 --- a/src/Augmentation/ui/Root.tsx +++ b/src/Augmentation/ui/Root.tsx @@ -25,7 +25,7 @@ export class AugmentationsRoot extends React.Component { super(props); } - render() { + render(): React.ReactNode { return (

    Purchased Augmentations

    diff --git a/src/Augmentation/ui/SourceFileMinus1.tsx b/src/Augmentation/ui/SourceFileMinus1.tsx index b97bcbf40..817c3250f 100644 --- a/src/Augmentation/ui/SourceFileMinus1.tsx +++ b/src/Augmentation/ui/SourceFileMinus1.tsx @@ -5,15 +5,12 @@ import * as React from "react"; import { Player } from "../../Player"; -import { Settings } from "../../Settings/Settings"; -import { OwnedAugmentationsOrderSetting } from "../../Settings/SettingEnums"; -import { SourceFiles } from "../../SourceFile/SourceFiles"; import { Exploit, ExploitName } from "../../Exploits/Exploit"; import { Accordion } from "../../ui/React/Accordion"; export function SourceFileMinus1(): React.ReactElement { - let exploits = Player.exploits; + const exploits = Player.exploits; if(exploits.length === 0) { return <> diff --git a/src/BitNode/BitNode.ts b/src/BitNode/BitNode.ts index 42d937351..ed86041cc 100644 --- a/src/BitNode/BitNode.ts +++ b/src/BitNode/BitNode.ts @@ -16,7 +16,7 @@ class BitNode { number: number; - constructor(n: number, name: string, desc: string="", info: string="") { + constructor(n: number, name: string, desc="", info="") { this.number = n; this.name = name; this.desc = desc; @@ -252,11 +252,11 @@ BitNodes["BitNode22"] = new BitNode(22, "", "COMING SOON"); BitNodes["BitNode23"] = new BitNode(23, "", "COMING SOON"); BitNodes["BitNode24"] = new BitNode(24, "", "COMING SOON"); -export function initBitNodeMultipliers(p: IPlayer) { +export function initBitNodeMultipliers(p: IPlayer): void { if (p.bitNodeN == null) { p.bitNodeN = 1; } - for (var mult in BitNodeMultipliers) { + for (const mult in BitNodeMultipliers) { if (BitNodeMultipliers.hasOwnProperty(mult)) { BitNodeMultipliers[mult] = 1; } @@ -433,15 +433,15 @@ export function initBitNodeMultipliers(p: IPlayer) { BitNodeMultipliers.FourSigmaMarketDataCost = 4; BitNodeMultipliers.FourSigmaMarketDataApiCost = 4; break; - case 12: //The Recursion - var sf12Lvl = 0; - for (var i = 0; i < p.sourceFiles.length; i++) { + case 12: { //The Recursion + let sf12Lvl = 0; + for (let i = 0; i < p.sourceFiles.length; i++) { if (p.sourceFiles[i].n === 12) { sf12Lvl = p.sourceFiles[i].lvl; } } - var inc = Math.pow(1.02, sf12Lvl); - var dec = 1/inc; + const inc = Math.pow(1.02, sf12Lvl); + const dec = 1/inc; // Multiplier for number of augs needed for Daedalus increases // up to a maximum of 1.34, which results in 40 Augs required @@ -499,6 +499,7 @@ export function initBitNodeMultipliers(p: IPlayer) { BitNodeMultipliers.BladeburnerRank = dec; BitNodeMultipliers.BladeburnerSkillCost = inc; break; + } default: console.warn("Player.bitNodeN invalid"); break; diff --git a/src/Bladeburner.jsx b/src/Bladeburner.jsx index a32d251d0..f786d5d96 100644 --- a/src/Bladeburner.jsx +++ b/src/Bladeburner.jsx @@ -1,7 +1,6 @@ import { Augmentations } from "./Augmentation/Augmentations"; import { AugmentationNames } from "./Augmentation/data/AugmentationNames"; import { BitNodeMultipliers } from "./BitNode/BitNodeMultipliers"; -import { CONSTANTS } from "./Constants"; import { Engine } from "./engine"; import { Faction } from "./Faction/Faction"; import { Factions, factionExists } from "./Faction/Factions"; @@ -17,17 +16,19 @@ import { dialogBoxCreate } from "../utils/DialogBox"; import { Reviver, Generic_toJSON, - Generic_fromJSON + Generic_fromJSON, } from "../utils/JSONReviver"; import { setTimeoutRef } from "./utils/SetTimeoutRef"; -import { formatNumber } from "../utils/StringHelperFunctions"; +import { + formatNumber, + convertTimeMsToTimeElapsedString, +} from "../utils/StringHelperFunctions"; import { ConsoleHelpText } from "./Bladeburner/data/Help"; import { City } from "./Bladeburner/City"; import { BladeburnerConstants } from "./Bladeburner/data/Constants"; import { Skill } from "./Bladeburner/Skill"; import { Skills } from "./Bladeburner/Skills"; -import { SkillNames } from "./Bladeburner/data/SkillNames"; import { Operation } from "./Bladeburner/Operation"; import { BlackOperation } from "./Bladeburner/BlackOperation"; import { BlackOperations } from "./Bladeburner/BlackOperations"; @@ -45,7 +46,6 @@ import { KEY } from "../utils/helpers/keyCodes"; import { removeChildrenFromElement } from "../utils/uiHelpers/removeChildrenFromElement"; import { appendLineBreaks } from "../utils/uiHelpers/appendLineBreaks"; -import { convertTimeMsToTimeElapsedString } from "../utils/StringHelperFunctions"; import { createElement } from "../utils/uiHelpers/createElement"; import { createPopup } from "../utils/uiHelpers/createPopup"; import { removeElement } from "../utils/uiHelpers/removeElement"; @@ -236,7 +236,7 @@ Bladeburner.prototype.create = function() { count:getRandomInt(25, 150), countGrowth:getRandomInt(5, 75)/10, weights:{hack:0,str:0.05,def:0.05,dex:0.35,agi:0.35,cha:0.1, int:0.05}, decays:{hack:0,str:0.91,def:0.91,dex:0.91,agi:0.91,cha:0.9, int:1}, - isStealth:true + isStealth:true, }); this.contracts["Bounty Hunter"] = new Contract({ name:"Bounty Hunter", @@ -248,7 +248,7 @@ Bladeburner.prototype.create = function() { count:getRandomInt(5, 150), countGrowth:getRandomInt(5, 75)/10, weights:{hack:0,str:0.15,def:0.15,dex:0.25,agi:0.25,cha:0.1, int:0.1}, decays:{hack:0,str:0.91,def:0.91,dex:0.91,agi:0.91,cha:0.8, int:0.9}, - isKill:true + isKill:true, }); this.contracts["Retirement"] = new Contract({ name:"Retirement", @@ -260,7 +260,7 @@ Bladeburner.prototype.create = function() { count:getRandomInt(5, 150), countGrowth:getRandomInt(5, 75)/10, weights:{hack:0,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0.1, int:0.1}, decays:{hack:0,str:0.91,def:0.91,dex:0.91,agi:0.91,cha:0.8, int:0.9}, - isKill:true + isKill:true, }); this.operations["Investigation"] = new Operation({ @@ -275,7 +275,7 @@ Bladeburner.prototype.create = function() { count:getRandomInt(1, 100), countGrowth:getRandomInt(10, 40)/10, weights:{hack:0.25,str:0.05,def:0.05,dex:0.2,agi:0.1,cha:0.25, int:0.1}, decays:{hack:0.85,str:0.9,def:0.9,dex:0.9,agi:0.9,cha:0.7, int:0.9}, - isStealth:true + isStealth:true, }); this.operations["Undercover Operation"] = new Operation({ name:"Undercover Operation", @@ -288,7 +288,7 @@ Bladeburner.prototype.create = function() { count:getRandomInt(1, 100), countGrowth:getRandomInt(10, 40)/10, weights:{hack:0.2,str:0.05,def:0.05,dex:0.2,agi:0.2,cha:0.2, int:0.1}, decays:{hack:0.8,str:0.9,def:0.9,dex:0.9,agi:0.9,cha:0.7, int:0.9}, - isStealth:true + isStealth:true, }); this.operations["Sting Operation"] = new Operation({ name:"Sting Operation", @@ -299,7 +299,7 @@ Bladeburner.prototype.create = function() { count:getRandomInt(1, 150), countGrowth:getRandomInt(3, 40)/10, weights:{hack:0.25,str:0.05,def:0.05,dex:0.25,agi:0.1,cha:0.2, int:0.1}, decays:{hack:0.8,str:0.85,def:0.85,dex:0.85,agi:0.85,cha:0.7, int:0.9}, - isStealth:true + isStealth:true, }); this.operations["Raid"] = new Operation({ name:"Raid", @@ -311,7 +311,7 @@ Bladeburner.prototype.create = function() { count:getRandomInt(1, 150), countGrowth:getRandomInt(2, 40)/10, weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1}, decays:{hack:0.7,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.9}, - isKill:true + isKill:true, }); this.operations["Stealth Retirement Operation"] = new Operation({ name:"Stealth Retirement Operation", @@ -323,7 +323,7 @@ Bladeburner.prototype.create = function() { count:getRandomInt(1, 150), countGrowth:getRandomInt(1, 20)/10, weights:{hack:0.1,str:0.1,def:0.1,dex:0.3,agi:0.3,cha:0, int:0.1}, decays:{hack:0.7,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.9}, - isStealth:true, isKill:true + isStealth:true, isKill:true, }); this.operations["Assassination"] = new Operation({ name:"Assassination", @@ -335,7 +335,7 @@ Bladeburner.prototype.create = function() { count:getRandomInt(1, 150), countGrowth:getRandomInt(1, 20)/10, weights:{hack:0.1,str:0.1,def:0.1,dex:0.3,agi:0.3,cha:0, int:0.1}, decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.8}, - isStealth:true, isKill:true + isStealth:true, isKill:true, }); } @@ -1271,7 +1271,7 @@ Bladeburner.prototype.createContent = function() { DomElems.consoleInput.focus(); } return false; - } + }, }); DomElems.consoleTable = createElement("table", {class:"bladeburner-console-table"}); DomElems.consoleInputRow = createElement("tr", {class:"bladeburner-console-input-row", id:"bladeburner-console-input-row"}); @@ -1279,7 +1279,7 @@ Bladeburner.prototype.createContent = function() { DomElems.consoleInputHeader = createElement("pre", {innerText:"> "}); DomElems.consoleInput = createElement("input", { type:"text", class:"bladeburner-console-input", tabIndex:1, - onfocus:() => {DomElems.consoleInput.value = DomElems.consoleInput.value} + onfocus:() => {DomElems.consoleInput.value = DomElems.consoleInput.value}, }); DomElems.consoleInputCell.appendChild(DomElems.consoleInputHeader); @@ -1363,7 +1363,7 @@ Bladeburner.prototype.createOverviewContent = function() { innerText:"Est. Synthoid Population: ", display:"inline-block", tooltip:"This is your Bladeburner division's estimate of how many Synthoids exist " + - "in your current city." + "in your current city.", }); DomElems.overviewEstPopHelpTip = createElement("div", { @@ -1381,7 +1381,7 @@ Bladeburner.prototype.createOverviewContent = function() { "The Synthoid populations of cities can change due to your " + "actions or random events. If random events occur, they will " + "be logged in the Bladeburner Console."); - } + }, }); DomElems.overviewEstComms = createElement("p", { @@ -1395,14 +1395,14 @@ Bladeburner.prototype.createOverviewContent = function() { innerText:"City Chaos: ", display:"inline-block", tooltip:"The city's chaos level due to tensions and conflicts between humans and Synthoids. " + - "Having too high of a chaos level can make contracts and operations harder." + "Having too high of a chaos level can make contracts and operations harder.", }); DomElems.overviewBonusTime = createElement("p", { innerText: "Bonus time: ", display: "inline-block", tooltip: "You gain bonus time while offline or when the game is inactive (e.g. when the tab is throttled by browser). " + - "Bonus time makes the Bladeburner mechanic progress faster, up to 5x the normal speed." + "Bonus time makes the Bladeburner mechanic progress faster, up to 5x the normal speed.", }); DomElems.overviewSkillPoints = createElement("p", {display:"block"}); @@ -1438,7 +1438,7 @@ Bladeburner.prototype.createOverviewContent = function() { innerText:"Cancel", class:"a-link-button", clickListener:() => { removeElementById(popupId); return false; - } + }, })) popupArguments.push(createElement("p", { // Info Text innerText:"Travel to a different city for your Bladeburner " + @@ -1460,12 +1460,12 @@ Bladeburner.prototype.createOverviewContent = function() { removeElementById(popupId); inst.updateOverviewContent(); return false; - } + }, })); })(this, i); } createPopup(popupId, popupArguments); - } + }, })); // Faction button @@ -1493,7 +1493,7 @@ Bladeburner.prototype.createOverviewContent = function() { } } return false; - } + }, })); } @@ -1526,14 +1526,14 @@ Bladeburner.prototype.createActionAndSkillsContent = function() { DomElems.currentTab = buttons[i].toLowerCase(); inst.createActionAndSkillsContent(); return false; - } + }, })); }) (buttons, i, this, currTab); } // General info/description for each action DomElems.actionsAndSkillsDesc = createElement("p", { - display:"block", margin:"4px", padding:"4px" + display:"block", margin:"4px", padding:"4px", }); // List for actions/skills @@ -1578,7 +1578,7 @@ Bladeburner.prototype.createGeneralActionsContent = function() { for (var actionName in GeneralActions) { if (GeneralActions.hasOwnProperty(actionName)) { DomElems.generalActions[actionName] = createElement("div", { - class:"bladeburner-action", name:actionName + class:"bladeburner-action", name:actionName, }); DomElems.actionsAndSkillsList.appendChild(DomElems.generalActions[actionName]); } @@ -1600,7 +1600,7 @@ Bladeburner.prototype.createContractsContent = function() { for (var contractName in this.contracts) { if (this.contracts.hasOwnProperty(contractName)) { DomElems.contracts[contractName] = createElement("div", { - class:"bladeburner-action", name:contractName + class:"bladeburner-action", name:contractName, }); DomElems.actionsAndSkillsList.appendChild(DomElems.contracts[contractName]); } @@ -1629,7 +1629,7 @@ Bladeburner.prototype.createOperationsContent = function() { for (var operationName in this.operations) { if (this.operations.hasOwnProperty(operationName)) { DomElems.operations[operationName] = createElement("div", { - class:"bladeburner-action", name:operationName + class:"bladeburner-action", name:operationName, }); DomElems.actionsAndSkillsList.appendChild(DomElems.operations[operationName]); } @@ -1667,7 +1667,7 @@ Bladeburner.prototype.createBlackOpsContent = function() { for (var i = blackops.length-1; i >= 0 ; --i) { if (this.blackops[[blackops[i].name]] == null && i !== 0 && this.blackops[[blackops[i-1].name]] == null) {continue;} // If this one nor the next are completed then this isn't unlocked yet. DomElems.blackops[blackops[i].name] = createElement("div", { - class:"bladeburner-action", name:blackops[i].name + class:"bladeburner-action", name:blackops[i].name, }); DomElems.actionsAndSkillsList.appendChild(DomElems.blackops[blackops[i].name]); } @@ -1750,7 +1750,7 @@ Bladeburner.prototype.createSkillsContent = function() { // Skill Points DomElems.skillPointsDisplay = createElement("p", { - innerHTML:"
    Skill Points: " + formatNumber(this.skillPoints, 0) + "" + innerHTML:"
    Skill Points: " + formatNumber(this.skillPoints, 0) + "", }); DomElems.actionAndSkillsDiv.appendChild(DomElems.skillPointsDisplay); @@ -1758,7 +1758,7 @@ Bladeburner.prototype.createSkillsContent = function() { for (var skillName in Skills) { if (Skills.hasOwnProperty(skillName)) { DomElems.skills[skillName] = createElement("div", { - class:"bladeburner-action", name:skillName + class:"bladeburner-action", name:skillName, }); DomElems.actionsAndSkillsList.appendChild(DomElems.skills[skillName]); } @@ -1902,7 +1902,7 @@ Bladeburner.prototype.updateGeneralActionsUIElement = function(el, action) { var progress = this.actionTimeCurrent / this.actionTimeToComplete; el.appendChild(createElement("p", { display:"block", - innerText:createProgressBarText({progress:progress}) + innerText:createProgressBarText({progress:progress}), })); } else { // Start button @@ -1915,13 +1915,13 @@ Bladeburner.prototype.updateGeneralActionsUIElement = function(el, action) { this.startAction(this.action); this.updateActionAndSkillsContent(); return false; - } + }, })); } appendLineBreaks(el, 2); el.appendChild(createElement("pre", { // Info - innerHTML:action.desc, display:"inline-block" + innerHTML:action.desc, display:"inline-block", })); @@ -1937,14 +1937,14 @@ Bladeburner.prototype.updateContractsUIElement = function(el, action) { formatNumber(this.actionTimeCurrent, 0) + " / " + formatNumber(this.actionTimeToComplete, 0) + ")" : action.name, - display:"inline-block" + display:"inline-block", })); if (isActive) { // Progress bar if its active var progress = this.actionTimeCurrent / this.actionTimeToComplete; el.appendChild(createElement("p", { display:"block", - innerText:createProgressBarText({progress:progress}) + innerText:createProgressBarText({progress:progress}), })); } else { // Start button el.appendChild(createElement("a", { @@ -1956,7 +1956,7 @@ Bladeburner.prototype.updateContractsUIElement = function(el, action) { this.startAction(this.action); this.updateActionAndSkillsContent(); return false; - } + }, })); } @@ -1967,7 +1967,7 @@ Bladeburner.prototype.updateContractsUIElement = function(el, action) { display:"inline-block", innerText:"Level: " + action.level + " / " + action.maxLevel, tooltip:action.getSuccessesNeededForNextLevel(BladeburnerConstants.ContractSuccessesPerLevel) + " successes " + - "needed for next level" + "needed for next level", })); el.appendChild(createElement("a", { class: maxLevel ? "a-link-button-inactive" : "a-link-button", innerHTML:"↑", @@ -1979,7 +1979,7 @@ Bladeburner.prototype.updateContractsUIElement = function(el, action) { if (isActive) {this.startAction(this.action);} // Restart Action this.updateContractsUIElement(el, action); return false; - } + }, })); el.appendChild(createElement("a", { class: (action.level <= 1) ? "a-link-button-inactive" : "a-link-button", innerHTML:"↓", @@ -1991,7 +1991,7 @@ Bladeburner.prototype.updateContractsUIElement = function(el, action) { if (isActive) {this.startAction(this.action);} // Restart Action this.updateContractsUIElement(el, action); return false; - } + }, })); var actionTime = action.getActionTime(this); @@ -2011,7 +2011,7 @@ Bladeburner.prototype.updateContractsUIElement = function(el, action) { var autolevelCheckboxId = "bladeburner-" + action.name + "-autolevel-checkbox"; el.appendChild(createElement("label", { for:autolevelCheckboxId, innerText:"Autolevel: ",color:"white", - tooltip:"Automatically increase contract level when possible" + tooltip:"Automatically increase contract level when possible", })); const checkboxInput = createElement("input", { @@ -2035,14 +2035,14 @@ Bladeburner.prototype.updateOperationsUIElement = function(el, action) { formatNumber(this.actionTimeCurrent, 0) + " / " + formatNumber(this.actionTimeToComplete, 0) + ")" : action.name, - display:"inline-block" + display:"inline-block", })); if (isActive) { // Progress bar if its active var progress = this.actionTimeCurrent / this.actionTimeToComplete; el.appendChild(createElement("p", { display:"block", - innerText:createProgressBarText({progress:progress}) + innerText:createProgressBarText({progress:progress}), })); } else { // Start button and set Team Size button el.appendChild(createElement("a", { @@ -2054,7 +2054,7 @@ Bladeburner.prototype.updateOperationsUIElement = function(el, action) { this.startAction(this.action); this.updateActionAndSkillsContent(); return false; - } + }, })); el.appendChild(createElement("a", { innerText:"Set Team Size (Curr Size: " + formatNumber(action.teamCount, 0) + ")", class:"a-link-button", @@ -2065,7 +2065,7 @@ Bladeburner.prototype.updateOperationsUIElement = function(el, action) { innerText:"Enter the amount of team members you would like to take on these " + "operations. If you do not have the specified number of team members, " + "then as many as possible will be used. Note that team members may " + - "be lost during operations." + "be lost during operations.", }); var input = createElement("input", { @@ -2083,17 +2083,17 @@ Bladeburner.prototype.updateOperationsUIElement = function(el, action) { } removeElementById(popupId); return false; - } + }, }); var cancelBtn = createElement("a", { innerText:"Cancel", class:"a-link-button", clickListener:() => { removeElementById(popupId); return false; - } + }, }); createPopup(popupId, [txt, input, setBtn, cancelBtn]); - } + }, })); } @@ -2104,7 +2104,7 @@ Bladeburner.prototype.updateOperationsUIElement = function(el, action) { display:"inline-block", innerText:"Level: " + action.level + " / " + action.maxLevel, tooltip:action.getSuccessesNeededForNextLevel(BladeburnerConstants.OperationSuccessesPerLevel) + " successes " + - "needed for next level" + "needed for next level", })); el.appendChild(createElement("a", { class: maxLevel ? "a-link-button-inactive" : "a-link-button", innerHTML:"↑", @@ -2116,7 +2116,7 @@ Bladeburner.prototype.updateOperationsUIElement = function(el, action) { if (isActive) {this.startAction(this.action);} // Restart Action this.updateOperationsUIElement(el, action); return false; - } + }, })); el.appendChild(createElement("a", { class: (action.level <= 1) ? "a-link-button-inactive" : "a-link-button", innerHTML:"↓", @@ -2128,11 +2128,10 @@ Bladeburner.prototype.updateOperationsUIElement = function(el, action) { if (isActive) {this.startAction(this.action);} // Restart Action this.updateOperationsUIElement(el, action); return false; - } + }, })); // General Info - var difficulty = action.getDifficulty(); var actionTime = action.getActionTime(this); appendLineBreaks(el, 2); el.appendChild(createElement("pre", { @@ -2150,7 +2149,7 @@ Bladeburner.prototype.updateOperationsUIElement = function(el, action) { var autolevelCheckboxId = "bladeburner-" + action.name + "-autolevel-checkbox"; el.appendChild(createElement("label", { for:autolevelCheckboxId, innerText:"Autolevel: ",color:"white", - tooltip:"Automatically increase operation level when possible" + tooltip:"Automatically increase operation level when possible", })); const checkboxInput = createElement("input", { @@ -2170,7 +2169,6 @@ Bladeburner.prototype.updateBlackOpsUIElement = function(el, action) { var isActive = el.classList.contains(ActiveActionCssClass); var isCompleted = (this.blackops[action.name] != null); var estimatedSuccessChance = action.getSuccessChance(this, {est:true}); - var difficulty = action.getDifficulty(); var actionTime = action.getActionTime(this); var hasReqdRank = this.rank >= action.reqdRank; @@ -2194,7 +2192,7 @@ Bladeburner.prototype.updateBlackOpsUIElement = function(el, action) { var progress = this.actionTimeCurrent / this.actionTimeToComplete; el.appendChild(createElement("p", { display:"block", - innerText:createProgressBarText({progress:progress}) + innerText:createProgressBarText({progress:progress}), })); } else { el.appendChild(createElement("a", { // Start button @@ -2206,7 +2204,7 @@ Bladeburner.prototype.updateBlackOpsUIElement = function(el, action) { this.startAction(this.action); this.updateActionAndSkillsContent(); return false; - } + }, })); el.appendChild(createElement("a", { // Set Team Size Button innerText:"Set Team Size (Curr Size: " + formatNumber(action.teamCount, 0) + ")", class:"a-link-button", @@ -2217,7 +2215,7 @@ Bladeburner.prototype.updateBlackOpsUIElement = function(el, action) { innerText:"Enter the amount of team members you would like to take on this " + "BlackOp. If you do not have the specified number of team members, " + "then as many as possible will be used. Note that team members may " + - "be lost during operations." + "be lost during operations.", }); var input = createElement("input", { @@ -2235,17 +2233,17 @@ Bladeburner.prototype.updateBlackOpsUIElement = function(el, action) { } removeElementById(popupId); return false; - } + }, }); var cancelBtn = createElement("a", { innerText:"Cancel", class:"a-link-button", clickListener:() => { removeElementById(popupId); return false; - } + }, }); createPopup(popupId, [txt, input, setBtn, cancelBtn]); - } + }, })); } @@ -2257,7 +2255,7 @@ Bladeburner.prototype.updateBlackOpsUIElement = function(el, action) { })); el.appendChild(createElement("p", { display:"block", color:hasReqdRank ? "white" : "red", - innerHTML:"Required Rank: " + formatNumber(action.reqdRank, 0) + "
    " + innerHTML:"Required Rank: " + formatNumber(action.reqdRank, 0) + "
    ", })); el.appendChild(createElement("p", { display:"inline-block", @@ -2297,7 +2295,7 @@ Bladeburner.prototype.updateSkillsUIElement = function(el, skill) { this.upgradeSkill(skill); this.createActionAndSkillsContent(); return false; - } + }, })); appendLineBreaks(el, 2); el.appendChild(createElement("p", { @@ -2307,7 +2305,7 @@ Bladeburner.prototype.updateSkillsUIElement = function(el, skill) { if (maxLvl) { el.appendChild(createElement("p", { color:"red", display:"block", - innerText:"MAX LEVEL" + innerText:"MAX LEVEL", })); } else { el.appendChild(createElement("p", { @@ -2508,7 +2506,7 @@ Bladeburner.prototype.executeAutomateConsoleCommand = function(args) { case "gen": if (GeneralActions[val] != null) { var action = new ActionIdentifier({ - type:ActionTypes[val], name:val + type:ActionTypes[val], name:val, }); if (highLow) { this.automateActionHigh = action; @@ -2524,7 +2522,7 @@ Bladeburner.prototype.executeAutomateConsoleCommand = function(args) { case "contracts": if (this.contracts[val] != null) { var action = new ActionIdentifier({ - type:ActionTypes.Contract, name:val + type:ActionTypes.Contract, name:val, }); if (highLow) { this.automateActionHigh = action; @@ -2542,7 +2540,7 @@ Bladeburner.prototype.executeAutomateConsoleCommand = function(args) { case "operation": if (this.operations[val] != null) { var action = new ActionIdentifier({ - type:ActionTypes.Operation, name:val + type:ActionTypes.Operation, name:val, }); if (highLow) { this.automateActionHigh = action; @@ -3210,7 +3208,7 @@ Bladeburner.prototype.setTeamSizeNetscriptFn = function(type, name, size, worker return -1; } - const sanitizedSize = Math.round(size); + let sanitizedSize = Math.round(size); if (isNaN(sanitizedSize) || sanitizedSize < 0) { workerScript.log("bladeburner.setTeamSize", `Invalid size: ${size}`); return -1; diff --git a/src/Bladeburner/Action.ts b/src/Bladeburner/Action.ts index d2b78a011..e4e42d749 100644 --- a/src/Bladeburner/Action.ts +++ b/src/Bladeburner/Action.ts @@ -3,21 +3,20 @@ import { getRandomInt } from "../../utils/helpers/getRandomInt"; import { addOffset } from "../../utils/helpers/addOffset"; import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver"; import { BladeburnerConstants } from "./data/Constants"; -// import { Contract } from "./Contract"; -// import { Operation } from "./Operation"; -// import { BlackOperation } from "./BlackOperation"; +import { IBladeburner } from "./IBladeburner"; +import { IAction, ISuccessChanceParams } from "./IAction"; class StatsMultiplier { - hack: number = 0; - str: number = 0; - def: number = 0; - dex: number = 0; - agi: number = 0; - cha: number = 0; - int: number = 0; - [key: string]: number; -}; + + hack = 0; + str = 0; + def = 0; + dex = 0; + agi = 0; + cha = 0; + int = 0; +} export interface IActionParams { name?: string; @@ -43,32 +42,32 @@ export interface IActionParams { teamCount?: number; } -export class Action { - name: string = ""; - desc: string = ""; +export class Action implements IAction { + name = ""; + desc = ""; // Difficulty scales with level. See getDifficulty() method - level: number = 1; - maxLevel: number = 1; - autoLevel: boolean = true; - baseDifficulty: number = 100; - difficultyFac: number = 1.01; + level = 1; + maxLevel = 1; + autoLevel = true; + baseDifficulty = 100; + difficultyFac = 1.01; // Rank increase/decrease is affected by this exponent - rewardFac: number = 1.02; + rewardFac = 1.02; - successes: number = 0; - failures: number = 0; + successes = 0; + failures = 0; // All of these scale with level/difficulty - rankGain: number = 0; - rankLoss: number = 0; - hpLoss: number = 0; - hpLost: number = 0; + rankGain = 0; + rankLoss = 0; + hpLoss = 0; + hpLost = 0; // Action Category. Current categories are stealth and kill - isStealth: boolean = false; - isKill: boolean = false; + isStealth = false; + isKill = false; /** * Number of this contract remaining, and its growth rate @@ -81,7 +80,7 @@ export class Action { weights: StatsMultiplier = {hack:1/7,str:1/7,def:1/7,dex:1/7,agi:1/7,cha:1/7,int:1/7}; // Diminishing returns of stats (stat ^ decay where 0 <= decay <= 1) decays: StatsMultiplier = { hack: 0.9, str: 0.9, def: 0.9, dex: 0.9, agi: 0.9, cha: 0.9, int: 0.9 }; - teamCount: number = 0; + teamCount = 0; // Base Class for Contracts, Operations, and BlackOps constructor(params: IActionParams| null = null) { // | null = null @@ -138,7 +137,7 @@ export class Action { * Tests for success. Should be called when an action has completed * @param inst {Bladeburner} - Bladeburner instance */ - attempt(inst: any): boolean { + attempt(inst: IBladeburner): boolean { return (Math.random() < this.getSuccessChance(inst)); } @@ -147,7 +146,7 @@ export class Action { return 1; } - getActionTime(inst: any): number { + getActionTime(inst: IBladeburner): number { const difficulty = this.getDifficulty(); let baseTime = difficulty / BladeburnerConstants.DifficultyToTimeFactor; const skillFac = inst.skillMultipliers.actionTime; // Always < 1 @@ -165,15 +164,15 @@ export class Action { } // For actions that have teams. To be implemented by subtypes. - getTeamSuccessBonus(inst: any): number { + getTeamSuccessBonus(inst: IBladeburner): number { return 1; } - getActionTypeSkillSuccessBonus(inst: any): number { + getActionTypeSkillSuccessBonus(inst: IBladeburner): number { return 1; } - getChaosCompetencePenalty(inst: any, params: any): number { + getChaosCompetencePenalty(inst: IBladeburner, params: ISuccessChanceParams): number { const city = inst.getCurrentCity(); if (params.est) { return Math.pow((city.popEst / BladeburnerConstants.PopulationThreshold), BladeburnerConstants.PopulationExponent); @@ -182,7 +181,7 @@ export class Action { } } - getChaosDifficultyBonus(inst: any, params: any): number { + getChaosDifficultyBonus(inst: IBladeburner/*, params: ISuccessChanceParams*/): number { const city = inst.getCurrentCity(); if (city.chaos > BladeburnerConstants.ChaosThreshold) { const diff = 1 + (city.chaos - BladeburnerConstants.ChaosThreshold); @@ -198,14 +197,14 @@ export class Action { * @params - options: * est (bool): Get success chance estimate instead of real success chance */ - getSuccessChance(inst: any, params: any={}) { + getSuccessChance(inst: IBladeburner, params: ISuccessChanceParams={est: false}): number { if (inst == null) {throw new Error("Invalid Bladeburner instance passed into Action.getSuccessChance");} let difficulty = this.getDifficulty(); let competence = 0; - for (let stat in this.weights) { + for (const stat in this.weights) { if (this.weights.hasOwnProperty(stat)) { - let playerStatLvl = Player.queryStatFromString(stat); - let key = "eff" + stat.charAt(0).toUpperCase() + stat.slice(1); + const playerStatLvl = Player.queryStatFromString(stat); + const key = "eff" + stat.charAt(0).toUpperCase() + stat.slice(1); let effMultiplier = inst.skillMultipliers[key]; if (effMultiplier == null) { console.error(`Failed to find Bladeburner Skill multiplier for: ${stat}`); @@ -220,7 +219,7 @@ export class Action { competence *= this.getTeamSuccessBonus(inst); competence *= this.getChaosCompetencePenalty(inst, params); - difficulty *= this.getChaosDifficultyBonus(inst, params); + difficulty *= this.getChaosDifficultyBonus(inst); if(this.name == "Raid" && inst.getCurrentCity().comms <= 0) { return 0; @@ -253,18 +252,14 @@ export class Action { } } - static fromJSON(value: any): Action { - return Generic_fromJSON(Action, value.data); - } - toJSON(): any { return Generic_toJSON("Action", this); } + + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types + static fromJSON(value: any): Action { + return Generic_fromJSON(Action, value.data); + } } - - - - - Reviver.constructors.Action = Action; \ No newline at end of file diff --git a/src/Bladeburner/BlackOperation.ts b/src/Bladeburner/BlackOperation.ts index 11ac83dc4..c5fbe1e07 100644 --- a/src/Bladeburner/BlackOperation.ts +++ b/src/Bladeburner/BlackOperation.ts @@ -13,21 +13,22 @@ export class BlackOperation extends Operation { return 1.5; } - getChaosCompetencePenalty(inst: any, params: any): number { + getChaosCompetencePenalty(/*inst: IBladeburner, params: ISuccessChanceParams*/): number { return 1; } - getChaosDifficultyBonus(inst: any, params: any): number { + getChaosDifficultyBonus(/*inst: IBladeburner, params: ISuccessChanceParams*/): number { return 1; } - static fromJSON(value: any): Operation { - return Generic_fromJSON(BlackOperation, value.data); - } - toJSON(): any { return Generic_toJSON("BlackOperation", this); } + + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types + static fromJSON(value: any): Operation { + return Generic_fromJSON(BlackOperation, value.data); + } } Reviver.constructors.BlackOperation = BlackOperation; \ No newline at end of file diff --git a/src/Bladeburner/BlackOperations.ts b/src/Bladeburner/BlackOperations.ts index 94adc750c..f7ed13fc6 100644 --- a/src/Bladeburner/BlackOperations.ts +++ b/src/Bladeburner/BlackOperations.ts @@ -16,7 +16,7 @@ export const BlackOperations: IMap = {}; rankGain:50, rankLoss:10, hpLoss:100, weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1}, decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, - isKill:true + isKill:true, }); BlackOperations["Operation Zero"] = new BlackOperation({ name:"Operation Zero", @@ -33,7 +33,7 @@ export const BlackOperations: IMap = {}; rankGain:60, rankLoss:15, hpLoss:50, weights:{hack:0.2,str:0.15,def:0.15,dex:0.2,agi:0.2,cha:0, int:0.1}, decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, - isStealth:true + isStealth:true, }); BlackOperations["Operation X"] = new BlackOperation({ name:"Operation X", @@ -52,7 +52,7 @@ export const BlackOperations: IMap = {}; rankGain:75, rankLoss:15, hpLoss:100, weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1}, decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, - isKill:true + isKill:true, }); BlackOperations["Operation Titan"] = new BlackOperation({ name:"Operation Titan", @@ -70,7 +70,7 @@ export const BlackOperations: IMap = {}; rankGain:100, rankLoss:20, hpLoss:100, weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1}, decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, - isKill:true + isKill:true, }); BlackOperations["Operation Ares"] = new BlackOperation({ name:"Operation Ares", @@ -84,7 +84,7 @@ export const BlackOperations: IMap = {}; rankGain:125, rankLoss:20, hpLoss:200, weights:{hack:0,str:0.25,def:0.25,dex:0.25,agi:0.25,cha:0, int:0}, decays:{hack:0,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, - isKill:true + isKill:true, }); BlackOperations["Operation Archangel"] = new BlackOperation({ name:"Operation Archangel", @@ -152,7 +152,7 @@ export const BlackOperations: IMap = {}; rankGain:750, rankLoss:60, hpLoss:1000, weights:{hack:0.05,str:0.2,def:0.2,dex:0.25,agi:0.25,cha:0, int:0.05}, decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, - isKill:true + isKill:true, }); BlackOperations["Operation Deckard"] = new BlackOperation({ name:"Operation Deckard", @@ -202,7 +202,7 @@ export const BlackOperations: IMap = {}; rankGain:2e3, rankLoss:150, hpLoss:1500, weights:{hack:0,str:0.24,def:0.24,dex:0.24,agi:0.24,cha:0, int:0.04}, decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, - isKill:true + isKill:true, }); BlackOperations["Operation Shoulder of Orion"] = new BlackOperation({ name:"Operation Shoulder of Orion", @@ -218,7 +218,7 @@ export const BlackOperations: IMap = {}; rankGain:2.5e3, rankLoss:500, hpLoss:1500, weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1}, decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, - isStealth:true + isStealth:true, }); BlackOperations["Operation Hyron"] = new BlackOperation({ name:"Operation Hyron", @@ -240,7 +240,7 @@ export const BlackOperations: IMap = {}; rankGain:3e3, rankLoss:1e3, hpLoss:500, weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1}, decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, - isKill:true + isKill:true, }); BlackOperations["Operation Morpheus"] = new BlackOperation({ name:"Operation Morpheus", @@ -257,7 +257,7 @@ export const BlackOperations: IMap = {}; rankGain:4e3, rankLoss:1e3, hpLoss:100, weights:{hack:0.05,str:0.15,def:0.15,dex:0.3,agi:0.3,cha:0, int:0.05}, decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, - isStealth:true + isStealth:true, }); BlackOperations["Operation Ion Storm"] = new BlackOperation({ name:"Operation Ion Storm", @@ -272,7 +272,7 @@ export const BlackOperations: IMap = {}; rankGain:5e3, rankLoss:1e3, hpLoss:5000, weights:{hack:0,str:0.24,def:0.24,dex:0.24,agi:0.24,cha:0, int:0.04}, decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, - isKill:true + isKill:true, }); BlackOperations["Operation Annihilus"] = new BlackOperation({ name:"Operation Annihilus", @@ -286,7 +286,7 @@ export const BlackOperations: IMap = {}; rankGain:7.5e3, rankLoss:1e3, hpLoss:10e3, weights:{hack:0,str:0.24,def:0.24,dex:0.24,agi:0.24,cha:0, int:0.04}, decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, - isKill:true + isKill:true, }); BlackOperations["Operation Ultron"] = new BlackOperation({ name:"Operation Ultron", @@ -306,7 +306,7 @@ export const BlackOperations: IMap = {}; rankGain:10e3, rankLoss:2e3, hpLoss:10e3, weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1}, decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, - isKill:true + isKill:true, }); BlackOperations["Operation Centurion"] = new BlackOperation({ name:"Operation Centurion", diff --git a/src/Bladeburner/City.ts b/src/Bladeburner/City.ts index d159eab7e..75f8aff24 100644 --- a/src/Bladeburner/City.ts +++ b/src/Bladeburner/City.ts @@ -5,13 +5,13 @@ import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviv import { addOffset } from "../../utils/helpers/addOffset"; export class ChangePopulationByCountParams { - estChange: number = 0; - estOffset: number = 0; + estChange = 0; + estOffset = 0; } export class ChangePopulationByPercentageParams { - nonZero: boolean = false; - changeEstEqually: boolean = false; + nonZero = false; + changeEstEqually = false; } export class City { @@ -19,32 +19,32 @@ export class City { /** * Name of the city. */ - name: string = ""; + name = ""; /** * Population of the city. */ - pop: number = 0; + pop = 0; /** * Population estimation of the city. */ - popEst: number = 0; + popEst = 0; /** * Number of communities in the city. */ - comms: number = 0; + comms = 0; /** * Estimated number of communities in the city. */ - commsEst: number = 0; + commsEst = 0; /** * Chaos level of the city. */ - chaos: number = 0; + chaos = 0; constructor(name: string = BladeburnerConstants.CityNames[2]) { this.name = name; @@ -84,7 +84,7 @@ export class City { /** * p is the percentage, not the multiplier (e.g. pass in p = 5 for 5%) */ - improvePopulationEstimateByPercentage(p: number, skillMult: number=1): void { + improvePopulationEstimateByPercentage(p: number, skillMult=1): void { p = p*skillMult; if (isNaN(p)) {throw new Error("NaN passed into City.improvePopulationEstimateByPercentage()");} if (this.popEst < this.pop) { @@ -97,7 +97,7 @@ export class City { } } - improveCommunityEstimate(n: number=1): void { + improveCommunityEstimate(n=1): void { if (isNaN(n)) {throw new Error("NaN passed into City.improveCommunityEstimate()");} if (this.commsEst < this.comms) { this.commsEst += n; @@ -154,19 +154,20 @@ export class City { if (this.chaos < 0) {this.chaos = 0;} } - /** - * Initiatizes a City object from a JSON save state. - */ - static fromJSON(value: any): City { - return Generic_fromJSON(City, value.data); - } - /** * Serialize the current object to a JSON save state. */ toJSON(): any { return Generic_toJSON("City", this); } + + /** + * Initiatizes a City object from a JSON save state. + */ + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types + static fromJSON(value: any): City { + return Generic_fromJSON(City, value.data); + } } Reviver.constructors.City = City; diff --git a/src/Bladeburner/Contract.ts b/src/Bladeburner/Contract.ts index 8b9662e66..332b98609 100644 --- a/src/Bladeburner/Contract.ts +++ b/src/Bladeburner/Contract.ts @@ -1,4 +1,4 @@ -// import { BladeburnerConstants } from "./data/Constants"; +import { IBladeburner } from "./IBladeburner"; import { Action, IActionParams } from "./Action"; import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver"; @@ -8,17 +8,18 @@ export class Contract extends Action { super(params); } - getActionTypeSkillSuccessBonus(inst: any): number { + getActionTypeSkillSuccessBonus(inst: IBladeburner): number { return inst.skillMultipliers.successChanceContract; } - static fromJSON(value: any): Contract { - return Generic_fromJSON(Contract, value.data); - } - toJSON(): any { return Generic_toJSON("Contract", this); } + + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types + static fromJSON(value: any): Contract { + return Generic_fromJSON(Contract, value.data); + } } Reviver.constructors.Contract = Contract; \ No newline at end of file diff --git a/src/Bladeburner/GeneralActions.ts b/src/Bladeburner/GeneralActions.ts index 209b60002..ad457befa 100644 --- a/src/Bladeburner/GeneralActions.ts +++ b/src/Bladeburner/GeneralActions.ts @@ -11,7 +11,7 @@ export const GeneralActions: IMap = {}; name:actionName, desc:"Improve your abilities at the Bladeburner unit's specialized training " + "center. Doing this gives experience for all combat stats and also " + - "increases your max stamina." + "increases your max stamina.", }); actionName = "Field Analysis"; @@ -21,7 +21,7 @@ export const GeneralActions: IMap = {}; "Bladeburner's unit intelligence on Synthoid locations and " + "activities. Completing this action will improve the accuracy " + "of your Synthoid population estimated in the current city.

    " + - "Does NOT require stamina." + "Does NOT require stamina.", }); actionName = "Recruitment"; @@ -29,7 +29,7 @@ export const GeneralActions: IMap = {}; name:actionName, desc:"Attempt to recruit members for your Bladeburner team. These members " + "can help you conduct operations.

    " + - "Does NOT require stamina." + "Does NOT require stamina.", }); actionName = "Diplomacy"; @@ -37,7 +37,7 @@ export const GeneralActions: IMap = {}; name: actionName, desc: "Improve diplomatic relations with the Synthoid population. " + "Completing this action will reduce the Chaos level in your current city.

    " + - "Does NOT require stamina." + "Does NOT require stamina.", }); actionName = "Hyperbolic Regeneration Chamber"; diff --git a/src/Bladeburner/IAction.ts b/src/Bladeburner/IAction.ts new file mode 100644 index 000000000..2bae70182 --- /dev/null +++ b/src/Bladeburner/IAction.ts @@ -0,0 +1,71 @@ +import { IBladeburner } from "./IBladeburner"; + +export interface IStatsMultiplier { + [key: string]: number; + + hack: number; + str: number; + def: number; + dex: number; + agi: number; + cha: number; + int: number; +} + +export interface ISuccessChanceParams { + est: boolean; +} + +export interface IAction { + name: string; + desc: string; + + // Difficulty scales with level. See getDifficulty() method + level: number; + maxLevel: number; + autoLevel: boolean; + baseDifficulty: number; + difficultyFac: number; + + // Rank increase/decrease is affected by this exponent + rewardFac: number; + + successes: number; + failures: number; + + // All of these scale with level/difficulty + rankGain: number; + rankLoss: number; + hpLoss: number; + hpLost: number; + + // Action Category. Current categories are stealth and kill + isStealth: boolean; + isKill: boolean; + + /** + * Number of this contract remaining, and its growth rate + * Growth rate is an integer and the count will increase by that integer every "cycle" + */ + count: number; + countGrowth: number; + + // Weighting of each stat in determining action success rate + weights: IStatsMultiplier; + // Diminishing returns of stats (stat ^ decay where 0 <= decay <= 1) + decays: IStatsMultiplier; + teamCount: number; + + getDifficulty(): number; + attempt(inst: IBladeburner): boolean; + getActionTimePenalty(): number; + getActionTime(inst: IBladeburner): number; + getTeamSuccessBonus(inst: IBladeburner): number; + getActionTypeSkillSuccessBonus(inst: IBladeburner): number; + getChaosCompetencePenalty(inst: IBladeburner, params: ISuccessChanceParams): number; + getChaosDifficultyBonus(inst: IBladeburner): number; + getSuccessChance(inst: IBladeburner, params: ISuccessChanceParams): number; + getSuccessesNeededForNextLevel(baseSuccessesPerLevel: number): number; + setMaxLevel(baseSuccessesPerLevel: number): void; + toJSON(): any; +} \ No newline at end of file diff --git a/src/Bladeburner/IActionIdentifier.ts b/src/Bladeburner/IActionIdentifier.ts new file mode 100644 index 000000000..450ba774f --- /dev/null +++ b/src/Bladeburner/IActionIdentifier.ts @@ -0,0 +1,4 @@ +export interface IActionIdentifier { + name: string; + type: string; +} \ No newline at end of file diff --git a/src/Bladeburner/IBladeburner.ts b/src/Bladeburner/IBladeburner.ts new file mode 100644 index 000000000..7a7d9cd0e --- /dev/null +++ b/src/Bladeburner/IBladeburner.ts @@ -0,0 +1,39 @@ +import { IActionIdentifier } from "./IActionIdentifier"; +import { City } from "./City"; + +export interface IBladeburner { + numHosp: number; + moneyLost: number; + rank: number; + maxRank: number; + skillPoints: number; + totalSkillPoints: number; + teamSize: number; + teamLost: number; + storedCycles: number; + randomEventCounter: number; + actionTimeToComplete: number; + actionTimeCurrent: number; + action: IActionIdentifier; + cities: any; + city: string; + skills: any; + skillMultipliers: any; + staminaBonus: number; + maxStamina: number; + stamina: number; + contracts: any; + operations: any; + blackops: any; + logging: any; + automateEnabled: boolean; + automateActionHigh: number; + automateThreshHigh: number; + automateActionLow: number; + automateThreshLow: number; + consoleHistory: string[]; + consoleLogs: string[]; + + getCurrentCity(): City; + calculateStaminaPenalty(): number; +} \ No newline at end of file diff --git a/src/Bladeburner/Operation.ts b/src/Bladeburner/Operation.ts index 12718b493..9d9936ee4 100644 --- a/src/Bladeburner/Operation.ts +++ b/src/Bladeburner/Operation.ts @@ -1,3 +1,4 @@ +import { IBladeburner } from "./IBladeburner"; import { BladeburnerConstants } from "./data/Constants"; import { Action, IActionParams } from "./Action"; import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver"; @@ -8,8 +9,8 @@ export interface IOperationParams extends IActionParams { } export class Operation extends Action { - reqdRank: number = 100; - teamCount: number = 0; + reqdRank = 100; + teamCount = 0; constructor(params: IOperationParams | null = null) { super(params); @@ -18,38 +19,39 @@ export class Operation extends Action { } // For actions that have teams. To be implemented by subtypes. - getTeamSuccessBonus(inst: any): number { + getTeamSuccessBonus(inst: IBladeburner): number { if (this.teamCount && this.teamCount > 0) { this.teamCount = Math.min(this.teamCount, inst.teamSize); - let teamMultiplier = Math.pow(this.teamCount, 0.05); + const teamMultiplier = Math.pow(this.teamCount, 0.05); return teamMultiplier; } return 1; } - getActionTypeSkillSuccessBonus(inst: any): number { + getActionTypeSkillSuccessBonus(inst: IBladeburner): number { return inst.skillMultipliers.successChanceOperation; } - getChaosDifficultyBonus(inst: any, params: any): number { + getChaosDifficultyBonus(inst: IBladeburner/*, params: ISuccessChanceParams*/): number { const city = inst.getCurrentCity(); if (city.chaos > BladeburnerConstants.ChaosThreshold) { - let diff = 1 + (city.chaos - BladeburnerConstants.ChaosThreshold); - let mult = Math.pow(diff, 0.1); + const diff = 1 + (city.chaos - BladeburnerConstants.ChaosThreshold); + const mult = Math.pow(diff, 0.1); return mult; } return 1; } - static fromJSON(value: any): Operation { - return Generic_fromJSON(Operation, value.data); - } - toJSON(): any { return Generic_toJSON("Operation", this); } + + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types + static fromJSON(value: any): Operation { + return Generic_fromJSON(Operation, value.data); + } } Reviver.constructors.Operation = Operation; \ No newline at end of file diff --git a/src/Bladeburner/Skill.ts b/src/Bladeburner/Skill.ts index d901a25ca..deb84751e 100644 --- a/src/Bladeburner/Skill.ts +++ b/src/Bladeburner/Skill.ts @@ -33,36 +33,36 @@ export class Skill { name: string; desc: string; // Cost is in Skill Points - baseCost: number = 1; + baseCost = 1; // Additive cost increase per level - costInc: number = 1; - maxLvl: number = 0; + costInc = 1; + maxLvl = 0; /** * These benefits are additive. So total multiplier will be level (handled externally) times the * effects below */ - successChanceAll: number = 0; - successChanceStealth: number = 0; - successChanceKill: number = 0; - successChanceContract: number = 0; - successChanceOperation: number = 0; + successChanceAll = 0; + successChanceStealth = 0; + successChanceKill = 0; + successChanceContract = 0; + successChanceOperation = 0; /** * This multiplier affects everything that increases synthoid population/community estimate * e.g. Field analysis, Investigation Op, Undercover Op */ - successChanceEstimate: number = 0; - actionTime: number = 0; - effHack: number = 0; - effStr: number = 0; - effDef: number = 0; - effDex: number = 0; - effAgi: number = 0; - effCha: number = 0; - stamina: number = 0; - money: number = 0; - expGain: number = 0; + successChanceEstimate = 0; + actionTime = 0; + effHack = 0; + effStr = 0; + effDef = 0; + effDex = 0; + effAgi = 0; + effCha = 0; + stamina = 0; + money = 0; + expGain = 0; constructor(params: ISkillParams={name:"foo", desc:"foo"}) { if (!params.name) { diff --git a/src/Bladeburner/Skills.ts b/src/Bladeburner/Skills.ts index f762a296e..9fccf5614 100644 --- a/src/Bladeburner/Skills.ts +++ b/src/Bladeburner/Skills.ts @@ -10,55 +10,55 @@ export const Skills: IMap = {}; desc:"Each level of this skill increases your success chance " + "for all Contracts, Operations, and BlackOps by 3%", baseCost: 3, costInc: 2.1, - successChanceAll:3 + successChanceAll:3, }); Skills[SkillNames.Cloak] = new Skill({ name:SkillNames.Cloak, desc:"Each level of this skill increases your " + "success chance in stealth-related Contracts, Operations, and BlackOps by 5.5%", baseCost: 2, costInc: 1.1, - successChanceStealth:5.5 + successChanceStealth:5.5, }); Skills[SkillNames.ShortCircuit] = new Skill({ name:SkillNames.ShortCircuit, desc:"Each level of this skill increases your success chance " + "in Contracts, Operations, and BlackOps that involve retirement by 5.5%", baseCost: 2, costInc: 2.1, - successChanceKill:5.5 + successChanceKill:5.5, }); Skills[SkillNames.DigitalObserver] = new Skill({ name:SkillNames.DigitalObserver, desc:"Each level of this skill increases your success chance in " + "all Operations and BlackOps by 4%", baseCost: 2, costInc: 2.1, - successChanceOperation:4 + successChanceOperation:4, }); Skills[SkillNames.Tracer] = new Skill({ name:SkillNames.Tracer, desc:"Each level of this skill increases your success chance in " + "all Contracts by 4%", baseCost: 2, costInc: 2.1, - successChanceContract:4 + successChanceContract:4, }); Skills[SkillNames.Overclock] = new Skill({ name:SkillNames.Overclock, desc:"Each level of this skill decreases the time it takes " + "to attempt a Contract, Operation, and BlackOp by 1% (Max Level: 90)", baseCost: 3, costInc: 1.4, maxLvl: 90, - actionTime:1 + actionTime:1, }); Skills[SkillNames.Reaper] = new Skill({ name: SkillNames.Reaper, desc: "Each level of this skill increases your effective combat stats for Bladeburner actions by 2%", baseCost: 2, costInc: 2.1, - effStr: 2, effDef: 2, effDex: 2, effAgi: 2 + effStr: 2, effDef: 2, effDex: 2, effAgi: 2, }); Skills[SkillNames.EvasiveSystem] = new Skill({ name:SkillNames.EvasiveSystem, desc:"Each level of this skill increases your effective " + "dexterity and agility for Bladeburner actions by 4%", baseCost: 2, costInc: 2.1, - effDex: 4, effAgi: 4 + effDex: 4, effAgi: 4, }); Skills[SkillNames.Datamancer] = new Skill({ name:SkillNames.Datamancer, @@ -67,13 +67,13 @@ export const Skills: IMap = {}; "This affects all actions that can potentially increase " + "the accuracy of your synthoid population/community estimates.", baseCost:3, costInc:1, - successChanceEstimate:5 + successChanceEstimate:5, }); Skills[SkillNames.CybersEdge] = new Skill({ name:SkillNames.CybersEdge, desc:"Each level of this skill increases your max stamina by 2%", baseCost:1, costInc:3, - stamina:2 + stamina:2, }); Skills[SkillNames.HandsOfMidas] = new Skill({ name: SkillNames.HandsOfMidas, diff --git a/src/Bladeburner/data/Help.ts b/src/Bladeburner/data/Help.ts index ed87118b8..b08f86f10 100644 --- a/src/Bladeburner/data/Help.ts +++ b/src/Bladeburner/data/Help.ts @@ -1,4 +1,14 @@ -export const ConsoleHelpText: {} = { +export const ConsoleHelpText: { + helpList: string[]; + automate: string[]; + clear: string[]; + cls: string[]; + help: string[]; + log: string[]; + skill: string[]; + start: string[]; + stop: string[]; +} = { helpList: [ "Use 'help [command]' to get more information about a particular Bladeburner console command.", "", @@ -8,7 +18,7 @@ export const ConsoleHelpText: {} = { " log [en/dis] [type] Enable or disable logging for events and actions", " skill [action] [name] Level or display info about your Bladeburner skills", " start [type] [name] Start a Bladeburner action/task" , - " stop Stops your current Bladeburner action/task" + " stop Stops your current Bladeburner action/task", ], automate: [ "automate [var] [val] [hi/low]", @@ -30,17 +40,17 @@ export const ConsoleHelpText: {} = { "Using the four console commands above will set the automation to perform Tracking contracts " + "if your stamina is 100 or higher, and then switch to Field Analysis if your stamina drops below " + "50. Note that when setting the action, the name of the action is CASE-SENSITIVE. It must " + - "exactly match whatever the name is in the UI." + "exactly match whatever the name is in the UI.", ], clear: [ "clear", "", - "Clears the console" + "Clears the console", ], cls: [ "cls", "", - "Clears the console" + "Clears the console", ], help: [ "help [command]", @@ -51,7 +61,7 @@ export const ConsoleHelpText: {} = { "", " help automate", "", - "will display specific information about using the automate console command" + "will display specific information about using the automate console command", ], log: [ "log [en/dis] [type]", @@ -71,7 +81,7 @@ export const ConsoleHelpText: {} = { "Logging can be universally enabled/disabled using the 'all' keyword:", "", " log dis all", - " log en all" + " log en all", ], skill: [ "skill [action] [name]", @@ -91,7 +101,7 @@ export const ConsoleHelpText: {} = { "", "This console command can also be used to level up skills:", "", - " skill level [skill name]" + " skill level [skill name]", ], start: [ "start [type] [name]", @@ -106,11 +116,11 @@ export const ConsoleHelpText: {} = { "Examples:", "", " start contract Tracking", - " start op 'Undercover Operation'" + " start op 'Undercover Operation'", ], stop:[ "stop", "", - "Stop your current action and go idle." + "Stop your current action and go idle.", ], } \ No newline at end of file diff --git a/src/Bladeburner/ui/BlackOperationsPage.tsx b/src/Bladeburner/ui/BlackOperationsPage.tsx index 134147551..7f73397c1 100644 --- a/src/Bladeburner/ui/BlackOperationsPage.tsx +++ b/src/Bladeburner/ui/BlackOperationsPage.tsx @@ -38,7 +38,7 @@ for (var i = blackops.length-1; i >= 0 ; --i) { import * as React from "react"; -export function BlackOperationsPage(inst: any): React.ReactElement { +export function BlackOperationsPage(): React.ReactElement { // Put Black Operations in sequence of required rank const blackops = []; for (const name in BlackOperations) { @@ -55,9 +55,8 @@ export function BlackOperationsPage(inst: any): React.ReactElement { Black Operations (Black Ops) are special, one-time covert operations. Each Black Op must be unlocked successively by completing the one before it.

    Your ultimate goal to climb through the ranks of Bladeburners is to complete all of the Black Ops.

    Like normal operations, you may use a team for Black Ops. Failing a black op will incur heavy HP and rank losses.

    - {blackops.map( op => -
    -
    + {blackops.map(() =>
    +
    , )}
    ) } diff --git a/src/Casino/CoinFlip.tsx b/src/Casino/CoinFlip.tsx index a9c10948d..e67935073 100644 --- a/src/Casino/CoinFlip.tsx +++ b/src/Casino/CoinFlip.tsx @@ -41,7 +41,7 @@ export class CoinFlip extends Game { this.updateInvestment = this.updateInvestment.bind(this); } - updateInvestment(e: React.FormEvent) { + updateInvestment(e: React.FormEvent): void { let investment: number = parseInt(e.currentTarget.value); if (isNaN(investment)) { investment = minPlay; @@ -55,7 +55,7 @@ export class CoinFlip extends Game { this.setState({investment: investment}); } - play(guess: string) { + play(guess: string): void { if(this.reachedLimit(this.props.p)) return; const v = BadRNG.random(); let letter: string; @@ -80,7 +80,7 @@ export class CoinFlip extends Game { } - render() { + render(): React.ReactNode { return <>
     +———————+
    @@ -89,7 +89,7 @@ export class CoinFlip extends Game { | | | |
    +———————+
    - Play for:
    + Play for:
    this.play('H'))} text={"Head!"} disabled={this.state.playLock} /> this.play('T'))} text={"Tail!"} disabled={this.state.playLock} />

    {this.state.status}

    diff --git a/src/Casino/RNG.ts b/src/Casino/RNG.ts index 483bdf3b7..00550020f 100644 --- a/src/Casino/RNG.ts +++ b/src/Casino/RNG.ts @@ -1,6 +1,6 @@ export interface RNG { - random(): number + random(): number; } /* @@ -9,16 +9,16 @@ export interface RNG { */ class RNG0 implements RNG { x: number; - m: number = 1024; - a: number = 341; - c: number = 1; + m = 1024; + a = 341; + c = 1; constructor() { this.x = 0; this.reset(); } - step() { + step(): void { this.x = (this.a*this.x+this.c) % this.m; } @@ -27,7 +27,7 @@ class RNG0 implements RNG { return this.x/this.m; } - reset() { + reset(): void { this.x = (new Date()).getTime() % this.m; } } @@ -39,9 +39,9 @@ export const BadRNG: RNG0 = new RNG0(); * The period is 6e12. */ export class WHRNG implements RNG { - s1: number = 0; - s2: number = 0; - s3: number = 0; + s1 = 0; + s2 = 0; + s3 = 0; constructor(totalPlaytime: number) { // This one is seeded by the players total play time. @@ -51,7 +51,7 @@ export class WHRNG implements RNG { this.s3 = v; } - step() { + step(): void { this.s1 = (171 * this.s1) % 30269; this.s2 = (172 * this.s2) % 30307; this.s3 = (170 * this.s3) % 30323; diff --git a/src/Casino/Roulette.tsx b/src/Casino/Roulette.tsx index 158dfb528..fcfda71c2 100644 --- a/src/Casino/Roulette.tsx +++ b/src/Casino/Roulette.tsx @@ -28,10 +28,6 @@ function isRed(n: number): boolean { 21, 23, 25, 27, 30, 32, 34, 36].includes(n); } -function isBlack(n: number): boolean { - return !isRed(n); -} - type Strategy = { match: (n: number) => boolean; payout: number; @@ -102,14 +98,14 @@ const strategies: { Third2: { match: (n: number): boolean => { if (n === 0) return false; - return 13 <= n && n <= 24; + return n >= 13 && n <= 24; }, payout: 2, }, Third3: { match: (n: number): boolean => { if (n === 0) return false; - return 25 <= n; + return n >= 25; }, payout: 2, }, @@ -125,7 +121,7 @@ function Single(s: number): Strategy { } export class Roulette extends Game { - interval: number = -1; + interval = -1; rng: WHRNG; constructor(props: IProps) { @@ -140,7 +136,7 @@ export class Roulette extends Game { lock: true, strategy: { payout: 0, - match: (n: number): boolean => { return false }, + match: (): boolean => { return false }, }, } @@ -150,21 +146,21 @@ export class Roulette extends Game { } - componentDidMount() { + componentDidMount(): void { this.interval = setInterval(this.step, 50); } - step() { + step(): void { if (!this.state.lock) { this.setState({n: Math.floor(Math.random()*37)}); } } - componentWillUnmount() { + componentWillUnmount(): void { clearInterval(this.interval); } - updateInvestment(e: React.FormEvent) { + updateInvestment(e: React.FormEvent): void { let investment: number = parseInt(e.currentTarget.value); if (isNaN(investment)) { investment = minPlay; @@ -178,13 +174,13 @@ export class Roulette extends Game { this.setState({investment: investment}); } - currentNumber() { + currentNumber(): string { if (this.state.n === 0) return '0'; const color = isRed(this.state.n) ? 'R' : 'B'; return `${this.state.n}${color}`; } - play(s: Strategy) { + play(s: Strategy): void { if(this.reachedLimit(this.props.p)) return; this.setState({ canPlay: false, @@ -223,10 +219,10 @@ export class Roulette extends Game { } - render() { + render(): React.ReactNode { return <>

    {this.currentNumber()}

    - +

    {this.state.status}

    diff --git a/src/Casino/SlotMachine.tsx b/src/Casino/SlotMachine.tsx index 470ef5301..7b61934a8 100644 --- a/src/Casino/SlotMachine.tsx +++ b/src/Casino/SlotMachine.tsx @@ -20,7 +20,7 @@ type IState = { } // statically shuffled array of symbols. -let symbols = ["D", "C", "$", "?", "♥", "A", "C", "B", "C", "E", "B", "E", "C", +const symbols = ["D", "C", "$", "?", "♥", "A", "C", "B", "C", "E", "B", "E", "C", "*", "D", "♥", "B", "A", "A", "A", "C", "A", "D", "B", "E", "?", "D", "*", "@", "♥", "B", "E", "?"]; @@ -63,7 +63,7 @@ const maxPlay = 1e6; export class SlotMachine extends Game { rng: WHRNG; - interval: number = -1; + interval = -1; constructor(props: IProps) { super(props); @@ -86,11 +86,11 @@ export class SlotMachine extends Game { this.updateInvestment = this.updateInvestment.bind(this); } - componentDidMount() { + componentDidMount(): void { this.interval = setInterval(this.step, 50); } - step() { + step(): void { let stoppedOne = false; const index = this.state.index.slice(); for(const i in index) { @@ -106,7 +106,7 @@ export class SlotMachine extends Game { } } - componentWillUnmount() { + componentWillUnmount(): void { clearInterval(this.interval); } @@ -118,7 +118,7 @@ export class SlotMachine extends Game { ]; } - play() { + play(): void { if(this.reachedLimit(this.props.p)) return; this.setState({status: 'playing'}); this.win(this.props.p, -this.state.investment); @@ -127,7 +127,7 @@ export class SlotMachine extends Game { setTimeout(this.lock, this.rng.random()*2000+1000); } - lock() { + lock(): void { this.setState({ locks: [ Math.floor(this.rng.random()*symbols.length), @@ -139,10 +139,10 @@ export class SlotMachine extends Game { }) } - checkWinnings() { + checkWinnings(): void { const t = this.getTable(); const getPaylineData = function(payline: number[][]): string[] { - let data = []; + const data = []; for(const point of payline) { data.push(t[point[0]][point[1]]); } @@ -176,14 +176,14 @@ export class SlotMachine extends Game { if(this.reachedLimit(this.props.p)) return; } - unlock() { + unlock(): void { this.setState({ locks: [-1, -1, -1, -1, -1], canPlay: false, }) } - updateInvestment(e: React.FormEvent) { + updateInvestment(e: React.FormEvent): void { let investment: number = parseInt(e.currentTarget.value); if (isNaN(investment)) { investment = minPlay; @@ -197,7 +197,7 @@ export class SlotMachine extends Game { this.setState({investment: investment}); } - render() { + render(): React.ReactNode { const t = this.getTable(); return <>
    @@ -209,7 +209,7 @@ export class SlotMachine extends Game {
     | | {symbols[(this.state.index[0]+1)%symbols.length]} | {symbols[(this.state.index[1]+1)%symbols.length]} | {symbols[(this.state.index[2]+1)%symbols.length]} | {symbols[(this.state.index[3]+1)%symbols.length]} | {symbols[(this.state.index[4]+1)%symbols.length]} | |
    +———————————————————————+
    - +

    {this.state.status}

    Pay lines

    diff --git a/src/CinematicText.js b/src/CinematicText.js index f1899a5b9..7cdb67ff4 100644 --- a/src/CinematicText.js +++ b/src/CinematicText.js @@ -90,7 +90,7 @@ function cinematicTextEnd() { var mainMenu = document.getElementById("mainmenu-container"); container.appendChild(createElement("br")); - return new Promise (function(resolve, reject) { + return new Promise (function(resolve) { container.appendChild(createElement("a", { class:"a-link-button", innerText:"Continue...", clickListener:()=>{ @@ -99,7 +99,7 @@ function cinematicTextEnd() { mainMenu.style.visibility = "visible"; cinematicTextFlag = false; resolve(); - } + }, })); }); } diff --git a/src/CodingContractGenerator.ts b/src/CodingContractGenerator.ts index 6b5e62ad4..49f89c4ee 100644 --- a/src/CodingContractGenerator.ts +++ b/src/CodingContractGenerator.ts @@ -2,7 +2,7 @@ import { CodingContract, CodingContractRewardType, CodingContractTypes, - ICodingContractReward + ICodingContractReward, } from "./CodingContracts"; import { Factions } from "./Faction/Factions"; import { Player } from "./Player"; @@ -15,7 +15,7 @@ import { HacknetServer } from "./Hacknet/HacknetServer"; import { getRandomInt } from "../utils/helpers/getRandomInt"; -export function generateRandomContract() { +export function generateRandomContract(): void { // First select a random problem type const problemType = getRandomProblemType(); @@ -31,7 +31,7 @@ export function generateRandomContract() { randServer.addContract(contract); } -export function generateRandomContractOnHome() { +export function generateRandomContractOnHome(): void { // First select a random problem type const problemType = getRandomProblemType(); @@ -53,7 +53,7 @@ export interface IGenerateContractParams { fn?: string; } -export function generateContract(params: IGenerateContractParams) { +export function generateContract(params: IGenerateContractParams): void { // Problem Type let problemType; const problemTypes = Object.keys(CodingContractTypes); @@ -88,7 +88,7 @@ export function generateContract(params: IGenerateContractParams) { fn = getRandomFilename(server, reward); } - let contract = new CodingContract(fn, problemType, reward); + const contract = new CodingContract(fn, problemType, reward); server.addContract(contract); } @@ -117,15 +117,15 @@ function sanitizeRewardType(rewardType: CodingContractRewardType): CodingContrac return type; } -function getRandomProblemType() { +function getRandomProblemType(): string { const problemTypes = Object.keys(CodingContractTypes); - let randIndex = getRandomInt(0, problemTypes.length - 1); + const randIndex = getRandomInt(0, problemTypes.length - 1); return problemTypes[randIndex]; } function getRandomReward(): ICodingContractReward { - let reward: ICodingContractReward = { + const reward: ICodingContractReward = { name: "", type: getRandomInt(0, CodingContractRewardType.Money), }; @@ -145,8 +145,8 @@ function getRandomReward(): ICodingContractReward { case CodingContractRewardType.FactionReputation: { // Get a random faction that player is a part of. That // faction must allow hacking contracts - var numFactions = factionsThatAllowHacking.length; - var randFaction = factionsThatAllowHacking[getRandomInt(0, numFactions - 1)]; + const numFactions = factionsThatAllowHacking.length; + const randFaction = factionsThatAllowHacking[getRandomInt(0, numFactions - 1)]; reward.name = randFaction; break; } diff --git a/src/CodingContracts.ts b/src/CodingContracts.ts index 1af8fb5fa..3b93250b8 100644 --- a/src/CodingContracts.ts +++ b/src/CodingContracts.ts @@ -2,7 +2,7 @@ import { codingContractTypesMetadata, DescriptionFunc, GeneratorFunc, - SolverFunc + SolverFunc, } from "./data/codingcontracttypes"; import { IMap } from "./types"; @@ -10,7 +10,7 @@ import { IMap } from "./types"; import { Generic_fromJSON, Generic_toJSON, - Reviver + Reviver, } from "../utils/JSONReviver"; import { KEY } from "../utils/helpers/keyCodes"; import { createElement } from "../utils/uiHelpers/createElement"; @@ -108,12 +108,6 @@ export interface ICodingContractReward { * The player receives a reward if the problem is solved correctly */ export class CodingContract { - /** - * Initiatizes a CodingContract from a JSON save state. - */ - static fromJSON(value: any): CodingContract { - return Generic_fromJSON(CodingContract, value.data); - } /* Relevant data for the contract's problem */ data: any; @@ -126,13 +120,13 @@ export class CodingContract { reward: ICodingContractReward | null; /* Number of times the Contract has been attempted */ - tries: number = 0; + tries = 0; /* String representing the contract's type. Must match type in ContractTypes */ type: string; - constructor(fn: string = "", - type: string = "Find Largest Prime Factor", + constructor(fn = "", + type = "Find Largest Prime Factor", reward: ICodingContractReward | null = null) { this.fn = fn; if (!this.fn.endsWith(".cct")) { @@ -178,9 +172,9 @@ export class CodingContract { */ async prompt(): Promise { // tslint:disable-next-line - return new Promise((resolve: Function, reject: Function) => { + return new Promise((resolve) => { const contractType: CodingContractType = CodingContractTypes[this.type]; - const popupId: string = `coding-contract-prompt-popup-${this.fn}`; + const popupId = `coding-contract-prompt-popup-${this.fn}`; const title: HTMLElement = createElement("h1", { innerHTML: this.type, }); @@ -190,10 +184,16 @@ export class CodingContract { "after which the contract will self-destruct.

    ", `${contractType.desc(this.data).replace(/\n/g, "
    ")}`].join(" "), }); - let answerInput: HTMLInputElement; let solveBtn: HTMLElement; - let cancelBtn: HTMLElement; - answerInput = createElement("input", { + const cancelBtn = createElement("a", { + class: "a-link-button", + clickListener: () => { + resolve(CodingContractResult.Cancelled); + removeElementById(popupId); + }, + innerText: "Cancel", + }); + const answerInput = createElement("input", { onkeydown: (e: any) => { if (e.keyCode === KEY.ENTER && answerInput.value !== "") { e.preventDefault(); @@ -219,14 +219,6 @@ export class CodingContract { }, innerText: "Solve", }); - cancelBtn = createElement("a", { - class: "a-link-button", - clickListener: () => { - resolve(CodingContractResult.Cancelled); - removeElementById(popupId); - }, - innerText: "Cancel", - }); const lineBreak: HTMLElement = createElement("br"); createPopup(popupId, [title, lineBreak, txt, lineBreak, lineBreak, answerInput, solveBtn, cancelBtn]); answerInput.focus(); @@ -239,6 +231,14 @@ export class CodingContract { toJSON(): any { return Generic_toJSON("CodingContract", this); } + + /** + * Initiatizes a CodingContract from a JSON save state. + */ + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types + static fromJSON(value: any): CodingContract { + return Generic_fromJSON(CodingContract, value.data); + } } Reviver.constructors.CodingContract = CodingContract; diff --git a/src/Company/Companies.ts b/src/Company/Companies.ts index 60b78c295..6c775b42c 100644 --- a/src/Company/Companies.ts +++ b/src/Company/Companies.ts @@ -6,7 +6,7 @@ import { Reviver } from "../../utils/JSONReviver"; export let Companies: IMap = {}; -function addCompany(params: IConstructorParams) { +function addCompany(params: IConstructorParams): void { if (Companies[params.name] != null) { console.warn(`Duplicate Company Position being defined: ${params.name}`); } @@ -15,7 +15,7 @@ function addCompany(params: IConstructorParams) { // Used to initialize new Company objects for the Companies map // Called when creating new game or after a prestige/reset -export function initCompanies() { +export function initCompanies(): void { // Save Old Company data for 'favor' const oldCompanies = Companies; @@ -40,11 +40,11 @@ export function initCompanies() { } // Used to load Companies map from a save -export function loadCompanies(saveString: string) { +export function loadCompanies(saveString: string): void { Companies = JSON.parse(saveString, Reviver); } // Utility function to check if a string is valid company name -export function companyExists(name: string) { +export function companyExists(name: string): boolean { return Companies.hasOwnProperty(name); } diff --git a/src/Company/Company.ts b/src/Company/Company.ts index 52dc44cd1..6bf877a94 100644 --- a/src/Company/Company.ts +++ b/src/Company/Company.ts @@ -25,12 +25,6 @@ const DefaultConstructorParams: IConstructorParams = { } export class Company { - /** - * Initiatizes a Company from a JSON save state. - */ - static fromJSON(value: any): Company { - return Generic_fromJSON(Company, value.data); - } /** * Company name @@ -136,7 +130,7 @@ export class Company { gainFavor(): void { if (this.favor == null) { this.favor = 0; } if (this.rolloverRep == null) { this.rolloverRep = 0; } - var res = this.getFavorGain(); + const res = this.getFavorGain(); if (res.length != 2) { console.error("Invalid result from getFavorGain() function"); return; @@ -170,6 +164,14 @@ export class Company { toJSON(): any { return Generic_toJSON("Company", this); } + + /** + * Initiatizes a Company from a JSON save state. + */ + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types + static fromJSON(value: any): Company { + return Generic_fromJSON(Company, value.data); + } } Reviver.constructors.Company = Company; diff --git a/src/Company/CompanyPositions.ts b/src/Company/CompanyPositions.ts index 27578f0d6..097abe2ba 100644 --- a/src/Company/CompanyPositions.ts +++ b/src/Company/CompanyPositions.ts @@ -5,7 +5,7 @@ import { IMap } from "../types"; export const CompanyPositions: IMap = {}; -function addCompanyPosition(params: IConstructorParams) { +function addCompanyPosition(params: IConstructorParams): void { if (CompanyPositions[params.name] != null) { console.warn(`Duplicate Company Position being defined: ${params.name}`); } diff --git a/src/Company/GetJobRequirementText.ts b/src/Company/GetJobRequirementText.ts index b3d023aa9..c9da1b541 100644 --- a/src/Company/GetJobRequirementText.ts +++ b/src/Company/GetJobRequirementText.ts @@ -5,8 +5,8 @@ import { CompanyPosition } from "./CompanyPosition"; * Returns a string with the given CompanyPosition's stat requirements */ -export function getJobRequirementText(company: Company, pos: CompanyPosition, tooltiptext: boolean = false): string { - let reqText: string = ""; +export function getJobRequirementText(company: Company, pos: CompanyPosition, tooltiptext = false): string { + let reqText = ""; const offset: number = company.jobStatReqOffset; const reqHacking: number = pos.requiredHacking > 0 ? pos.requiredHacking+offset : 0; const reqStrength: number = pos.requiredStrength > 0 ? pos.requiredStrength+offset : 0; diff --git a/src/Company/data/CompaniesMetadata.ts b/src/Company/data/CompaniesMetadata.ts index 06f5dc872..a4d833fec 100644 --- a/src/Company/data/CompaniesMetadata.ts +++ b/src/Company/data/CompaniesMetadata.ts @@ -95,7 +95,7 @@ export const companiesMetadata: IConstructorParams[] = [ companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions, - AllSecurityPositions + AllSecurityPositions, ), expMultiplier: 3, salaryMultiplier: 3, @@ -107,7 +107,7 @@ export const companiesMetadata: IConstructorParams[] = [ companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions, - AllSecurityPositions + AllSecurityPositions, ), expMultiplier: 3, salaryMultiplier: 3, @@ -119,7 +119,7 @@ export const companiesMetadata: IConstructorParams[] = [ companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions, - AllSecurityPositions + AllSecurityPositions, ), expMultiplier: 2.6, salaryMultiplier: 2.6, @@ -131,7 +131,7 @@ export const companiesMetadata: IConstructorParams[] = [ companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions, - AllSecurityPositions + AllSecurityPositions, ), expMultiplier: 2.75, salaryMultiplier: 2.75, @@ -143,7 +143,7 @@ export const companiesMetadata: IConstructorParams[] = [ companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions, - AllSecurityPositions + AllSecurityPositions, ), expMultiplier: 2.75, salaryMultiplier: 2.75, @@ -155,7 +155,7 @@ export const companiesMetadata: IConstructorParams[] = [ companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions, - AllSecurityPositions + AllSecurityPositions, ), expMultiplier: 2.25, salaryMultiplier: 2.25, @@ -167,7 +167,7 @@ export const companiesMetadata: IConstructorParams[] = [ companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions, - AllSecurityPositions + AllSecurityPositions, ), expMultiplier: 2.25, salaryMultiplier: 2.25, @@ -179,7 +179,7 @@ export const companiesMetadata: IConstructorParams[] = [ companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions, - AllSecurityPositions + AllSecurityPositions, ), expMultiplier: 2.5, salaryMultiplier: 2.5, @@ -191,7 +191,7 @@ export const companiesMetadata: IConstructorParams[] = [ companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions, - AllSecurityPositions + AllSecurityPositions, ), expMultiplier: 2.2, salaryMultiplier: 2.2, @@ -202,7 +202,7 @@ export const companiesMetadata: IConstructorParams[] = [ info: "", companyPositions: Object.assign({}, AllTechnologyPositions, - AllBusinessPositions + AllBusinessPositions, ), expMultiplier: 2, salaryMultiplier: 2, @@ -214,7 +214,7 @@ export const companiesMetadata: IConstructorParams[] = [ companyPositions: Object.assign({}, AllTechnologyPositions, AllSoftwareConsultantPositions, - AllBusinessPositions + AllBusinessPositions, ), expMultiplier: 1.8, salaryMultiplier: 1.8, @@ -226,7 +226,7 @@ export const companiesMetadata: IConstructorParams[] = [ companyPositions: Object.assign({}, CEOOnly, AllTechnologyPositions, - AllSoftwareConsultantPositions + AllSoftwareConsultantPositions, ), expMultiplier: 1.75, salaryMultiplier: 1.75, @@ -238,7 +238,7 @@ export const companiesMetadata: IConstructorParams[] = [ companyPositions: Object.assign({}, CEOOnly, AllTechnologyPositions, - AllSoftwareConsultantPositions + AllSoftwareConsultantPositions, ), expMultiplier: 1.8, salaryMultiplier: 1.8, @@ -250,7 +250,7 @@ export const companiesMetadata: IConstructorParams[] = [ companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions, - AllSoftwareConsultantPositions + AllSoftwareConsultantPositions, ), expMultiplier: 1.8, salaryMultiplier: 1.8, @@ -262,7 +262,7 @@ export const companiesMetadata: IConstructorParams[] = [ companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions, - AllSoftwareConsultantPositions + AllSoftwareConsultantPositions, ), expMultiplier: 1.9, salaryMultiplier: 1.9, @@ -274,7 +274,7 @@ export const companiesMetadata: IConstructorParams[] = [ companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions, - AllSoftwareConsultantPositions + AllSoftwareConsultantPositions, ), expMultiplier: 2, salaryMultiplier: 2, @@ -286,7 +286,7 @@ export const companiesMetadata: IConstructorParams[] = [ companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions, - AllSoftwareConsultantPositions + AllSoftwareConsultantPositions, ), expMultiplier: 1.9, salaryMultiplier: 1.9, @@ -299,7 +299,7 @@ export const companiesMetadata: IConstructorParams[] = [ CEOOnly, OperationsManagerOnly, AllTechnologyPositions, - AllSecurityPositions + AllSecurityPositions, ), expMultiplier: 1.7, salaryMultiplier: 1.7, @@ -351,7 +351,7 @@ export const companiesMetadata: IConstructorParams[] = [ AllTechnologyPositions, AllBusinessPositions, AllSoftwareConsultantPositions, - AllSecurityPositions + AllSecurityPositions, ), expMultiplier: 1.8, salaryMultiplier: 1.8, @@ -364,7 +364,7 @@ export const companiesMetadata: IConstructorParams[] = [ AllTechnologyPositions, AllBusinessPositions, AllSoftwareConsultantPositions, - AllSecurityPositions + AllSecurityPositions, ), expMultiplier: 1.75, salaryMultiplier: 1.75, @@ -379,7 +379,7 @@ export const companiesMetadata: IConstructorParams[] = [ SecurityEngineerPositions, AllITPositions, AllSecurityPositions, - AllAgentPositions + AllAgentPositions, ), expMultiplier: 2, salaryMultiplier: 2, @@ -394,7 +394,7 @@ export const companiesMetadata: IConstructorParams[] = [ SecurityEngineerPositions, AllITPositions, AllSecurityPositions, - AllAgentPositions + AllAgentPositions, ), expMultiplier: 2, salaryMultiplier: 2, @@ -409,7 +409,7 @@ export const companiesMetadata: IConstructorParams[] = [ AllITPositions, AllSecurityPositions, AllAgentPositions, - AllSoftwareConsultantPositions + AllSoftwareConsultantPositions, ), expMultiplier: 1.5, salaryMultiplier: 1.5, @@ -422,7 +422,7 @@ export const companiesMetadata: IConstructorParams[] = [ AllTechnologyPositions, AllSoftwareConsultantPositions, AllBusinessPositions, - AllSecurityPositions + AllSecurityPositions, ), expMultiplier: 1.4, salaryMultiplier: 1.4, @@ -433,7 +433,7 @@ export const companiesMetadata: IConstructorParams[] = [ info: "", companyPositions: Object.assign({}, SoftwarePositionsUpToLeadDeveloper, - BusinessPositionsUpToOperationsManager + BusinessPositionsUpToOperationsManager, ), expMultiplier: 1.3, salaryMultiplier: 1.3, @@ -445,7 +445,7 @@ export const companiesMetadata: IConstructorParams[] = [ companyPositions: Object.assign({}, SoftwarePositionsUpToLeadDeveloper, BusinessPositionsUpToOperationsManager, - AllSoftwareConsultantPositions + AllSoftwareConsultantPositions, ), expMultiplier: 1.5, salaryMultiplier: 1.5, @@ -456,7 +456,7 @@ export const companiesMetadata: IConstructorParams[] = [ info: "", companyPositions: Object.assign({}, AllSecurityPositions, - SoftwarePositionsUpToLeadDeveloper + SoftwarePositionsUpToLeadDeveloper, ), expMultiplier: 1.3, salaryMultiplier: 1.3, @@ -466,7 +466,7 @@ export const companiesMetadata: IConstructorParams[] = [ name: LocationName.VolhavenSysCoreSecurities, info: "", companyPositions: Object.assign({}, - AllTechnologyPositions + AllTechnologyPositions, ), expMultiplier: 1.3, salaryMultiplier: 1.3, @@ -476,7 +476,7 @@ export const companiesMetadata: IConstructorParams[] = [ name: LocationName.VolhavenCompuTek, info: "", companyPositions: Object.assign({}, - AllTechnologyPositions + AllTechnologyPositions, ), expMultiplier: 1.2, salaryMultiplier: 1.2, @@ -486,7 +486,7 @@ export const companiesMetadata: IConstructorParams[] = [ name: LocationName.AevumNetLinkTechnologies, info: "", companyPositions: Object.assign({}, - AllTechnologyPositions + AllTechnologyPositions, ), expMultiplier: 1.2, salaryMultiplier: 1.2, @@ -509,7 +509,7 @@ export const companiesMetadata: IConstructorParams[] = [ name: LocationName.Sector12FoodNStuff, info: "", companyPositions: Object.assign({}, - EmployeeOnly, PartTimeEmployeeOnly + EmployeeOnly, PartTimeEmployeeOnly, ), expMultiplier: 1, salaryMultiplier: 1, @@ -519,7 +519,7 @@ export const companiesMetadata: IConstructorParams[] = [ name: LocationName.Sector12JoesGuns, info: "", companyPositions: Object.assign({}, - EmployeeOnly, PartTimeEmployeeOnly + EmployeeOnly, PartTimeEmployeeOnly, ), expMultiplier: 1, salaryMultiplier: 1, @@ -531,7 +531,7 @@ export const companiesMetadata: IConstructorParams[] = [ companyPositions: Object.assign({}, AllSoftwarePositions, AllSoftwareConsultantPositions, - AllITPositions + AllITPositions, ), expMultiplier: 1.1, salaryMultiplier: 1.1, @@ -541,7 +541,7 @@ export const companiesMetadata: IConstructorParams[] = [ name: LocationName.NewTokyoNoodleBar, info: "", companyPositions: Object.assign({}, - WaiterOnly, PartTimeWaiterOnly + WaiterOnly, PartTimeWaiterOnly, ), expMultiplier: 1, salaryMultiplier: 1, diff --git a/src/Company/data/companypositionnames.ts b/src/Company/data/companypositionnames.ts index 857e1cfaf..c1d4a46b3 100644 --- a/src/Company/data/companypositionnames.ts +++ b/src/Company/data/companypositionnames.ts @@ -8,23 +8,23 @@ export const SoftwareCompanyPositions: string[] = [ "Head of Software", "Head of Engineering", "Vice President of Technology", - "Chief Technology Officer" + "Chief Technology Officer", ]; export const ITCompanyPositions: string[] = [ "IT Intern", "IT Analyst", "IT Manager", - "Systems Administrator" + "Systems Administrator", ]; export const SecurityEngineerCompanyPositions: string[] = [ - "Security Engineer" + "Security Engineer", ]; export const NetworkEngineerCompanyPositions: string[] = [ "Network Engineer", - "Network Administrator" + "Network Administrator", ]; export const BusinessCompanyPositions: string[] = [ @@ -33,7 +33,7 @@ export const BusinessCompanyPositions: string[] = [ "Business Manager", "Operations Manager", "Chief Financial Officer", - "Chief Executive Officer" + "Chief Executive Officer", ]; export const SecurityCompanyPositions: string[] = [ @@ -42,31 +42,31 @@ export const SecurityCompanyPositions: string[] = [ "Security Guard", "Security Officer", "Security Supervisor", - "Head of Security" + "Head of Security", ]; export const AgentCompanyPositions: string[] = [ "Field Agent", "Secret Agent", - "Special Operative" + "Special Operative", ]; export const MiscCompanyPositions: string[] = [ "Waiter", - "Employee" + "Employee", ]; export const SoftwareConsultantCompanyPositions: string[] = [ "Software Consultant", - "Senior Software Consultant" + "Senior Software Consultant", ]; export const BusinessConsultantCompanyPositions: string[] = [ "Business Consultant", - "Senior Business Consultant" + "Senior Business Consultant", ]; export const PartTimeCompanyPositions: string[] = [ "Part-time Waiter", - "Part-time Employee" + "Part-time Employee", ]; diff --git a/src/Constants.ts b/src/Constants.ts index 14e846d84..de47de68c 100644 --- a/src/Constants.ts +++ b/src/Constants.ts @@ -5,7 +5,7 @@ */ import { IMap } from "./types"; -export let CONSTANTS: IMap = { +export const CONSTANTS: IMap = { Version: "0.51.6", /** Max level for any skill, assuming no multipliers. Determined by max numerical value in javascript for experience @@ -268,5 +268,5 @@ export let CONSTANTS: IMap = { * so many documentation and typos fixes (@Pimgd) * A corruption visual effect has been added to location with servers that have backdoor installed. (@dewint) - ` + `, } \ No newline at end of file diff --git a/src/Corporation/Corporation.jsx b/src/Corporation/Corporation.jsx index 08403439a..4d9809401 100644 --- a/src/Corporation/Corporation.jsx +++ b/src/Corporation/Corporation.jsx @@ -5,7 +5,6 @@ import { CorporationUpgrades } from "./data/Corporation import { EmployeePositions } from "./EmployeePositions"; import { Industries, IndustryStartingCosts, - IndustryDescriptions, IndustryResearchTrees } from "./IndustryData"; import { IndustryUpgrades } from "./IndustryUpgrades"; import { Material } from "./Material"; @@ -15,11 +14,8 @@ import { ResearchMap } from "./ResearchMap"; import { Warehouse } from "./Warehouse"; import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; -import { CONSTANTS } from "../Constants"; -import { Factions } from "../Faction/Factions"; import { showLiterature } from "../Literature/LiteratureHelpers"; import { LiteratureNames } from "../Literature/data/LiteratureNames"; -import { createCityMap } from "../Locations/Cities"; import { CityName } from "../Locations/data/CityNames"; import { Player } from "../Player"; @@ -29,7 +25,6 @@ import { Page, routing } from "../ui/navigationTr import { calculateEffectWithFactors } from "../utils/calculateEffectWithFactors"; import { dialogBoxCreate } from "../../utils/DialogBox"; -import { clearSelector } from "../../utils/uiHelpers/clearSelector"; import { Reviver, Generic_toJSON, Generic_fromJSON } from "../../utils/JSONReviver"; @@ -99,7 +94,6 @@ export const BaseMaxProducts = 3; // Initial value for maximum let researchTreeBoxOpened = false; let researchTreeBox = null; $(document).mousedown(function(event) { - const boxId = "corporation-research-popup-box"; const contentId = "corporation-research-popup-box-content"; if (researchTreeBoxOpened) { if ( $(event.target).closest("#" + contentId).get(0) == null ) { @@ -111,7 +105,6 @@ $(document).mousedown(function(event) { } }); -var empManualAssignmentModeActive = false; function Industry(params={}) { this.offices = { //Maps locations to offices. 0 if no office at that location [CityName.Aevum]: 0, @@ -122,7 +115,7 @@ function Industry(params={}) { }), [CityName.NewTokyo]: 0, [CityName.Ishima]: 0, - [CityName.Volhaven]: 0 + [CityName.Volhaven]: 0, }; this.name = params.name ? params.name : 0; @@ -183,7 +176,7 @@ function Industry(params={}) { }), [CityName.NewTokyo]: 0, [CityName.Ishima]: 0, - [CityName.Volhaven]: 0 + [CityName.Volhaven]: 0, }; this.init(); @@ -378,7 +371,7 @@ Industry.prototype.init = function() { "Metal": 5, "Energy": 5, "Water": 2, - "Hardware": 4 + "Hardware": 4, } this.prodMats = ["RealEstate"]; this.makesProducts = true; @@ -441,8 +434,7 @@ Industry.prototype.calculateProductionFactors = function() { continue; } - var materials = warehouse.materials, - office = this.offices[city]; + var materials = warehouse.materials; var cityMult = Math.pow(0.002 * materials.RealEstate.qty+1, this.reFac) * Math.pow(0.002 * materials.Hardware.qty+1, this.hwFac) * @@ -535,7 +527,7 @@ Industry.prototype.process = function(marketCycles=1, state, company) { } // Process change in demand and competition for this industry's materials -Industry.prototype.processMaterialMarket = function(marketCycles=1) { +Industry.prototype.processMaterialMarket = function() { //References to prodMats and reqMats var reqMats = this.reqMats, prodMats = this.prodMats; @@ -589,7 +581,7 @@ Industry.prototype.processProductMarket = function(marketCycles=1) { //Process production, purchase, and import/export of materials Industry.prototype.processMaterials = function(marketCycles=1, company) { - var revenue = 0, expenses = 0, industry = this; + var revenue = 0, expenses = 0; this.calculateProductionFactors(); //At the start of the export state, set the imports of everything to 0 @@ -642,7 +634,7 @@ Industry.prototype.processMaterials = function(marketCycles=1, company) { mat.qty += buyAmt; expenses += (buyAmt * mat.bCost); } - })(matName, industry); + })(matName, this); this.updateWarehouseSizeUsed(warehouse); } } //End process purchase of materials @@ -1003,7 +995,7 @@ Industry.prototype.processProduct = function(marketCycles=1, product, corporatio if (warehouse instanceof Warehouse) { switch(this.state) { - case "PRODUCTION": + case "PRODUCTION": { //Calculate the maximum production of this material based //on the office's productivity var maxProd = this.getOfficeProductivity(office, {forProduct:true}) @@ -1065,8 +1057,8 @@ Industry.prototype.processProduct = function(marketCycles=1, product, corporatio //Keep track of production Per second product.data[city][1] = prod * producableFrac / (SecsPerMarketCycle * marketCycles); break; - - case "SALE": + } + case "SALE": { //Process sale of Products product.pCost = 0; //Estimated production cost for (var reqMatName in product.reqMats) { @@ -1174,7 +1166,7 @@ Industry.prototype.processProduct = function(marketCycles=1, product, corporatio product.data[city][2] = 0; //data[2] is sell property } break; - + } case "START": case "PURCHASE": case "EXPORT": @@ -1199,10 +1191,9 @@ Industry.prototype.discontinueProduct = function(product) { } Industry.prototype.upgrade = function(upgrade, refs) { - var corporation = refs.corporation, division = refs.division, - office = refs.office; - var upgN = upgrade[0], basePrice = upgrade[1], priceMult = upgrade[2], - upgradeBenefit = upgrade[3]; + var corporation = refs.corporation; + var office = refs.office; + var upgN = upgrade[0]; while (this.upgrades.length <= upgN) {this.upgrades.push(0);} ++this.upgrades[upgN]; @@ -1374,9 +1365,6 @@ Industry.prototype.createResearchBox = function() { }, } - // Construct the tree with Treant - const treantTree = new Treant(markup); - // Add Event Listeners for all Nodes const allResearch = researchTree.getAllNodes(); for (let i = 0; i < allResearch.length; ++i) { @@ -1620,7 +1608,7 @@ var OfficeSpaceTiers = { Basic: "Basic", Enhanced: "Enhanced", Luxurious: "Luxurious", - Extravagant: "Extravagant" + Extravagant: "Extravagant", } function OfficeSpace(params={}) { @@ -1658,7 +1646,7 @@ OfficeSpace.prototype.atCapacity = function() { } OfficeSpace.prototype.process = function(marketCycles=1, parentRefs) { - var corporation = parentRefs.corporation, industry = parentRefs.industry; + var industry = parentRefs.industry; // HRBuddy AutoRecruitment and training if (industry.hasResearch("HRBuddy-Recruitment") && !this.atCapacity()) { @@ -1741,7 +1729,6 @@ OfficeSpace.prototype.calculateEmployeeProductivity = function(parentRefs) { //Takes care of UI as well OfficeSpace.prototype.findEmployees = function(parentRefs) { - var company = parentRefs.corporation, division = parentRefs.industry; if (this.atCapacity()) { return; } if (document.getElementById("cmpy-mgmt-hire-employee-popup") != null) {return;} @@ -1800,7 +1787,7 @@ OfficeSpace.prototype.findEmployees = function(parentRefs) { office.hireEmployee(employee, parentRefs); removeElementById("cmpy-mgmt-hire-employee-popup"); return false; - } + }, }); return div; }; @@ -1812,7 +1799,7 @@ OfficeSpace.prototype.findEmployees = function(parentRefs) { clickListener:() => { removeElementById("cmpy-mgmt-hire-employee-popup"); return false; - } + }, }); var elems = [text, @@ -1825,7 +1812,7 @@ OfficeSpace.prototype.findEmployees = function(parentRefs) { } OfficeSpace.prototype.hireEmployee = function(employee, parentRefs) { - var company = parentRefs.corporation, division = parentRefs.industry; + var company = parentRefs.corporation; var yesBtn = yesNoTxtInpBoxGetYesButton(), noBtn = yesNoTxtInpBoxGetNoButton(); yesBtn.innerHTML = "Hire"; @@ -1958,15 +1945,14 @@ Corporation.prototype.storeCycles = function(numCycles=1) { } Corporation.prototype.process = function() { - var corp = this; if (this.storedCycles >= CyclesPerIndustryStateCycle) { const state = this.getState(); const marketCycles = 1; const gameCycles = (marketCycles * CyclesPerIndustryStateCycle); this.storedCycles -= gameCycles; - this.divisions.forEach(function(ind) { - ind.process(marketCycles, state, corp); + this.divisions.forEach((ind) => { + ind.process(marketCycles, state, this); }); // Process cooldowns @@ -2111,7 +2097,7 @@ Corporation.prototype.goPublic = function() { onkeyup:(e) => { e.preventDefault(); if (e.keyCode === KEY.ENTER) {yesBtn.click();} - } + }, }); var br = createElement("br", {}); yesBtn = createElement("a", { @@ -2138,7 +2124,7 @@ Corporation.prototype.goPublic = function() { dialogBoxCreate(`You took your ${this.name} public and earned ` + `${numeralWrapper.formatMoney(numShares * initialSharePrice)} in your IPO`); return false; - } + }, }); var noBtn = createElement("a", { class:"a-link-button", @@ -2146,7 +2132,7 @@ Corporation.prototype.goPublic = function() { clickListener:() => { removeElementById(goPublicPopupId); return false; - } + }, }); createPopup(goPublicPopupId, [txt, br, input, yesBtn, noBtn]); } @@ -2208,7 +2194,6 @@ Corporation.prototype.calculateShareSale = function(numShares) { Corporation.prototype.convertCooldownToString = function(cd) { // The cooldown value is based on game cycles. Convert to a simple string - const CyclesPerSecond = 1000 / CONSTANTS.MilliPerCycle; const seconds = cd / 5; const SecondsPerMinute = 60; @@ -2351,7 +2336,7 @@ Corporation.prototype.createUI = function() { companyManagementDiv = createElement("div", { id:"cmpy-mgmt-container", position:"fixed", - class:"generic-menupage-container" + class:"generic-menupage-container", }); document.getElementById("entire-game-container").appendChild(companyManagementDiv); diff --git a/src/Corporation/CorporationState.ts b/src/Corporation/CorporationState.ts index adc474496..1a7b2f806 100644 --- a/src/Corporation/CorporationState.ts +++ b/src/Corporation/CorporationState.ts @@ -6,16 +6,10 @@ import { Generic_fromJSON, export const AllCorporationStates: string[] = ["START", "PURCHASE", "PRODUCTION", "SALE", "EXPORT"]; export class CorporationState { - // Initiatizes a CorporationState object from a JSON save state. - static fromJSON(value: any): CorporationState { - return Generic_fromJSON(CorporationState, value.data); - } // Number representing what state the Corporation is in. The number // is an index for the array that holds all Corporation States - state: number = 0; - - constructor() {} + state = 0; // Get the name of the current state // NOTE: This does NOT return the number stored in the 'state' property, @@ -40,6 +34,12 @@ export class CorporationState { toJSON(): any { return Generic_toJSON("CorporationState", this); } + + // Initiatizes a CorporationState object from a JSON save state. + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types + static fromJSON(value: any): CorporationState { + return Generic_fromJSON(CorporationState, value.data); + } } Reviver.constructors.CorporationState = CorporationState; diff --git a/src/Corporation/IndustryData.ts b/src/Corporation/IndustryData.ts index f085f7bcc..a7154026f 100644 --- a/src/Corporation/IndustryData.ts +++ b/src/Corporation/IndustryData.ts @@ -4,8 +4,6 @@ import { getBaseResearchTreeCopy, import { numeralWrapper } from "../ui/numeralFormat"; -import { Reviver } from "../../utils/JSONReviver"; - interface IIndustryMap { Energy: T; Utilities: T; @@ -107,7 +105,7 @@ export const IndustryDescriptions: IIndustryMap = { // Map of available Research for each Industry. This data is held in a // ResearchTree object -export let IndustryResearchTrees: IIndustryMap = { +export const IndustryResearchTrees: IIndustryMap = { Energy: getBaseResearchTreeCopy(), Utilities: getBaseResearchTreeCopy(), Agriculture: getBaseResearchTreeCopy(), @@ -124,7 +122,7 @@ export let IndustryResearchTrees: IIndustryMap = { RealEstate: getProductIndustryResearchTreeCopy(), } -export function resetIndustryResearchTrees() { +export function resetIndustryResearchTrees(): void { IndustryResearchTrees.Energy = getBaseResearchTreeCopy(); IndustryResearchTrees.Utilities = getBaseResearchTreeCopy(); IndustryResearchTrees.Agriculture = getBaseResearchTreeCopy(); diff --git a/src/Corporation/IndustryUpgrades.ts b/src/Corporation/IndustryUpgrades.ts index 71b0d7ff7..d83ada87f 100644 --- a/src/Corporation/IndustryUpgrades.ts +++ b/src/Corporation/IndustryUpgrades.ts @@ -11,5 +11,5 @@ export const IndustryUpgrades: IMap = { "this upgrade grants your company a static increase of 3 and 1 to its awareness and " + "popularity, respectively. It will then increase your company's awareness by 1%, and its popularity " + "by a random percentage between 1% and 3%. These effects are increased by other upgrades " + - "that increase the power of your advertising."] + "that increase the power of your advertising."], } diff --git a/src/Corporation/Material.ts b/src/Corporation/Material.ts index abf4bb86b..29a165dd7 100644 --- a/src/Corporation/Material.ts +++ b/src/Corporation/Material.ts @@ -7,56 +7,52 @@ interface IConstructorParams { } export class Material { - // Initiatizes a Material object from a JSON save state. - static fromJSON(value: any): Material { - return Generic_fromJSON(Material, value.data); - } // Name of material - name: string = "InitName"; + name = "InitName"; // Amount of material owned - qty: number = 0; + qty = 0; // Material's "quality". Unbounded - qlt: number = 0; + qlt = 0; // How much demand the Material has in the market, and the range of possible // values for this "demand" - dmd: number = 0; + dmd = 0; dmdR: number[] = [0, 0]; // How much competition there is for this Material in the market, and the range // of possible values for this "competition" - cmp: number = 0; + cmp = 0; cmpR: number[] = [0, 0]; // Maximum volatility of this Materials stats - mv: number = 0; + mv = 0; // Markup. Determines how high of a price you can charge on the material // compared to the market price without suffering loss in # of sales // Quality is divided by this to determine markup limits // e,g, If mku is 10 and quality is 100 then you can markup prices by 100/10 = 10 - mku: number = 0; + mku = 0; // How much of this material is being bought, sold, imported and produced every second - buy: number = 0; - sll: number = 0; - prd: number = 0; - imp: number = 0; + buy = 0; + sll = 0; + prd = 0; + imp = 0; // Exports of this material to another warehouse/industry exp: any[] = []; // Total amount of this material exported in the last cycle - totalExp: number = 0; + totalExp = 0; // Cost / sec to buy this material. AKA Market Price - bCost: number = 0; + bCost = 0; // Cost / sec to sell this material - sCost: number = 0; + sCost = 0; // Flags to keep track of whether production and/or sale of this material is limited // [Whether production/sale is limited, limit amount] @@ -64,9 +60,9 @@ export class Material { sllman: any[] = [false, 0]; // Sale // Flags that signal whether automatic sale pricing through Market TA is enabled - marketTa1: boolean = false; - marketTa2: boolean = false; - marketTa2Price: number = 0; + marketTa1 = false; + marketTa2 = false; + marketTa2Price = 0; constructor(params: IConstructorParams = {}) { if (params.name) { this.name = params.name; } @@ -166,7 +162,7 @@ export class Material { const compChange: number = 1 + compVolatility; if (Math.random() < 0.5) { this.cmp *= compChange; - if (this.cmp > this.cmpR[1]) {this.cmp = this.cmpR[1]}; + if (this.cmp > this.cmpR[1]) {this.cmp = this.cmpR[1]} this.bCost *= (1 / priceChange); // Competition increases, so price goes down } else { this.cmp *= (1 / compChange); @@ -192,6 +188,12 @@ export class Material { toJSON(): any { return Generic_toJSON("Material", this); } + + // Initiatizes a Material object from a JSON save state. + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types + static fromJSON(value: any): Material { + return Generic_fromJSON(Material, value.data); + } } Reviver.constructors.Material = Material; diff --git a/src/Corporation/Product.ts b/src/Corporation/Product.ts index 902b0015b..974f8e4a9 100644 --- a/src/Corporation/Product.ts +++ b/src/Corporation/Product.ts @@ -42,49 +42,45 @@ interface IIndustry { export class Product { - // Initiatizes a Product object from a JSON save state. - static fromJSON(value: any): Product { - return Generic_fromJSON(Product, value.data); - } // Product name - name: string = ""; + name = ""; // The demand for this Product in the market. Gradually decreases - dmd: number = 0; + dmd = 0; // How much competition there is in the market for this Product - cmp: number = 0; + cmp = 0; // Markup. Affects how high of a price you can charge for this Product // without suffering a loss in the # of sales - mku: number = 0; + mku = 0; // Production cost - estimation of how much money it costs to make this Product - pCost: number = 0; + pCost = 0; // Sell cost - sCost: number = 0; + sCost = 0; // Variables for handling the creation process of this Product - fin: boolean = false; // Whether this Product has finished being created - prog: number = 0; // Creation progress - A number betwee 0-100 representing percentage - createCity: string = ""; // City in which the product is/was being created - designCost: number = 0; // How much money was invested into designing this Product - advCost: number = 0; // How much money was invested into advertising this Product + fin = false; // Whether this Product has finished being created + prog = 0; // Creation progress - A number betwee 0-100 representing percentage + createCity = ""; // City in which the product is/was being created + designCost = 0; // How much money was invested into designing this Product + advCost = 0; // How much money was invested into advertising this Product // Aggregate score for this Product's 'rating' // This is based on the stats/properties below. The weighting of the // stats/properties below differs between different industries - rat: number = 0; + rat = 0; // Stats/properties of this Product - qlt: number = 0; - per: number = 0; - dur: number = 0; - rel: number = 0; - aes: number = 0; - fea: number = 0; + qlt = 0; + per = 0; + dur = 0; + rel = 0; + aes = 0; + fea = 0; // Data refers to the production, sale, and quantity of the products // These values are specific to a city @@ -93,11 +89,11 @@ export class Product { // Location of this Product // Only applies for location-based products like restaurants/hospitals - loc: string = ""; + loc = ""; // How much space 1 unit of the Product takes (in the warehouse) // Not applicable for all Products - siz: number = 0; + siz = 0; // Material requirements. An object that maps the name of a material to how much it requires // to make 1 unit of the product. @@ -110,8 +106,8 @@ export class Product { sllman: IMap = createCityMap([false, 0]); // Flags that signal whether automatic sale pricing through Market TA is enabled - marketTa1: boolean = false; - marketTa2: boolean = false; + marketTa1 = false; + marketTa2 = false; marketTa2Price: IMap = createCityMap(0); constructor(params: IConstructorParams={}) { @@ -135,7 +131,7 @@ export class Product { // empWorkMult is a multiplier that increases progress rate based on // productivity of employees - createProduct(marketCycles: number=1, empWorkMult: number=1): void { + createProduct(marketCycles=1, empWorkMult=1): void { if (this.fin) { return; } this.prog += (marketCycles * .01 * empWorkMult); } @@ -145,18 +141,18 @@ export class Product { this.fin = true; //Calculate properties - var progrMult = this.prog / 100; + const progrMult = this.prog / 100; const engrRatio = employeeProd[EmployeePositions.Engineer] / employeeProd["total"]; const mgmtRatio = employeeProd[EmployeePositions.Management] / employeeProd["total"]; const rndRatio = employeeProd[EmployeePositions.RandD] / employeeProd["total"]; const opsRatio = employeeProd[EmployeePositions.Operations] / employeeProd["total"]; const busRatio = employeeProd[EmployeePositions.Business] / employeeProd["total"]; - var designMult = 1 + (Math.pow(this.designCost, 0.1) / 100); - var balanceMult = (1.2 * engrRatio) + (0.9 * mgmtRatio) + (1.3 * rndRatio) + + const designMult = 1 + (Math.pow(this.designCost, 0.1) / 100); + const balanceMult = (1.2 * engrRatio) + (0.9 * mgmtRatio) + (1.3 * rndRatio) + (1.5 * opsRatio) + (busRatio); - var sciMult = 1 + (Math.pow(industry.sciResearch.qty, industry.sciFac) / 800); - var totalMult = progrMult * balanceMult * designMult * sciMult; + const sciMult = 1 + (Math.pow(industry.sciResearch.qty, industry.sciFac) / 800); + const totalMult = progrMult * balanceMult * designMult * sciMult; this.qlt = totalMult * ((0.10 * employeeProd[EmployeePositions.Engineer]) + (0.05 * employeeProd[EmployeePositions.Management]) + @@ -189,14 +185,14 @@ export class Product { (0.05 * employeeProd[EmployeePositions.Operations]) + (0.05 * employeeProd[EmployeePositions.Business])); this.calculateRating(industry); - var advMult = 1 + (Math.pow(this.advCost, 0.1) / 100); + const advMult = 1 + (Math.pow(this.advCost, 0.1) / 100); this.mku = 100 / (advMult * Math.pow((this.qlt + 0.001), 0.65) * (busRatio + mgmtRatio)); this.dmd = industry.awareness === 0 ? 20 : Math.min(100, advMult * (100 * (industry.popularity / industry.awareness))); this.cmp = getRandomInt(0, 70); //Calculate the product's required materials //For now, just set it to be the same as the requirements to make materials - for (var matName in industry.reqMats) { + for (const matName in industry.reqMats) { if (industry.reqMats.hasOwnProperty(matName)) { this.reqMats[matName] = industry.reqMats[matName]; } @@ -205,7 +201,7 @@ export class Product { //Calculate the product's size //For now, just set it to be the same size as the requirements to make materials this.siz = 0; - for (var matName in industry.reqMats) { + for (const matName in industry.reqMats) { this.siz += MaterialSizes[matName] * industry.reqMats[matName]; } @@ -240,6 +236,12 @@ export class Product { toJSON(): any { return Generic_toJSON("Product", this); } + + // Initiatizes a Product object from a JSON save state. + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types + static fromJSON(value: any): Product { + return Generic_fromJSON(Product, value.data); + } } Reviver.constructors.Product = Product; diff --git a/src/Corporation/ProductRatingWeights.ts b/src/Corporation/ProductRatingWeights.ts index e19e9298d..8459fa6bf 100644 --- a/src/Corporation/ProductRatingWeights.ts +++ b/src/Corporation/ProductRatingWeights.ts @@ -10,7 +10,7 @@ export interface IProductRatingWeight { Reliability?: number; } -export const ProductRatingWeights: IMap = { +export const ProductRatingWeights: IMap = { [Industries.Food]: { Quality: 0.7, Durability: 0.1, @@ -73,5 +73,5 @@ export const ProductRatingWeights: IMap = { Reliability: 0.1, Aesthetics: 0.35, Features: 0.1, - } + }, } diff --git a/src/Corporation/Research.ts b/src/Corporation/Research.ts index ee017ec06..6c370e8ab 100644 --- a/src/Corporation/Research.ts +++ b/src/Corporation/Research.ts @@ -16,25 +16,25 @@ export interface IConstructorParams { export class Research { // Name of research. This will be used to identify researches in the Research Tree - name: string = ""; + name = ""; // How much scientific research it costs to unlock this - cost: number = 0; + cost = 0; // Description of what the Research does - desc: string = ""; + desc = ""; // All possible generic upgrades for the company, in the form of multipliers - advertisingMult: number = 1; - employeeChaMult: number = 1; - employeeCreMult: number = 1; - employeeEffMult: number = 1; - employeeIntMult: number = 1; - productionMult: number = 1; - productProductionMult: number = 1; - salesMult: number = 1; - sciResearchMult: number = 1; - storageMult: number = 1; + advertisingMult = 1; + employeeChaMult = 1; + employeeCreMult = 1; + employeeEffMult = 1; + employeeIntMult = 1; + productionMult = 1; + productProductionMult = 1; + salesMult = 1; + sciResearchMult = 1; + storageMult = 1; constructor(p: IConstructorParams={name: "", cost: 0, desc: ""}) { this.name = p.name; diff --git a/src/Corporation/ResearchMap.ts b/src/Corporation/ResearchMap.ts index b38b8356b..0159c3283 100644 --- a/src/Corporation/ResearchMap.ts +++ b/src/Corporation/ResearchMap.ts @@ -5,9 +5,9 @@ import { Research, import { researchMetadata } from "./data/ResearchMetadata"; import { IMap } from "../types"; -export let ResearchMap: IMap = {}; +export const ResearchMap: IMap = {}; -function addResearch(p: IConstructorParams) { +function addResearch(p: IConstructorParams): void { if (ResearchMap[p.name] != null) { console.warn(`Duplicate Research being defined: ${p.name}`); } diff --git a/src/Corporation/ResearchTree.ts b/src/Corporation/ResearchTree.ts index 8414631c8..c55a62e43 100644 --- a/src/Corporation/ResearchTree.ts +++ b/src/Corporation/ResearchTree.ts @@ -26,10 +26,10 @@ export class Node { // How much Scientific Research is needed for this // Necessary to show it on the UI - cost: number = 0; + cost = 0; // Whether or not this Research has been unlocked - researched: boolean = false; + researched = false; // Parent node in the tree // The parent node defines the prerequisite Research (there can only be one) @@ -37,7 +37,7 @@ export class Node { parent: Node | null = null; // Name of the Research held in this Node - text: string = ""; + text = ""; constructor(p: IConstructorParams = {cost: 0, text: ""}) { if (ResearchMap[p.text] == null) { @@ -56,21 +56,21 @@ export class Node { } } - addChild(n: Node) { + addChild(n: Node): void { this.children.push(n); n.parent = this; } // Return an object that describes a TreantJS-compatible markup/config for this Node // See: http://fperucic.github.io/treant-js/ - createTreantMarkup(): object { + createTreantMarkup(): any { const childrenArray = []; for (let i = 0; i < this.children.length; ++i) { childrenArray.push(this.children[i].createTreantMarkup()); } // Determine what css class this Node should have in the diagram - let htmlClass: string = ""; + let htmlClass = ""; if (this.researched) { htmlClass = "researched"; } else if (this.parent && this.parent.researched === false) { @@ -109,7 +109,7 @@ export class Node { return null; } - setParent(n: Node) { + setParent(n: Node): void { this.parent = n; } } @@ -124,11 +124,9 @@ export class ResearchTree { // Root Node root: Node | null = null; - constructor() {} - // Return an object that contains a Tree markup for TreantJS (using the JSON approach) // See: http://fperucic.github.io/treant-js/ - createTreantMarkup(): object { + createTreantMarkup(): any { if (this.root == null) { return {}; } const treeMarkup = this.root.createTreantMarkup(); @@ -205,7 +203,7 @@ export class ResearchTree { // Helper function for all the multiplier getter fns getMultiplierHelper(propName: string): number { - let res: number = 1; + let res = 1; if (this.root == null) { return res; } const queue: Node[] = []; diff --git a/src/Corporation/Warehouse.ts b/src/Corporation/Warehouse.ts index 15bdf03b6..ec912fa28 100644 --- a/src/Corporation/Warehouse.ts +++ b/src/Corporation/Warehouse.ts @@ -19,17 +19,13 @@ interface IConstructorParams { } export class Warehouse { - // Initiatizes a Warehouse object from a JSON save state. - static fromJSON(value: any): Warehouse { - return Generic_fromJSON(Warehouse, value.data); - } // Text that describes how the space in this Warehouse is being used // Used to create a tooltip in the UI - breakdown: string = ""; + breakdown = ""; // Warehouse's level, which affects its maximum size - level: number = 1; + level = 1; // City that this Warehouse is in loc: string; @@ -41,19 +37,19 @@ export class Warehouse { size: number; // Amount of space currently used by warehouse - sizeUsed: number = 0; + sizeUsed = 0; // Whether Smart Supply is enabled for this Industry (the Industry that this Warehouse is for) - smartSupplyEnabled: boolean = false; + smartSupplyEnabled = false; // Flag that indicates whether Smart Supply accounts for imports when calculating // the amount fo purchase - smartSupplyConsiderExports: boolean = false; + smartSupplyConsiderExports = false; // Stores the amount of product to be produced. Used for Smart Supply unlock. // The production tracked by smart supply is always based on the previous cycle, // so it will always trail the "true" production by 1 cycle - smartSupplyStore: number = 0; + smartSupplyStore = 0; constructor(params: IConstructorParams = {}) { this.loc = params.loc ? params.loc : ""; @@ -70,7 +66,7 @@ export class Warehouse { Drugs: new Material({name: "Drugs"}), Robots: new Material({name: "Robots"}), AICores: new Material({name: "AI Cores"}), - RealEstate: new Material({name: "Real Estate"}) + RealEstate: new Material({name: "Real Estate"}), } if (params.corp && params.industry) { @@ -79,11 +75,11 @@ export class Warehouse { } // Re-calculate how much space is being used by this Warehouse - updateMaterialSizeUsed() { + updateMaterialSizeUsed(): void { this.sizeUsed = 0; this.breakdown = ""; for (const matName in this.materials) { - var mat = this.materials[matName]; + const mat = this.materials[matName]; if (MaterialSizes.hasOwnProperty(matName)) { this.sizeUsed += (mat.qty * MaterialSizes[matName]); if (mat.qty > 0) { @@ -96,7 +92,7 @@ export class Warehouse { } } - updateSize(corporation: IParent, industry: IParent) { + updateSize(corporation: IParent, industry: IParent): void { try { this.size = (this.level * 100) * corporation.getStorageMultiplier() @@ -110,6 +106,12 @@ export class Warehouse { toJSON(): any { return Generic_toJSON("Warehouse", this); } + + // Initiatizes a Warehouse object from a JSON save state. + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types + static fromJSON(value: any): Warehouse { + return Generic_fromJSON(Warehouse, value.data); + } } Reviver.constructors.Warehouse = Warehouse; diff --git a/src/Corporation/data/ResearchMetadata.ts b/src/Corporation/data/ResearchMetadata.ts index e19d730b2..921989bb8 100644 --- a/src/Corporation/data/ResearchMetadata.ts +++ b/src/Corporation/data/ResearchMetadata.ts @@ -82,7 +82,7 @@ export const researchMetadata: IConstructorParams[] = [ cost: 15e3, desc: "Use automated software to handle the hiring of employees. With this " + "research, each office will automatically hire one employee per " + - "market cycle if there is available space." + "market cycle if there is available space.", }, { @@ -90,7 +90,7 @@ export const researchMetadata: IConstructorParams[] = [ cost: 20e3, desc: "Use automated software to handle the training of employees. With this " + "research, each employee hired with HRBuddy-Recruitment will automatically " + - "be assigned to 'Training', rather than being unassigned." + "be assigned to 'Training', rather than being unassigned.", }, { name: "JoyWire", diff --git a/src/Corporation/ui/BaseReactComponent.js b/src/Corporation/ui/BaseReactComponent.js index a6b5d2f9d..b3da9a6fc 100644 --- a/src/Corporation/ui/BaseReactComponent.js +++ b/src/Corporation/ui/BaseReactComponent.js @@ -17,6 +17,4 @@ export class BaseReactComponent extends Component { routing() { return this.props.routing; } - - render() {} } diff --git a/src/Corporation/ui/CorporationUIEventHandler.js b/src/Corporation/ui/CorporationUIEventHandler.js index 0d1eaa336..06ad8af6c 100644 --- a/src/Corporation/ui/CorporationUIEventHandler.js +++ b/src/Corporation/ui/CorporationUIEventHandler.js @@ -16,7 +16,7 @@ import { Corporation, import { Industries, IndustryStartingCosts, IndustryDescriptions, - IndustryResearchTrees } from "../IndustryData"; +} from "../IndustryData"; import { MaterialSizes } from "../MaterialSizes"; @@ -61,13 +61,13 @@ export class CorporationEventHandler { createBribeFactionsPopup() { const popupId = "cmpy-mgmt-bribe-factions-popup"; const txt = createElement("p", { - innerText:"You can use Corporation funds or stock shares to bribe Faction Leaders in exchange for faction reputation" + innerText:"You can use Corporation funds or stock shares to bribe Faction Leaders in exchange for faction reputation", }); const factionSelector = createElement("select", { margin:"3px" }); for (let i = 0; i < Player.factions.length; ++i) { const facName = Player.factions[i]; factionSelector.add(createElement("option", { - text: facName, value: facName + text: facName, value: facName, })); } var repGainText = createElement("p"); @@ -93,7 +93,7 @@ export class CorporationEventHandler { factionSelector.options[factionSelector.selectedIndex].value + " with this bribe"; } - } + }, }); stockSharesInput = createElement("input", { type:"number", placeholder:"Stock Shares", margin: "5px", @@ -115,7 +115,7 @@ export class CorporationEventHandler { factionSelector.options[factionSelector.selectedIndex].value + " with this bribe"; } - } + }, }); var confirmButton = createElement("button", { class:"a-link-button", innerText:"Bribe", display:"inline-block", @@ -145,7 +145,7 @@ export class CorporationEventHandler { removeElementById(popupId); return false; } - } + }, }); const cancelButton = createPopupCloseButton(popupId, { class: "std-button", @@ -187,7 +187,7 @@ export class CorporationEventHandler { costIndicator.innerText = "Purchase " + numShares + " shares for a total of " + numeralWrapper.format(numShares * buybackPrice, '$0.000a'); } - } + }, }); var confirmBtn = createElement("button", { class:"a-link-button", innerText:"Buy shares", display:"inline-block", @@ -221,7 +221,7 @@ export class CorporationEventHandler { } return false; - } + }, }); var cancelBtn = createPopupCloseButton(popupId, { class: "std-button", @@ -249,7 +249,7 @@ export class CorporationEventHandler { removeElementById(popupId); this.rerender(); return false; - } + }, }); const cancelBtn = createPopupCloseButton(popupId, { innerText: "Cancel" }); @@ -264,7 +264,7 @@ export class CorporationEventHandler { const exportTxt = createElement("p", { innerText:"Select the industry and city to export this material to, as well as " + "how much of this material to export per second. You can set the export " + - "amount to 'MAX' to export all of the materials in this warehouse." + "amount to 'MAX' to export all of the materials in this warehouse.", }); //Select industry and city to export to @@ -286,7 +286,7 @@ export class CorporationEventHandler { return; } } - } + }, }); for (let i = 0; i < corp.divisions.length; ++i) { @@ -299,7 +299,7 @@ export class CorporationEventHandler { //Select amount to export const exportAmount = createElement("input", { class: "text-input", - placeholder:"Export amount / s" + placeholder:"Export amount / s", }); const exportBtn = createElement("button", { @@ -328,14 +328,14 @@ export class CorporationEventHandler { mat.exp.push(exportObj); removeElementById(popupId); return false; - } + }, }); const cancelBtn = createPopupCloseButton(popupId, { innerText: "Cancel" }); const currExportsText = createElement("p", { innerText:"Below is a list of all current exports of this material from this warehouse. " + - "Clicking on one of the exports below will REMOVE that export." + "Clicking on one of the exports below will REMOVE that export.", }); const currExports = []; for (var i = 0; i < mat.exp.length; ++i) { @@ -349,7 +349,7 @@ export class CorporationEventHandler { mat.exp.splice(i, 1); //Remove export object removeElementById(popupId); createExportMaterialPopup(mat); - } + }, })); })(i, mat, currExports); } @@ -385,7 +385,7 @@ export class CorporationEventHandler { onkeyup: (e) => { e.preventDefault(); if (e.keyCode === KEY.ENTER) {allocateBtn.click();} - } + }, }); allocateBtn = createElement("button", { @@ -404,7 +404,7 @@ export class CorporationEventHandler { this.rerender(); return false; - } + }, }); const cancelBtn = createPopupCloseButton(popupId, { @@ -478,7 +478,7 @@ export class CorporationEventHandler { } else { updateDynamicText(this.corp); } - } + }, }); issueBtn = createElement("button", { @@ -523,7 +523,7 @@ export class CorporationEventHandler { this.rerender(); return false; - } + }, }); const cancelBtn = createPopupCloseButton(popupId, { @@ -541,7 +541,7 @@ export class CorporationEventHandler { const popupId = "cmpy-mgmt-limit-product-production-popup"; const txt = createElement("p", { innerText:"Enter a limit to the amount of this product you would " + - "like to product per second. Leave the box empty to set no limit." + "like to product per second. Leave the box empty to set no limit.", }); let confirmBtn; const input = createElement("input", { @@ -551,7 +551,7 @@ export class CorporationEventHandler { onkeyup: (e) => { e.preventDefault(); if (e.keyCode === KEY.ENTER) { confirmBtn.click(); } - } + }, }); confirmBtn = createElement("button", { class: "std-button", @@ -578,7 +578,7 @@ export class CorporationEventHandler { removeElementById(popupId); this.rerender(); return false; - } + }, }); const cancelBtn = createPopupCloseButton(popupId, { innerText: "Cancel" }); cancelBtn.style.margin = "6px"; @@ -600,7 +600,7 @@ export class CorporationEventHandler { if (division.offices[cityName] instanceof OfficeSpace) { designCity.add(createElement("option", { value: cityName, - text: cityName + text: cityName, })); } } @@ -630,7 +630,7 @@ export class CorporationEventHandler { onkeyup: (e) => { e.preventDefault(); if (e.keyCode === KEY.ENTER) { confirmBtn.click(); } - } + }, }); confirmBtn = createElement("button", { class: "std-button", @@ -665,7 +665,7 @@ export class CorporationEventHandler { } this.rerender(); return false; - } + }, }) const cancelBtn = createPopupCloseButton(popupId, { class: "std-button", @@ -679,8 +679,6 @@ export class CorporationEventHandler { // Create a popup that lets the player use the Market TA research for Materials createMaterialMarketTaPopup(mat, industry) { - const corp = this.corp; - const popupId = "cmpy-mgmt-marketta-popup"; const markupLimit = mat.getMarkupLimit(); const ta1 = createElement("p", { @@ -699,7 +697,7 @@ export class CorporationEventHandler { for: useTa1AutoSaleId, innerText: "Use Market-TA.I for Auto-Sale Price", tooltip: "If this is enabled, then this Material will automatically " + - "be sold at the price identified by Market-TA.I (i.e. the price shown above)" + "be sold at the price identified by Market-TA.I (i.e. the price shown above)", }) const useTa1AutoSaleCheckbox = createElement("input", { checked: mat.marketTa1, @@ -708,7 +706,7 @@ export class CorporationEventHandler { type: "checkbox", changeListener: (e) => { mat.marketTa1 = e.target.checked; - } + }, }); useTa1AutoSaleDiv.appendChild(useTa1AutoSaleLabel); useTa1AutoSaleDiv.appendChild(useTa1AutoSaleCheckbox); @@ -766,7 +764,7 @@ export class CorporationEventHandler { tooltip: "If this is enabled, then this Material will automatically " + "be sold at the optimal price such that the amount sold matches the " + "amount produced. (i.e. the highest possible price, while still ensuring " + - " that all produced materials will be sold)" + " that all produced materials will be sold)", }) const useTa2AutoSaleCheckbox = createElement("input", { checked: mat.marketTa2, @@ -775,14 +773,14 @@ export class CorporationEventHandler { type: "checkbox", changeListener: (e) => { mat.marketTa2 = e.target.checked; - } + }, }); useTa2AutoSaleDiv.appendChild(useTa2AutoSaleLabel); useTa2AutoSaleDiv.appendChild(useTa2AutoSaleCheckbox); const ta2OverridesTa1 = createElement("p", { innerText: "Note that Market-TA.II overrides Market-TA.I. This means that if " + - "both are enabled, then Market-TA.II will take effect, not Market-TA.I" + "both are enabled, then Market-TA.II will take effect, not Market-TA.I", }); createPopup(popupId, [ta1, useTa1AutoSaleDiv, ta2Text, ta2Input, useTa2AutoSaleDiv, ta2OverridesTa1, closeBtn]); @@ -805,7 +803,7 @@ export class CorporationEventHandler { if (!(division.offices[cityName] instanceof OfficeSpace)) { citySelector.add(createElement("option", { text: cityName, - value: cityName + value: cityName, })); } } @@ -832,7 +830,7 @@ export class CorporationEventHandler { removeElementById(popupId); this.rerender(); return false; - } + }, }); const cancelBtn = createPopupCloseButton(popupId, { class: "std-button", @@ -852,7 +850,7 @@ export class CorporationEventHandler { innerHTML: "Create a new division to expand into a new industry:", }); var selector = createElement("select", { - class:"dropdown" + class:"dropdown", }); var industryDescription = createElement("p", {}); var yesBtn; @@ -866,11 +864,11 @@ export class CorporationEventHandler { onkeyup:(e)=>{ e.preventDefault(); if (e.keyCode === KEY.ENTER) {yesBtn.click();} - } + }, }); var nameLabel = createElement("label", { for:"cmpy-mgmt-expand-industry-name-input", - innerText:"Division name: " + innerText:"Division name: ", }); yesBtn = createElement("span", { class:"popup-box-button", @@ -905,7 +903,7 @@ export class CorporationEventHandler { this.rerender(); } return false; - } + }, }); const noBtn = createPopupCloseButton(popupId, { @@ -923,7 +921,7 @@ export class CorporationEventHandler { // Have Agriculture be first as recommended option if (!ownedIndustries["Agriculture"]) { selector.add(createElement("option", { - text:Industries["Agriculture"], value:"Agriculture" + text:Industries["Agriculture"], value:"Agriculture", })); } @@ -964,8 +962,6 @@ export class CorporationEventHandler { // Create a popup that lets the player use the Market TA research for Products createProductMarketTaPopup(product, industry) { - const corp = this.corp; - const popupId = "cmpy-mgmt-marketta-popup"; const markupLimit = product.rat / product.mku; const ta1 = createElement("p", { @@ -984,7 +980,7 @@ export class CorporationEventHandler { for: useTa1AutoSaleId, innerText: "Use Market-TA.I for Auto-Sale Price", tooltip: "If this is enabled, then this Product will automatically " + - "be sold at the price identified by Market-TA.I (i.e. the price shown above)" + "be sold at the price identified by Market-TA.I (i.e. the price shown above)", }) const useTa1AutoSaleCheckbox = createElement("input", { checked: product.marketTa1, @@ -993,7 +989,7 @@ export class CorporationEventHandler { type: "checkbox", changeListener: (e) => { product.marketTa1 = e.target.checked; - } + }, }); useTa1AutoSaleDiv.appendChild(useTa1AutoSaleLabel); useTa1AutoSaleDiv.appendChild(useTa1AutoSaleCheckbox); @@ -1043,7 +1039,7 @@ export class CorporationEventHandler { tooltip: "If this is enabled, then this Product will automatically " + "be sold at the optimal price such that the amount sold matches the " + "amount produced. (i.e. the highest possible price, while still ensuring " + - " that all produced materials will be sold)" + " that all produced materials will be sold)", }) const useTa2AutoSaleCheckbox = createElement("input", { checked: product.marketTa2, @@ -1052,14 +1048,14 @@ export class CorporationEventHandler { type: "checkbox", changeListener: (e) => { product.marketTa2 = e.target.checked; - } + }, }); useTa2AutoSaleDiv.appendChild(useTa2AutoSaleLabel); useTa2AutoSaleDiv.appendChild(useTa2AutoSaleCheckbox); const ta2OverridesTa1 = createElement("p", { innerText: "Note that Market-TA.II overrides Market-TA.I. This means that if " + - "both are enabled, then Market-TA.II will take effect, not Market-TA.I" + "both are enabled, then Market-TA.II will take effect, not Market-TA.I", }); createPopup(popupId, [ta1, useTa1AutoSaleDiv, ta2Text, ta2Input, useTa2AutoSaleDiv, ta2OverridesTa1, closeBtn]); @@ -1076,7 +1072,7 @@ export class CorporationEventHandler { const purchasePopupId = "cmpy-mgmt-material-purchase-popup"; const txt = createElement("p", { innerHTML: "Enter the amount of " + mat.name + " you would like " + - "to purchase per second. This material's cost changes constantly" + "to purchase per second. This material's cost changes constantly", }); let confirmBtn; let input = createElement("input", { @@ -1087,7 +1083,7 @@ export class CorporationEventHandler { onkeyup: (e) => { e.preventDefault(); if (e.keyCode === KEY.ENTER) {confirmBtn.click();} - } + }, }); confirmBtn = createElement("button", { innerText: "Confirm", class: "std-button", @@ -1101,7 +1097,7 @@ export class CorporationEventHandler { this.rerender(); return false; } - } + }, }); const clearButton = createElement("button", { innerText: "Clear Purchase", class: "std-button", @@ -1110,7 +1106,7 @@ export class CorporationEventHandler { removeElementById(purchasePopupId); this.rerender(); return false; - } + }, }); const cancelBtn = createPopupCloseButton(purchasePopupId, { class: "std-button", @@ -1153,7 +1149,7 @@ export class CorporationEventHandler { e.preventDefault(); updateBulkPurchaseText(e.target.value); if (e.keyCode === KEY.ENTER) {bulkPurchaseConfirmBtn.click();} - } + }, }); bulkPurchaseConfirmBtn = createElement("button", { @@ -1184,7 +1180,7 @@ export class CorporationEventHandler { removeElementById(purchasePopupId); return false; } - } + }, }) elems.push(bulkPurchaseInfo); @@ -1224,7 +1220,7 @@ export class CorporationEventHandler { onkeyup: (e) => { e.preventDefault(); if (e.keyCode === KEY.ENTER) {confirmBtn.click();} - } + }, }); let inputButtonInitValue = mat.sCost ? mat.sCost : null; @@ -1241,7 +1237,7 @@ export class CorporationEventHandler { onkeyup: (e) => { e.preventDefault(); if (e.keyCode === KEY.ENTER) {confirmBtn.click();} - } + }, }); confirmBtn = createElement("button", { class: "std-button", @@ -1307,7 +1303,7 @@ export class CorporationEventHandler { removeElementById(sellPopupId); this.rerender(); return false; - } + }, }); const cancelBtn = createPopupCloseButton(sellPopupId, { class: "std-button", @@ -1347,7 +1343,7 @@ export class CorporationEventHandler { onkeyup: (e) => { e.preventDefault(); if (e.keyCode === KEY.ENTER) {confirmBtn.click();} - } + }, }); let inputButtonInitValue = product.sCost ? product.sCost : null; @@ -1365,7 +1361,7 @@ export class CorporationEventHandler { onkeyup: (e) => { e.preventDefault(); if (e.keyCode === KEY.ENTER) {confirmBtn.click();} - } + }, }); const checkboxDiv = createElement("div", { border: "1px solid white", @@ -1478,7 +1474,7 @@ export class CorporationEventHandler { removeElementById(popupId); this.rerender(); return false; - } + }, }); const cancelBtn = createPopupCloseButton(popupId, { class: "std-button" }); @@ -1515,12 +1511,10 @@ export class CorporationEventHandler { } else { const stockSaleResults = this.corp.calculateShareSale(numShares); const profit = stockSaleResults[0]; - const newSharePrice = stockSaleResults[1]; - const newSharesUntilUpdate = stockSaleResults[2]; profitIndicator.innerText = "Sell " + numShares + " shares for a total of " + numeralWrapper.format(profit, '$0.000a'); } - } + }, }); const confirmBtn = createElement("button", { class:"a-link-button", innerText:"Sell shares", display:"inline-block", @@ -1562,7 +1556,7 @@ export class CorporationEventHandler { return false; } - } + }, }); const cancelBtn = createPopupCloseButton(popupId, { class: "std-button", @@ -1579,10 +1573,10 @@ export class CorporationEventHandler { const popupId = "cmpy-mgmt-throw-office-party-popup"; const txt = createElement("p", { innerText:"Enter the amount of money you would like to spend PER EMPLOYEE " + - "on this office party" + "on this office party", }); const totalCostTxt = createElement("p", { - innerText:"Throwing this party will cost a total of $0" + innerText:"Throwing this party will cost a total of $0", }); let confirmBtn; const input = createElement("input", { @@ -1598,7 +1592,7 @@ export class CorporationEventHandler { onkeyup:(e)=>{ e.preventDefault(); if (e.keyCode === KEY.ENTER) {confirmBtn.click();} - } + }, }); confirmBtn = createElement("button", { class: "std-button", @@ -1622,7 +1616,7 @@ export class CorporationEventHandler { } } return false; - } + }, }); const cancelBtn = createPopupCloseButton(popupId, { class: "std-button", innerText: "Cancel" }); @@ -1661,7 +1655,7 @@ export class CorporationEventHandler { const upgradeCostMax = OfficeInitialCost * mult; const text = createElement("p", { - innerText:"Increase the size of your office space to fit additional employees!" + innerText:"Increase the size of your office space to fit additional employees!", }); const text2 = createElement("p", { innerText: "Upgrade size: " }); @@ -1680,7 +1674,7 @@ export class CorporationEventHandler { } removeElementById(popupId); return false; - } + }, }); const confirmBtn15 = createElement("button", { class: this.corp.funds.lt(upgradeCost15) ? "a-link-button-inactive" : "a-link-button", @@ -1697,7 +1691,7 @@ export class CorporationEventHandler { } removeElementById(popupId); return false; - } + }, }); const confirmBtnMax = createElement("button", { class:this.corp.funds.lt(upgradeCostMax) ? "a-link-button-inactive" : "a-link-button", @@ -1714,7 +1708,7 @@ export class CorporationEventHandler { } removeElementById(popupId); return false; - } + }, }); const cancelBtn = createPopupCloseButton(popupId, { innerText: "Cancel" }); cancelBtn.style.margin = "4px"; diff --git a/src/Corporation/ui/HeaderTabs.jsx b/src/Corporation/ui/HeaderTabs.jsx index a0e6fd1da..c2d895d7d 100644 --- a/src/Corporation/ui/HeaderTabs.jsx +++ b/src/Corporation/ui/HeaderTabs.jsx @@ -4,8 +4,6 @@ import React from "react"; import { BaseReactComponent } from "./BaseReactComponent"; -import { overviewPage } from "./Routing"; - function HeaderTab(props) { let className = "cmpy-mgmt-header-tab"; if (props.current) { @@ -71,7 +69,7 @@ export class HeaderTabs extends BaseReactComponent { { this.renderTab({ onClick: this.eventHandler().createNewIndustryPopup.bind(this.eventHandler()), - text: "Expand into new Industry" + text: "Expand into new Industry", }) } diff --git a/src/Corporation/ui/IndustryOffice.jsx b/src/Corporation/ui/IndustryOffice.jsx index 324148733..d43cadf22 100644 --- a/src/Corporation/ui/IndustryOffice.jsx +++ b/src/Corporation/ui/IndustryOffice.jsx @@ -62,7 +62,6 @@ export class IndustryOffice extends BaseReactComponent { // Calculate how many NEW emplyoees we need to account for const currentNumEmployees = office.employees.length; - const newEmployees = currentNumEmployees - this.state.numEmployees; // Record the number of employees in each position, for NEW employees only for (let i = this.state.numEmployees; i < office.employees.length; ++i) { diff --git a/src/Corporation/ui/IndustryOverview.jsx b/src/Corporation/ui/IndustryOverview.jsx index a108fba6d..09cdc6a0a 100644 --- a/src/Corporation/ui/IndustryOverview.jsx +++ b/src/Corporation/ui/IndustryOverview.jsx @@ -12,7 +12,6 @@ import { createProgressBarText } from "../../../utils/helpers/createProgressB export class IndustryOverview extends BaseReactComponent { renderMakeProductButton() { - const corp = this.corp(); const division = this.routing().currentDivision; // Validated inside render() var createProductButtonText, createProductPopupText; @@ -97,7 +96,6 @@ export class IndustryOverview extends BaseReactComponent { const popularity = `Popularity: ${numeralWrapper.format(division.popularity, "0.000")}`; let advertisingInfo = false; - let advertisingTooltip; const advertisingFactors = division.getAdvertisingFactors(); const awarenessFac = advertisingFactors[1]; const popularityFac = advertisingFactors[2]; diff --git a/src/Corporation/ui/IndustryWarehouse.jsx b/src/Corporation/ui/IndustryWarehouse.jsx index f36f451e4..d0f220a56 100644 --- a/src/Corporation/ui/IndustryWarehouse.jsx +++ b/src/Corporation/ui/IndustryWarehouse.jsx @@ -19,7 +19,6 @@ import { isString } from "../../../utils/helpers/isString"; function ProductComponent(props) { const corp = props.corp; const division = props.division; - const warehouse = props.warehouse; const city = props.city; const product = props.product; const eventHandler = props.eventHandler; @@ -203,15 +202,6 @@ function MaterialComponent(props) { // Total gain or loss of this material (per second) const totalGain = mat.buy + mat.prd + mat.imp - mat.sll - mat.totalExp; - // Competition and demand info, if they're unlocked - let cmpAndDmdText = ""; - if (corp.unlockUpgrades[2] === 1) { - cmpAndDmdText += "
    Demand: " + numeralWrapper.format(mat.dmd, nf); - } - if (corp.unlockUpgrades[3] === 1) { - cmpAndDmdText += "
    Competition: " + numeralWrapper.format(mat.cmp, nf); - } - // Flag that determines whether this industry is "new" and the current material should be // marked with flashing-red lights const tutorial = division.newInd && Object.keys(division.reqMats).includes(mat.name) && @@ -511,7 +501,6 @@ export class IndustryWarehouse extends BaseReactComponent { } render() { - const corp = this.corp(); const division = this.routing().currentDivision; if (division == null) { throw new Error(`Routing does not hold reference to the current Industry`); diff --git a/src/Corporation/ui/MainPanel.jsx b/src/Corporation/ui/MainPanel.jsx index 00d48bf33..3a632639c 100644 --- a/src/Corporation/ui/MainPanel.jsx +++ b/src/Corporation/ui/MainPanel.jsx @@ -7,7 +7,6 @@ import { BaseReactComponent } from "./BaseReactComponent"; import { CityTabs } from "./CityTabs"; import { Industry } from "./Industry"; import { Overview } from "./Overview"; -import { overviewPage } from "./Routing"; import { OfficeSpace } from "../Corporation"; diff --git a/src/Corporation/ui/Overview.jsx b/src/Corporation/ui/Overview.jsx index 0c7c26d33..c33297e3c 100644 --- a/src/Corporation/ui/Overview.jsx +++ b/src/Corporation/ui/Overview.jsx @@ -158,7 +158,7 @@ export class Overview extends BaseReactComponent { onClick: findInvestorsOnClick, style: "inline-block", text: "Find Investors", - tooltip: findInvestorsTooltip + tooltip: findInvestorsTooltip, }); const goPublicBtn = this.createButton({ class: "std-button", @@ -167,7 +167,7 @@ export class Overview extends BaseReactComponent { text: "Go Public", tooltip: "Become a publicly traded and owned entity. Going public " + "involves issuing shares for an IPO. Once you are a public " + - "company, your shares will be traded on the stock market." + "company, your shares will be traded on the stock market.", }); return ( diff --git a/src/Corporation/ui/Routing.ts b/src/Corporation/ui/Routing.ts index 5e2c023fb..307f64f16 100644 --- a/src/Corporation/ui/Routing.ts +++ b/src/Corporation/ui/Routing.ts @@ -1,15 +1,27 @@ import { IMap } from "../../types"; -export const overviewPage: string = "Overview"; +export const overviewPage = "Overview"; // Interfaces for whatever's required to sanitize routing with Corporation Data interface IOfficeSpace { - + loc: string; + cost: number; + size: number; + comf: number; + beau: number; + tier: any; + minEne: number; + maxEne: number; + minHap: number; + maxHap: number; + maxMor: number; + employees: any; + employeeProd: any; } interface IDivision { name: string; - offices: IMap + offices: IMap; } interface ICorporation { @@ -76,7 +88,7 @@ export class CorporationRouting { for (let i = 0; i < this.corp.divisions.length; ++i) { if (this.corp.divisions[i].name === page) { this.currentDivision = this.corp.divisions[i]; - }; + } } // 'currentDivision' should not be null, since the routing is either on diff --git a/src/Crime/Crime.ts b/src/Crime/Crime.ts index 176069cf7..bbff32d4b 100644 --- a/src/Crime/Crime.ts +++ b/src/Crime/Crime.ts @@ -22,49 +22,49 @@ export interface IConstructorParams { export class Crime { // Number representing the difficulty of the crime. Used for success chance calculations - difficulty: number = 0; + difficulty = 0; // Amount of karma lost for SUCCESSFULLY committing this crime - karma: number = 0; + karma = 0; // How many people die as a result of this crime - kills: number = 0; + kills = 0; // How much money is given by the - money: number = 0; + money = 0; // Name of crime - name: string = ""; + name = ""; // Milliseconds it takes to attempt the crime - time: number = 0; + time = 0; // Corresponding type in CONSTANTS. Contains a description for the crime activity - type: string = ""; + type = ""; // Weighting factors that determine how stats affect the success rate of this crime - hacking_success_weight: number = 0; - strength_success_weight: number = 0; - defense_success_weight: number = 0; - dexterity_success_weight: number = 0; - agility_success_weight: number = 0; - charisma_success_weight: number = 0; + hacking_success_weight = 0; + strength_success_weight = 0; + defense_success_weight = 0; + dexterity_success_weight = 0; + agility_success_weight = 0; + charisma_success_weight = 0; // How much stat experience is granted by this crime - hacking_exp: number = 0; - strength_exp: number = 0; - defense_exp: number = 0; - dexterity_exp: number = 0; - agility_exp: number = 0; - charisma_exp: number = 0; - intelligence_exp: number = 0; + hacking_exp = 0; + strength_exp = 0; + defense_exp = 0; + dexterity_exp = 0; + agility_exp = 0; + charisma_exp = 0; + intelligence_exp = 0; - constructor(name: string = "", - type: string = "", - time: number = 0, - money: number = 0, - difficulty: number = 0, - karma: number = 0, + constructor(name = "", + type = "", + time = 0, + money = 0, + difficulty = 0, + karma = 0, params: IConstructorParams={}) { this.name = name; this.type = type; @@ -91,7 +91,7 @@ export class Crime { this.kills = params.kills ? params.kills : 0; } - commit(p: IPlayer, div: number=1, singParams: any=null): number { + commit(p: IPlayer, div=1, singParams: any=null): number { if (div <= 0) { div = 1; } p.startCrime( this.type, @@ -103,7 +103,7 @@ export class Crime { this.charisma_exp/div, this.money/div, this.time, - singParams + singParams, ); return this.time; diff --git a/src/Crime/CrimeHelpers.ts b/src/Crime/CrimeHelpers.ts index 27b2fd233..f617bb488 100644 --- a/src/Crime/CrimeHelpers.ts +++ b/src/Crime/CrimeHelpers.ts @@ -1,13 +1,14 @@ import { Crimes } from "./Crimes"; +import { Crime } from "./Crime"; import { IPlayer } from "../PersonObjects/IPlayer"; import { dialogBoxCreate } from "../../utils/DialogBox"; -export function determineCrimeSuccess(p: IPlayer, type: string) { - let chance: number = 0; - let found: boolean = false; +export function determineCrimeSuccess(p: IPlayer, type: string): boolean { + let chance = 0; + let found = false; for (const i in Crimes) { - let crime = Crimes[i]; + const crime = Crimes[i]; if (crime.type == type) { chance = crime.successRate(p); found = true; @@ -17,7 +18,7 @@ export function determineCrimeSuccess(p: IPlayer, type: string) { if (!found) { dialogBoxCreate(`ERR: Unrecognized crime type: ${type} This is probably a bug please contact the developer`, false); - return; + return false; } if (Math.random() <= chance) { @@ -29,7 +30,7 @@ export function determineCrimeSuccess(p: IPlayer, type: string) { } } -export function findCrime(roughName: string) { +export function findCrime(roughName: string): Crime | null { if (roughName.includes("shoplift")) { return Crimes.Shoplift; } else if (roughName.includes("rob") && roughName.includes("store")) { diff --git a/src/Crime/formulas/crime.ts b/src/Crime/formulas/crime.ts index 23748cfeb..c6cecb8a0 100644 --- a/src/Crime/formulas/crime.ts +++ b/src/Crime/formulas/crime.ts @@ -22,7 +22,7 @@ export interface IPerson { crime_success_mult: number; } -export function calculateCrimeSuccessChance(crime: ICrime, person: IPerson) { +export function calculateCrimeSuccessChance(crime: ICrime, person: IPerson): number { let chance: number = (crime.hacking_success_weight * person.hacking_skill + crime.strength_success_weight * person.strength + crime.defense_success_weight * person.defense + diff --git a/src/DarkWeb/DarkWeb.tsx b/src/DarkWeb/DarkWeb.tsx index b0cc18d98..380b91b83 100644 --- a/src/DarkWeb/DarkWeb.tsx +++ b/src/DarkWeb/DarkWeb.tsx @@ -7,8 +7,6 @@ import { post, postElement } from "../ui/postToTerminal"; import { Money } from "../ui/React/Money"; import { isValidIPAddress } from "../../utils/helpers/isValidIPAddress"; -import { formatNumber } from "../../utils/StringHelperFunctions"; -import { numeralWrapper } from "../ui/numeralFormat"; //Posts a "help" message if connected to DarkWeb export function checkIfConnectedToDarkweb(): void { @@ -29,27 +27,28 @@ export function checkIfConnectedToDarkweb(): void { export function executeDarkwebTerminalCommand(commandArray: string[]): void { if (commandArray.length == 0) {return;} switch (commandArray[0]) { - case "buy": + case "buy": { if (commandArray.length != 2) { post("Incorrect number of arguments. Usage: "); post("buy -l"); post("buy [item name]"); return; } - var arg = commandArray[1]; + const arg = commandArray[1]; if (arg == "-l") { listAllDarkwebItems(); } else { buyDarkwebItem(arg); } break; + } default: post("Command not found"); break; } } -function listAllDarkwebItems() { +function listAllDarkwebItems(): void { for(const key in DarkWebItems) { const item = DarkWebItems[key]; postElement(<>{item.program} - {Money(item.price)} - {item.description}); diff --git a/src/DarkWeb/DarkWebItem.ts b/src/DarkWeb/DarkWebItem.ts index 5045ee135..ce506a0eb 100644 --- a/src/DarkWeb/DarkWebItem.ts +++ b/src/DarkWeb/DarkWebItem.ts @@ -1,5 +1,3 @@ -import { numeralWrapper } from "../ui/numeralFormat"; - export class DarkWebItem { program: string; price: number; diff --git a/src/DevMenu.jsx b/src/DevMenu.jsx index b1c9167e7..98b53fcd1 100644 --- a/src/DevMenu.jsx +++ b/src/DevMenu.jsx @@ -3,10 +3,9 @@ import { CodingContractTypes } from "./CodingContracts"; import { generateContract, generateRandomContract, - generateRandomContractOnHome + generateRandomContractOnHome, } from "./CodingContractGenerator"; import { Companies } from "./Company/Companies"; -import { Company } from "./Company/Company"; import { Programs } from "./Programs/Programs"; import { Factions } from "./Faction/Factions"; import { Player } from "./Player"; @@ -14,17 +13,11 @@ import { PlayerOwnedSourceFile } from "./SourceFile/PlayerOwnedSourceFile"; import { AllServers } from "./Server/AllServers"; import { GetServerByHostname } from "./Server/ServerHelpers"; import { hackWorldDaemon } from "./RedPill"; -import { StockMarket, SymbolToStockMap } from "./StockMarket/StockMarket"; +import { StockMarket } from "./StockMarket/StockMarket"; import { Stock } from "./StockMarket/Stock"; -import { Terminal } from "./Terminal"; - -import { numeralWrapper } from "./ui/numeralFormat"; import { dialogBoxCreate } from "../utils/DialogBox"; -import { exceptionAlert } from "../utils/helpers/exceptionAlert"; import { createElement } from "../utils/uiHelpers/createElement"; -import { createOptionElement } from "../utils/uiHelpers/createOptionElement"; -import { getSelectText } from "../utils/uiHelpers/getSelectData"; import { removeElementById } from "../utils/uiHelpers/removeElementById"; import { Money } from "./ui/React/Money"; @@ -47,12 +40,13 @@ class ValueAdjusterComponent extends Component { this.state = { value: '' }; this.setValue = this.setValue.bind(this); } + setValue(event) { this.setState({ value: parseFloat(event.target.value) }); } + render() { const { title, add, subtract, reset } = this.props; - const { value } = this.state; return ( <> @@ -279,9 +273,8 @@ class DevMenuComponent extends Component { } modifyFactionRep(modifier) { - const component = this; - return function(reputation) { - const fac = Factions[component.state.faction]; + return (reputation) => { + const fac = Factions[this.state.faction]; if (fac != null && !isNaN(reputation)) { fac.playerReputation += reputation*modifier; } @@ -296,9 +289,8 @@ class DevMenuComponent extends Component { } modifyFactionFavor(modifier) { - const component = this; - return function(favor) { - const fac = Factions[component.state.faction]; + return (favor) => { + const fac = Factions[this.state.faction]; if (fac != null && !isNaN(favor)) { fac.favor += favor*modifier; } @@ -368,10 +360,9 @@ class DevMenuComponent extends Component { } setAllSF(sfLvl) { - const component = this; - return function(){ + return () => { for (let i = 0; i < validSFN.length; i++) { - component.setSF(validSFN[i], sfLvl)(); + this.setSF(validSFN[i], sfLvl)(); } } } @@ -441,9 +432,8 @@ class DevMenuComponent extends Component { } modifyCompanyRep(modifier) { - const component = this; - return function(reputation) { - const company = Companies[component.state.company]; + return (reputation) => { + const company = Companies[this.state.company]; if (company != null && !isNaN(reputation)) { company.playerReputation += reputation*modifier; } @@ -456,9 +446,8 @@ class DevMenuComponent extends Component { } modifyCompanyFavor(modifier) { - const component = this; - return function(favor) { - const company = Companies[component.state.company]; + return (favor) => { + const company = Companies[this.state.company]; if (company != null && !isNaN(favor)) { company.favor += favor*modifier; } @@ -496,7 +485,7 @@ class DevMenuComponent extends Component { modifyBladeburnerRank(modify) { return function(rank) { - if (!!Player.bladeburner) { + if (Player.bladeburner) { Player.bladeburner.changeRank(rank*modify); } } @@ -508,67 +497,67 @@ class DevMenuComponent extends Component { } addTonsBladeburnerRank() { - if (!!Player.bladeburner) { + if (Player.bladeburner) { Player.bladeburner.changeRank(tonsP); } } modifyBladeburnerCycles(modify) { return function(cycles) { - if (!!Player.bladeburner) { + if (Player.bladeburner) { Player.bladeburner.storedCycles += cycles*modify; } } } resetBladeburnerCycles() { - if (!!Player.bladeburner) { + if (Player.bladeburner) { Player.bladeburner.storedCycles = 0; } } addTonsBladeburnerCycles() { - if (!!Player.bladeburner) { + if (Player.bladeburner) { Player.bladeburner.storedCycles += tonsP; } } addTonsGangCycles() { - if (!!Player.gang) { + if (Player.gang) { Player.gang.storedCycles = tonsP; } } modifyGangCycles(modify) { return function(cycles) { - if (!!Player.gang) { + if (Player.gang) { Player.gang.storedCycles += cycles*modify; } } } resetGangCycles() { - if (!!Player.gang) { + if (Player.gang) { Player.gang.storedCycles = 0; } } addTonsCorporationCycles() { - if (!!Player.corporation) { + if (Player.corporation) { Player.corporation.storedCycles = tonsP; } } modifyCorporationCycles(modify) { return function(cycles) { - if (!!Player.corporation) { + if (Player.corporation) { Player.corporation.storedCycles += cycles*modify; } } } resetCorporationCycles() { - if (!!Player.corporation) { + if (Player.corporation) { Player.corporation.storedCycles = 0; } } @@ -580,10 +569,10 @@ class DevMenuComponent extends Component { }); } - processStocks(cb) { + processStocks(sub) { const inputSymbols = document.getElementById('dev-stock-symbol').value.toString().replace(/\s/g, ''); - let match = function(symbol) { return true; } + let match = function() { return true; } if (inputSymbols !== '' && inputSymbols !== 'all') { match = function(symbol) { @@ -595,7 +584,7 @@ class DevMenuComponent extends Component { if (StockMarket.hasOwnProperty(name)) { const stock = StockMarket[name]; if (stock instanceof Stock && match(stock.symbol)) { - cb(stock); + sub(stock); } } } @@ -636,13 +625,13 @@ class DevMenuComponent extends Component { } } - sleeveMaxAllSync() { + sleeveSyncMaxAll() { for (let i = 0; i < Player.sleeves.length; ++i) { Player.sleeves[i].sync = 100; } } - sleeveClearAllSync() { + sleeveSyncClearAll() { for (let i = 0; i < Player.sleeves.length; ++i) { Player.sleeves[i].sync = 0; } @@ -674,7 +663,7 @@ class DevMenuComponent extends Component { - + , )); @@ -1210,8 +1199,8 @@ class DevMenuComponent extends Component {
    - - + +
    Sync:
    diff --git a/src/Exploits/applyExploits.ts b/src/Exploits/applyExploits.ts index c2671b025..f1cdfe32d 100644 --- a/src/Exploits/applyExploits.ts +++ b/src/Exploits/applyExploits.ts @@ -1,6 +1,6 @@ import { Player } from "../Player"; -export function applyExploit() { +export function applyExploit(): void { if (Player.exploits && Player.exploits.length === 0) { return; } diff --git a/src/Exploits/unclickable.ts b/src/Exploits/unclickable.ts index 0ee7cd696..97cdbc214 100644 --- a/src/Exploits/unclickable.ts +++ b/src/Exploits/unclickable.ts @@ -2,7 +2,7 @@ import { Player } from "../Player"; import { Exploit } from "./Exploit"; (function() { - function clickTheUnclickable(event: MouseEvent) { + function clickTheUnclickable(event: MouseEvent): void { if(!event.target || !(event.target instanceof Element)) return; const display = window.getComputedStyle(event.target as Element).display; if(display === 'none' && event.isTrusted) @@ -10,7 +10,7 @@ import { Exploit } from "./Exploit"; } - function targetElement() { + function targetElement(): void { const elem = document.getElementById('unclickable'); if(elem == null) { console.error('Could not find the unclickable elem for the related exploit.'); diff --git a/src/Faction/Faction.ts b/src/Faction/Faction.ts index 2bf4b372e..233ae0dcc 100644 --- a/src/Faction/Faction.ts +++ b/src/Faction/Faction.ts @@ -4,18 +4,12 @@ import { FactionInfo, import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver"; export class Faction { - /** - * Initiatizes a Faction object from a JSON save state. - */ - static fromJSON(value: any): Faction { - return Generic_fromJSON(Faction, value.data); - } /** * Flag signalling whether the player has already received an invitation * to this faction */ - alreadyInvited: boolean = false; + alreadyInvited = false; /** * Holds names of all augmentations that this Faction offers @@ -25,35 +19,35 @@ export class Faction { /** * Amount of favor the player has with this faction. */ - favor: number = 0; + favor = 0; /** * Flag signalling whether player has been banned from this faction */ - isBanned: boolean = false; + isBanned = false; /** * Flag signalling whether player is a member of this faction */ - isMember: boolean = false; + isMember = false; /** * Name of faction */ - name: string = ""; + name = ""; /** * Amount of reputation player has with this faction */ - playerReputation: number = 0; + playerReputation = 0; /** * Reputation from the last "prestige" that was not converted to favor. * This reputation rolls over and is used for the next favor calculation */ - rolloverRep: number = 0; + rolloverRep = 0; - constructor(name: string="") { + constructor(name="") { this.name = name; } @@ -82,7 +76,7 @@ export class Faction { getFavorGain(): number[] { if (this.favor == null) { this.favor = 0; } if (this.rolloverRep == null) { this.rolloverRep = 0; } - var favorGain = 0, rep = this.playerReputation + this.rolloverRep; + let favorGain = 0, rep = this.playerReputation + this.rolloverRep; let reqdRep = CONSTANTS.FactionReputationToFavorBase * Math.pow(CONSTANTS.FactionReputationToFavorMult, this.favor); while(rep > 0) { @@ -103,6 +97,14 @@ export class Faction { toJSON(): any { return Generic_toJSON("Faction", this); } + + /** + * Initiatizes a Faction object from a JSON save state. + */ + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types + static fromJSON(value: any): Faction { + return Generic_fromJSON(Faction, value.data); + } } Reviver.constructors.Faction = Faction; diff --git a/src/Faction/FactionHelpers.jsx b/src/Faction/FactionHelpers.jsx index 0926b2faf..b9fb9e8dc 100644 --- a/src/Faction/FactionHelpers.jsx +++ b/src/Faction/FactionHelpers.jsx @@ -24,19 +24,12 @@ import { import { Page, routing } from "../ui/navigationTracking"; import { dialogBoxCreate } from "../../utils/DialogBox"; import { factionInvitationBoxCreate } from "../../utils/FactionInvitationBox"; -import { - Reviver, - Generic_toJSON, - Generic_fromJSON -} from "../../utils/JSONReviver"; -import { formatNumber } from "../../utils/StringHelperFunctions"; -import { numeralWrapper } from "../ui/numeralFormat"; import { Money } from "../ui/React/Money"; import { yesNoBoxCreate, yesNoBoxGetYesButton, yesNoBoxGetNoButton, - yesNoBoxClose + yesNoBoxClose, } from "../../utils/YesNoBox"; export function inviteToFaction(faction) { @@ -90,7 +83,7 @@ export function displayFactionContent(factionName, initiallyOnAugmentationsPage= p={Player} startHackingMissionFn={startHackingMission} />, - Engine.Display.factionContent + Engine.Display.factionContent, ) } diff --git a/src/Faction/Factions.ts b/src/Faction/Factions.ts index a5c05e809..8616018f0 100644 --- a/src/Faction/Factions.ts +++ b/src/Faction/Factions.ts @@ -16,7 +16,7 @@ export function loadFactions(saveString: string): void { Factions = JSON.parse(saveString, Reviver); } -export function AddToFactions(faction: Faction) { +export function AddToFactions(faction: Faction): void { const name: string = faction.name; Factions[name] = faction; } @@ -25,7 +25,7 @@ export function factionExists(name: string): boolean { return Factions.hasOwnProperty(name); } -export function initFactions(bitNode: number=1) { +export function initFactions(): void { for (const name in FactionInfos) { resetFaction(new Faction(name)); } @@ -34,7 +34,7 @@ export function initFactions(bitNode: number=1) { //Resets a faction during (re-)initialization. Saves the favor in the new //Faction object and deletes the old Faction Object from "Factions". Then //reinserts the new Faction object -export function resetFaction(newFactionObject: Faction) { +export function resetFaction(newFactionObject: Faction): void { if (!(newFactionObject instanceof Faction)) { throw new Error("Invalid argument 'newFactionObject' passed into resetFaction()"); } diff --git a/src/Faction/ui/AugmentationsPage.tsx b/src/Faction/ui/AugmentationsPage.tsx index c950c8291..5ac4ee8b5 100644 --- a/src/Faction/ui/AugmentationsPage.tsx +++ b/src/Faction/ui/AugmentationsPage.tsx @@ -77,7 +77,7 @@ export class AugmentationsPage extends React.Component { getAugsSortedByCost(): string[] { const augs = this.getAugs(); augs.sort((augName1, augName2)=>{ - var aug1 = Augmentations[augName1], aug2 = Augmentations[augName2]; + const aug1 = Augmentations[augName1], aug2 = Augmentations[augName2]; if (aug1 == null || aug2 == null) { throw new Error("Invalid Augmentation Names"); } @@ -91,7 +91,7 @@ export class AugmentationsPage extends React.Component { getAugsSortedByReputation(): string[] { const augs = this.getAugs(); augs.sort((augName1, augName2)=>{ - var aug1 = Augmentations[augName1], aug2 = Augmentations[augName2]; + const aug1 = Augmentations[augName1], aug2 = Augmentations[augName2]; if (aug1 == null || aug2 == null) { throw new Error("Invalid Augmentation Names"); } @@ -118,23 +118,21 @@ export class AugmentationsPage extends React.Component { }); } - render() { + render(): React.ReactNode { const augs = this.getAugsSorted(); - const purchasable = augs.filter((aug: string) => - aug === AugmentationNames.NeuroFluxGovernor || + const purchasable = augs.filter((aug: string) => aug === AugmentationNames.NeuroFluxGovernor || (!this.props.p.augmentations.some(a => a.name === aug) && - !this.props.p.queuedAugmentations.some(a => a.name === aug)) + !this.props.p.queuedAugmentations.some(a => a.name === aug)), ) - const parent = this; - function purchaseableAugmentation(aug: string) { + const purchaseableAugmentation = (aug: string): React.ReactNode => { return ( ) } diff --git a/src/Faction/ui/DonateOption.tsx b/src/Faction/ui/DonateOption.tsx index acb2e9222..9b0c63d48 100644 --- a/src/Faction/ui/DonateOption.tsx +++ b/src/Faction/ui/DonateOption.tsx @@ -7,7 +7,6 @@ import { CONSTANTS } from "../../Constants"; import { Faction } from "../../Faction/Faction"; import { IPlayer } from "../../PersonObjects/IPlayer"; -import { numeralWrapper } from "../../ui/numeralFormat"; import { Money } from "../../ui/React/Money"; import { Reputation } from "../../ui/React/Reputation"; @@ -32,7 +31,7 @@ const inputStyleMarkup = { export class DonateOption extends React.Component { // Style markup for block elements. Stored as property - blockStyle: object = { display: "block" }; + blockStyle: any = { display: "block" }; constructor(props: IProps) { super(props); @@ -87,11 +86,11 @@ export class DonateOption extends React.Component { } } - render() { + render(): React.ReactNode { return (
    - + { return <>Reputation: {Reputation(this.props.faction.playerReputation)} } - render() { + render(): React.ReactNode { const favorTooltip = "Faction favor increases the rate at which you earn reputation for " + "this faction by 1% per favor. Faction favor is gained whenever you " + "reset after installing an Augmentation. The amount of " + diff --git a/src/Faction/ui/Option.tsx b/src/Faction/ui/Option.tsx index 72c96df36..148790886 100644 --- a/src/Faction/ui/Option.tsx +++ b/src/Faction/ui/Option.tsx @@ -14,7 +14,7 @@ type IProps = { } export class Option extends React.Component { - render() { + render(): React.ReactNode { return (
    diff --git a/src/Faction/ui/PurchaseableAugmentation.tsx b/src/Faction/ui/PurchaseableAugmentation.tsx index 95f53bddd..ece801260 100644 --- a/src/Faction/ui/PurchaseableAugmentation.tsx +++ b/src/Faction/ui/PurchaseableAugmentation.tsx @@ -17,7 +17,6 @@ import { AugmentationNames } from "../../Augmentation/data/AugmentationNames"; import { Faction } from "../../Faction/Faction"; import { IPlayer } from "../../PersonObjects/IPlayer"; import { Settings } from "../../Settings/Settings"; -import { numeralWrapper } from "../../ui/numeralFormat"; import { Money } from "../../ui/React/Money"; import { Reputation } from "../../ui/React/Reputation"; import { IMap } from "../../types"; @@ -42,35 +41,37 @@ const inlineStyleMarkup = { } export class PurchaseableAugmentation extends React.Component { - aug: Augmentation | null; + aug: Augmentation; constructor(props: IProps) { super(props); - this.aug = Augmentations[this.props.augName]; + const aug = Augmentations[this.props.augName]; + if(aug == null) throw new Error(`aug ${this.props.augName} does not exists`); + this.aug = aug; this.handleClick = this.handleClick.bind(this); } getMoneyCost(): number { - return this.aug!.baseCost * this.props.faction.getInfo().augmentationPriceMult; + return this.aug.baseCost * this.props.faction.getInfo().augmentationPriceMult; } getRepCost(): number { - return this.aug!.baseRepRequirement * this.props.faction.getInfo().augmentationRepRequirementMult; + return this.aug.baseRepRequirement * this.props.faction.getInfo().augmentationRepRequirementMult; } - handleClick() { + handleClick(): void { if (!Settings.SuppressBuyAugmentationConfirmation) { - purchaseAugmentationBoxCreate(this.aug!, this.props.faction); + purchaseAugmentationBoxCreate(this.aug, this.props.faction); } else { - purchaseAugmentation(this.aug!, this.props.faction); + purchaseAugmentation(this.aug, this.props.faction); } } // Whether the player has the prerequisite Augmentations hasPrereqs(): boolean { - return hasAugmentationPrereqs(this.aug!); + return hasAugmentationPrereqs(this.aug); } // Whether the player has enough rep for this Augmentation @@ -98,7 +99,7 @@ export class PurchaseableAugmentation extends React.Component { return owned; } - render() { + render(): React.ReactNode { if (this.aug == null) { console.error(`Invalid Augmentation when trying to create PurchaseableAugmentation display element: ${this.props.augName}`); return null; @@ -108,9 +109,9 @@ export class PurchaseableAugmentation extends React.Component { const repCost = this.getRepCost(); // Determine UI properties - let disabled: boolean = false; + let disabled = false; let status: JSX.Element = <>; - let color: string = ""; + let color = ""; if (!this.hasPrereqs()) { disabled = true; status = <>LOCKED (Requires {this.aug.prereqs.map(aug => AugFormat(aug))} as prerequisite); diff --git a/src/Faction/ui/Root.tsx b/src/Faction/ui/Root.tsx index aa0c2a935..fb9156309 100644 --- a/src/Faction/ui/Root.tsx +++ b/src/Faction/ui/Root.tsx @@ -69,7 +69,7 @@ const GangNames = [ "The Dark Army", "Speakers for the Dead", "NiteSec", - "The Black Hand" + "The Black Hand", ]; export class FactionRoot extends React.Component { @@ -92,7 +92,7 @@ export class FactionRoot extends React.Component { this.startSecurityWork = this.startSecurityWork.bind(this); } - manageGang() { + manageGang(): void { // If player already has a gang, just go to the gang UI if (this.props.p.inGang()) { return this.props.engine.loadGangContent(); @@ -146,7 +146,7 @@ export class FactionRoot extends React.Component { "create a Gang with, and each of these Factions have all Augmentations available."); } - rerender() { + rerender(): void { this.setState((prevState) => { return { rerenderFlag: !prevState.rerenderFlag, @@ -155,42 +155,42 @@ export class FactionRoot extends React.Component { } // Route to the main faction page - routeToMain() { + routeToMain(): void { this.setState({ purchasingAugs: false }); } // Route to the purchase augmentation UI for this faction - routeToPurchaseAugs() { + routeToPurchaseAugs(): void { this.setState({ purchasingAugs: true }); } - sleevePurchases() { + sleevePurchases(): void { createSleevePurchasesFromCovenantPopup(this.props.p); } - startFieldWork() { + startFieldWork(): void { this.props.p.startFactionFieldWork(this.props.faction); } - startHackingContracts() { + startHackingContracts(): void { this.props.p.startFactionHackWork(this.props.faction); } - startHackingMission() { + startHackingMission(): void { const fac = this.props.faction; this.props.engine.loadMissionContent(); this.props.startHackingMissionFn(fac); } - startSecurityWork() { + startSecurityWork(): void { this.props.p.startFactionSecurityWork(this.props.faction); } - render() { + render(): React.ReactNode { return this.state.purchasingAugs ? this.renderAugmentationsPage() : this.renderMainPage(); } - renderMainPage() { + renderMainPage(): React.ReactNode { const p = this.props.p; const faction = this.props.faction; const factionInfo = faction.getInfo(); @@ -288,7 +288,7 @@ export class FactionRoot extends React.Component { ) } - renderAugmentationsPage() { + renderAugmentationsPage(): React.ReactNode { return (
    { var filterValue = UIElems.gangMemberUpgradeBoxFilter.value.toString(); this.createGangMemberUpgradeBox(player, filterValue); - } + }, }); UIElems.gangMemberUpgradeBoxDiscount = createElement("p", { innerText: "Discount: -" + numeralWrapper.formatPercentage(1 - 1 / this.getDiscount()), marginLeft: "6px", tooltip: "You get a discount on equipment and upgrades based on your gang's " + - "respect and power. More respect and power leads to more discounts." + "respect and power. More respect and power leads to more discounts.", }); UIElems.gangMemberUpgradeBoxElements = [UIElems.gangMemberUpgradeBoxFilter, UIElems.gangMemberUpgradeBoxDiscount]; @@ -1087,7 +1085,7 @@ GangMember.prototype.createGangMemberUpgradePanel = function(gangObj, player) { }); var header = createElement("h1", { - innerText: this.name + " (" + this.task + ")" + innerText: this.name + " (" + this.task + ")", }); container.appendChild(header); @@ -1192,7 +1190,7 @@ GangMember.prototype.createGangMemberUpgradePanel = function(gangObj, player) { clickListener:() => { memberObj.buyUpgrade(upg, player, gangObj); return false; - } + }, } // For the last two divs, tooltip should be on the left @@ -1266,10 +1264,7 @@ Gang.prototype.displayGangContent = function(player) { }); // Get variables - var facName = this.facName, - members = this.members, - wanted = this.wanted, - respect = this.respect; + var facName = this.facName; // Back button UIElems.gangContainer.appendChild(createElement("a", { @@ -1278,7 +1273,7 @@ Gang.prototype.displayGangContent = function(player) { Engine.loadFactionContent(); displayFactionContent(facName); return false; - } + }, })); // Buttons to switch between panels @@ -1294,7 +1289,7 @@ Gang.prototype.displayGangContent = function(player) { UIElems.territoryButton.classList.toggle("a-link-button"); this.updateGangContent(); return false; - } + }, }) UIElems.territoryButton = createElement("a", { id:"gang-territory-subpage-button", class:"a-link-button", @@ -1308,7 +1303,7 @@ Gang.prototype.displayGangContent = function(player) { UIElems.territoryButton.classList.toggle("a-link-button"); this.updateGangContent(); return false; - } + }, }); UIElems.gangContainer.appendChild(UIElems.managementButton); UIElems.gangContainer.appendChild(UIElems.territoryButton); @@ -1338,7 +1333,7 @@ Gang.prototype.displayGangContent = function(player) { "Installing Augmentations does NOT reset your progress with your Gang. " + "Furthermore, after installing Augmentations, you will " + "automatically be a member of whatever Faction you created your gang with.

    " + - "You can also manage your gang programmatically through Netscript using the Gang API" + "You can also manage your gang programmatically through Netscript using the Gang API", }); UIElems.gangManagementSubpage.appendChild(UIElems.gangDesc); @@ -1399,7 +1394,7 @@ Gang.prototype.displayGangContent = function(player) { }); createPopup(popupId, [txt, br, nameInput, yesBtn, noBtn]); nameInput.focus(); - } + }, }); UIElems.gangManagementSubpage.appendChild(UIElems.gangRecruitMemberButton); @@ -1425,7 +1420,7 @@ Gang.prototype.displayGangContent = function(player) { } } return false; - } + }, }); UIElems.gangCollapseAllButton = createElement("a", { class:"a-link-button", display:"inline-block", @@ -1439,21 +1434,21 @@ Gang.prototype.displayGangContent = function(player) { } } return false; - } + }, }); UIElems.gangMemberFilter = createElement("input", { type:"text", placeholder:"Filter gang members", margin:"5px", padding:"5px", class:"text-input", onkeyup:() => { this.displayGangMemberList(); - } + }, }); UIElems.gangManageEquipmentButton = createElement("a", { class:"a-link-button", display:"inline-block", innerHTML:"Manage Equipment", clickListener: () => { this.createGangMemberUpgradeBox(player); - } + }, }); UIElems.gangManagementSubpage.appendChild(UIElems.gangExpandAllButton); UIElems.gangManagementSubpage.appendChild(UIElems.gangCollapseAllButton); @@ -1467,7 +1462,7 @@ Gang.prototype.displayGangContent = function(player) { // Subpage for seeing gang territory information UIElems.gangTerritorySubpage = createElement("div", { - id:"gang-territory-subpage", display:"none" + id:"gang-territory-subpage", display:"none", }); // Info text for territory page @@ -1485,7 +1480,7 @@ Gang.prototype.displayGangContent = function(player) { "NOTE: Gang members assigned to 'Territory Warfare' can be killed during clashes. This can happen regardless of whether you win " + "or lose the clash. A gang member being killed results in both respect and power loss for your gang.

    " + "The amount of territory you have affects all aspects of your Gang members' production, including " + - "money, respect, and wanted level. It is very beneficial to have high territory control.

    " + "money, respect, and wanted level. It is very beneficial to have high territory control.

    ", }); UIElems.gangTerritorySubpage.appendChild(UIElems.gangTerritoryDescText); @@ -1654,7 +1649,7 @@ Gang.prototype.updateGangContent = function() { tooltip: "Represents the amount of respect your gang has from other gangs and criminal " + "organizations. Your respect affects the amount of money " + "your gang members will earn, and also determines how much " + - "reputation you are earning with your gang's corresponding Faction." + "reputation you are earning with your gang's corresponding Faction.", })); UIElems.gangInfo.appendChild(createElement("br")); @@ -1664,7 +1659,7 @@ Gang.prototype.updateGangContent = function() { " (" + numeralWrapper.formatWanted(5*this.wantedGainRate) + " / sec)", tooltip: "Represents how much the gang is wanted by law enforcement. The higher " + "your gang's wanted level, the harder it will be for your gang members " + - "to make money and earn respect. Note that the minimum wanted level is 1." + "to make money and earn respect. Note that the minimum wanted level is 1.", })); UIElems.gangInfo.appendChild(createElement("br")); @@ -1673,7 +1668,7 @@ Gang.prototype.updateGangContent = function() { UIElems.gangInfo.appendChild(createElement("p", { // Wanted Level multiplier display: "inline-block", innerText: `Wanted Level Penalty: -${formatNumber(wantedPenalty, 2)}%`, - tooltip: "Penalty for respect and money gain rates due to Wanted Level" + tooltip: "Penalty for respect and money gain rates due to Wanted Level", })); UIElems.gangInfo.appendChild(createElement("br")); @@ -1695,7 +1690,7 @@ Gang.prototype.updateGangContent = function() { UIElems.gangInfo.appendChild(createElement("p", { // Territory multiplier display: "inline-block", innerText: `Territory: ${formatNumber(displayNumber, 3)}%`, - tooltip: "The percentage of total territory your Gang controls" + tooltip: "The percentage of total territory your Gang controls", })); UIElems.gangInfo.appendChild(createElement("br")); @@ -1757,7 +1752,6 @@ Gang.prototype.createGangMemberDisplayElement = function(memberObj) { hdrText: name, }); const li = accordion[0]; - const hdr = accordion[1]; const gangMemberDiv = accordion[2]; UIElems.gangMemberPanels[name]["panel"] = gangMemberDiv; @@ -1819,7 +1813,7 @@ Gang.prototype.createGangMemberDisplayElement = function(memberObj) { innerText: "Cancel", }); createPopup(popupId, [txt, confirmBtn, cancelBtn]); - } + }, }); const ascendHelpTip = createElement("div", { class: "help-tip", diff --git a/src/Hacking.ts b/src/Hacking.ts index cd1676ecf..b45d49ee6 100644 --- a/src/Hacking.ts +++ b/src/Hacking.ts @@ -1,9 +1,7 @@ import { BitNodeMultipliers } from "./BitNode/BitNodeMultipliers"; -import { Player } from "./Player"; import { IPlayer } from "./PersonObjects/IPlayer"; import { calculateIntelligenceBonus } from "./PersonObjects/formulas/intelligence"; import { Server } from "./Server/Server"; -import { HacknetServer } from "./Hacknet/HacknetServer"; /** * Returns the chance the player has to successfully hack a server diff --git a/src/Hacking/netscriptCanHack.ts b/src/Hacking/netscriptCanHack.ts index 204d959a5..ee48ace6a 100644 --- a/src/Hacking/netscriptCanHack.ts +++ b/src/Hacking/netscriptCanHack.ts @@ -15,7 +15,7 @@ function baseCheck(server: Server, fnName: string): IReturnStatus { if (!("requiredHackingSkill" in server)) { return { res: false, - msg: `Cannot ${fnName} ${hostname} server because it is a Hacknet Node` + msg: `Cannot ${fnName} ${hostname} server because it is a Hacknet Node`, } } @@ -33,7 +33,7 @@ export function netscriptCanHack(server: Server, p: IPlayer): IReturnStatus { const initialCheck = baseCheck(server, "hack"); if (!initialCheck.res) { return initialCheck; } - let s = server; + const s = server; if (s.requiredHackingSkill > p.hacking_skill) { return { res: false, diff --git a/src/Hacknet/HacknetHelpers.jsx b/src/Hacknet/HacknetHelpers.jsx index 01877da3e..22ed184e1 100644 --- a/src/Hacknet/HacknetHelpers.jsx +++ b/src/Hacknet/HacknetHelpers.jsx @@ -20,7 +20,7 @@ import { generateRandomContract } from "../CodingContractGenerator"; import { iTutorialSteps, iTutorialNextStep, - ITutorial + ITutorial, } from "../InteractiveTutorial"; import { Player } from "../Player"; import { AllServers } from "../Server/AllServers"; @@ -28,8 +28,6 @@ import { GetServerByHostname } from "../Server/ServerHelpers"; import { SourceFileFlags } from "../SourceFile/SourceFileFlags"; import { Page, routing } from "../ui/navigationTracking"; -import { getElementById } from "../../utils/uiHelpers/getElementById"; - import React from "react"; import ReactDOM from "react-dom"; import { HacknetRoot } from "./ui/Root"; @@ -68,7 +66,7 @@ export function purchaseHacknet() { if (!Player.canAfford(cost)) { return -1; } Player.loseMoney(cost); - const server = Player.createHacknetServer(); + Player.createHacknetServer(); updateHashManagerCapacity(); return numOwned; diff --git a/src/Hacknet/HacknetNode.ts b/src/Hacknet/HacknetNode.ts index ea3204f29..6a356ef41 100644 --- a/src/Hacknet/HacknetNode.ts +++ b/src/Hacknet/HacknetNode.ts @@ -8,7 +8,6 @@ import { IHacknetNode } from "./IHacknetNode"; import { CONSTANTS } from "../Constants"; -import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; import { calculateMoneyGainRate, calculateLevelUpgradeCost, @@ -23,58 +22,52 @@ import { Generic_fromJSON, Reviver } from "../../utils/JSONReviver"; export class HacknetNode implements IHacknetNode { - /** - * Initiatizes a HacknetNode object from a JSON save state. - */ - static fromJSON(value: any): HacknetNode { - return Generic_fromJSON(HacknetNode, value.data); - } // Node's number of cores - cores: number = 1; + cores = 1; // Node's Level - level: number = 1; + level = 1; // Node's production per second - moneyGainRatePerSecond: number = 0; + moneyGainRatePerSecond = 0; // Identifier for Node. Includes the full "name" (hacknet-node-N) name: string; // How long this Node has existed, in seconds - onlineTimeSeconds: number = 0; + onlineTimeSeconds = 0; // Node's RAM (GB) - ram: number = 1; + ram = 1; // Total money earned by this Node - totalMoneyGenerated: number = 0; + totalMoneyGenerated = 0; - constructor(name: string="", prodMult: number=1) { + constructor(name="", prodMult=1) { this.name = name; this.updateMoneyGainRate(prodMult); } // Get the cost to upgrade this Node's number of cores - calculateCoreUpgradeCost(levels: number=1, costMult: number): number { + calculateCoreUpgradeCost(levels=1, costMult: number): number { return calculateCoreUpgradeCost(this.cores, levels, costMult); } // Get the cost to upgrade this Node's level - calculateLevelUpgradeCost(levels: number=1, costMult: number): number { + calculateLevelUpgradeCost(levels=1, costMult: number): number { return calculateLevelUpgradeCost(this.level, levels, costMult); } // Get the cost to upgrade this Node's RAM - calculateRamUpgradeCost(levels: number=1, costMult: number): number { + calculateRamUpgradeCost(levels=1, costMult: number): number { return calculateRamUpgradeCost(this.ram, levels, costMult); } // Process this Hacknet Node in the game loop. // Returns the amount of money generated - process(numCycles: number=1): number { + process(numCycles=1): number { const seconds = numCycles * CONSTANTS.MilliPerCycle / 1000; let gain = this.moneyGainRatePerSecond * seconds; if (isNaN(gain)) { @@ -90,21 +83,21 @@ export class HacknetNode implements IHacknetNode { // Upgrade this Node's number of cores, if possible // Returns a boolean indicating whether new cores were successfully bought - upgradeCore(levels: number=1, prodMult: number): void { + upgradeCore(levels=1, prodMult: number): void { this.cores = Math.min(HacknetNodeConstants.MaxCores, Math.round(this.cores + levels)); this.updateMoneyGainRate(prodMult); } // Upgrade this Node's level, if possible // Returns a boolean indicating whether the level was successfully updated - upgradeLevel(levels: number=1, prodMult: number): void { + upgradeLevel(levels=1, prodMult: number): void { this.level = Math.min(HacknetNodeConstants.MaxLevel, Math.round(this.level + levels)); this.updateMoneyGainRate(prodMult); } // Upgrade this Node's RAM, if possible // Returns a boolean indicating whether the RAM was successfully upgraded - upgradeRam(levels: number=1, prodMult: number): void { + upgradeRam(levels=1, prodMult: number): void { for (let i = 0; i < levels; ++i) { this.ram *= 2; // Ram is always doubled } @@ -127,6 +120,14 @@ export class HacknetNode implements IHacknetNode { toJSON(): any { return Generic_toJSON("HacknetNode", this); } + + /** + * Initiatizes a HacknetNode object from a JSON save state. + */ + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types + static fromJSON(value: any): HacknetNode { + return Generic_fromJSON(HacknetNode, value.data); + } } Reviver.constructors.HacknetNode = HacknetNode; diff --git a/src/Hacknet/HacknetServer.ts b/src/Hacknet/HacknetServer.ts index 9ea3f53ea..74f093ac5 100644 --- a/src/Hacknet/HacknetServer.ts +++ b/src/Hacknet/HacknetServer.ts @@ -5,7 +5,6 @@ import { CONSTANTS } from "../Constants"; import { IHacknetNode } from "./IHacknetNode"; -import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; import { BaseServer } from "../Server/BaseServer"; import { RunningScript } from "../Script/RunningScript"; import { HacknetServerConstants } from "./data/Constants"; @@ -22,7 +21,7 @@ import { createRandomIp } from "../../utils/IPAddress"; import { Generic_fromJSON, Generic_toJSON, - Reviver + Reviver, } from "../../utils/JSONReviver"; interface IConstructorParams { @@ -35,31 +34,27 @@ interface IConstructorParams { } export class HacknetServer extends BaseServer implements IHacknetNode { - // Initializes a HacknetServer Object from a JSON save state - static fromJSON(value: any): HacknetServer { - return Generic_fromJSON(HacknetServer, value.data); - } // Cache level. Affects hash Capacity - cache: number = 1; + cache = 1; // Number of cores. Improves hash production - cores: number = 1; + cores = 1; // Number of hashes that can be stored by this Hacknet Server - hashCapacity: number = 0; + hashCapacity = 0; // Hashes produced per second - hashRate: number = 0; + hashRate = 0; // Similar to Node level. Improves hash production - level: number = 1; + level = 1; // How long this HacknetServer has existed, in seconds - onlineTimeSeconds: number = 0; + onlineTimeSeconds = 0; // Total number of hashes earned by this server - totalHashesGenerated: number = 0; + totalHashesGenerated = 0; constructor(params: IConstructorParams={ hostname: "", ip: createRandomIp() }) { super(params); @@ -85,7 +80,7 @@ export class HacknetServer extends BaseServer implements IHacknetNode { } // Process this Hacknet Server in the game loop. Returns the number of hashes generated - process(numCycles: number=1): number { + process(numCycles=1): number { const seconds = numCycles * CONSTANTS.MilliPerCycle / 1000; return this.hashRate * seconds; @@ -141,6 +136,12 @@ export class HacknetServer extends BaseServer implements IHacknetNode { toJSON(): any { return Generic_toJSON("HacknetServer", this); } + + // Initializes a HacknetServer Object from a JSON save state + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types + static fromJSON(value: any): HacknetServer { + return Generic_fromJSON(HacknetServer, value.data); + } } Reviver.constructors.HacknetServer = HacknetServer; diff --git a/src/Hacknet/HashManager.ts b/src/Hacknet/HashManager.ts index aba43f9ec..d3a454740 100644 --- a/src/Hacknet/HashManager.ts +++ b/src/Hacknet/HashManager.ts @@ -15,17 +15,13 @@ import { Generic_fromJSON, Reviver } from "../../utils/JSONReviver"; export class HashManager { - // Initiatizes a HashManager object from a JSON save state. - static fromJSON(value: any): HashManager { - return Generic_fromJSON(HashManager, value.data); - } // Max number of hashes this can hold. Equal to the sum of capacities of // all Hacknet Servers - capacity: number = 0; + capacity = 0; // Number of hashes currently in storage - hashes: number = 0; + hashes = 0; // Map of Hash Upgrade Name -> levels in that upgrade upgrades: IMap = {}; @@ -159,6 +155,12 @@ export class HashManager { toJSON(): any { return Generic_toJSON("HashManager", this); } + + // Initiatizes a HashManager object from a JSON save state. + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types + static fromJSON(value: any): HashManager { + return Generic_fromJSON(HashManager, value.data); + } } Reviver.constructors.HashManager = HashManager; diff --git a/src/Hacknet/HashUpgrade.ts b/src/Hacknet/HashUpgrade.ts index db7518518..fe59838ca 100644 --- a/src/Hacknet/HashUpgrade.ts +++ b/src/Hacknet/HashUpgrade.ts @@ -23,25 +23,25 @@ export class HashUpgrade { * Base cost for this upgrade. Every time the upgrade is purchased, * its cost increases by this same amount (so its 1x, 2x, 3x, 4x, etc.) */ - costPerLevel: number = 0; + costPerLevel = 0; /** * Description of what the upgrade does */ - desc: string = ""; + desc = ""; /** * Boolean indicating that this upgrade's effect affects a single server, * the "target" server */ - hasTargetServer: boolean = false; + hasTargetServer = false; // Name of upgrade - name: string = ""; + name = ""; // Generic value used to indicate the potency/amount of this upgrade's effect // The meaning varies between different upgrades - value: number = 0; + value = 0; constructor(p: IConstructorParams) { if (p.cost != null) { this.cost = p.cost; } diff --git a/src/Hacknet/HashUpgrades.ts b/src/Hacknet/HashUpgrades.ts index 0a89e2525..da7f8f800 100644 --- a/src/Hacknet/HashUpgrades.ts +++ b/src/Hacknet/HashUpgrades.ts @@ -9,7 +9,7 @@ import { IMap } from "../types"; export const HashUpgrades: IMap = {}; -function createHashUpgrade(p: IConstructorParams) { +function createHashUpgrade(p: IConstructorParams): void { HashUpgrades[p.name] = new HashUpgrade(p); } diff --git a/src/Hacknet/formulas/HacknetNodes.ts b/src/Hacknet/formulas/HacknetNodes.ts index 717ab3aeb..176027c98 100644 --- a/src/Hacknet/formulas/HacknetNodes.ts +++ b/src/Hacknet/formulas/HacknetNodes.ts @@ -14,7 +14,7 @@ export function calculateMoneyGainRate(level: number, ram: number, cores: number BitNodeMultipliers.HacknetNodeMoney; } -export function calculateLevelUpgradeCost(startingLevel: number, extraLevels: number=1, costMult: number=1): number { +export function calculateLevelUpgradeCost(startingLevel: number, extraLevels=1, costMult=1): number { const sanitizedLevels = Math.round(extraLevels); if (isNaN(sanitizedLevels) || sanitizedLevels < 1) { return 0; @@ -35,7 +35,7 @@ export function calculateLevelUpgradeCost(startingLevel: number, extraLevels: nu return HacknetNodeConstants.BaseCost / 2 * totalMultiplier * costMult; } -export function calculateRamUpgradeCost(startingRam: number, extraLevels: number=1, costMult: number=1): number { +export function calculateRamUpgradeCost(startingRam: number, extraLevels=1, costMult=1): number { const sanitizedLevels = Math.round(extraLevels); if (isNaN(sanitizedLevels) || sanitizedLevels < 1) { return 0; @@ -64,7 +64,7 @@ export function calculateRamUpgradeCost(startingRam: number, extraLevels: number return totalCost; } -export function calculateCoreUpgradeCost(startingCore: number, extraLevels: number=1, costMult: number=1): number { +export function calculateCoreUpgradeCost(startingCore: number, extraLevels=1, costMult=1): number { const sanitizedCores = Math.round(extraLevels); if (isNaN(sanitizedCores) || sanitizedCores < 1) { return 0; @@ -88,7 +88,7 @@ export function calculateCoreUpgradeCost(startingCore: number, extraLevels: numb return totalCost; } -export function calculateNodeCost(n: number, mult: number=1): number { +export function calculateNodeCost(n: number, mult=1): number { if(n <= 0) { return 0; } diff --git a/src/Hacknet/formulas/HacknetServers.ts b/src/Hacknet/formulas/HacknetServers.ts index ef73b12b2..8908da045 100644 --- a/src/Hacknet/formulas/HacknetServers.ts +++ b/src/Hacknet/formulas/HacknetServers.ts @@ -15,7 +15,7 @@ export function calculateHashGainRate(level: number, ramUsed: number, maxRam: nu BitNodeMultipliers.HacknetNodeMoney; } -export function calculateLevelUpgradeCost(startingLevel: number, extraLevels: number=1, costMult: number=1): number { +export function calculateLevelUpgradeCost(startingLevel: number, extraLevels=1, costMult=1): number { const sanitizedLevels = Math.round(extraLevels); if (isNaN(sanitizedLevels) || sanitizedLevels < 1) { return 0; @@ -36,7 +36,7 @@ export function calculateLevelUpgradeCost(startingLevel: number, extraLevels: nu return 10 * HacknetServerConstants.BaseCost * totalMultiplier * costMult; } -export function calculateRamUpgradeCost(startingRam: number, extraLevels: number=1, costMult: number=1): number { +export function calculateRamUpgradeCost(startingRam: number, extraLevels=1, costMult=1): number { const sanitizedLevels = Math.round(extraLevels); if (isNaN(sanitizedLevels) || sanitizedLevels < 1) { return 0; @@ -50,8 +50,8 @@ export function calculateRamUpgradeCost(startingRam: number, extraLevels: number let numUpgrades = Math.round(Math.log2(startingRam)); let currentRam = startingRam; for (let i = 0; i < sanitizedLevels; ++i) { - let baseCost = currentRam * HacknetServerConstants.RamBaseCost; - let mult = Math.pow(HacknetServerConstants.UpgradeRamMult, numUpgrades); + const baseCost = currentRam * HacknetServerConstants.RamBaseCost; + const mult = Math.pow(HacknetServerConstants.UpgradeRamMult, numUpgrades); totalCost += (baseCost * mult); @@ -63,7 +63,7 @@ export function calculateRamUpgradeCost(startingRam: number, extraLevels: number return totalCost; } -export function calculateCoreUpgradeCost(startingCores: number, extraLevels: number=1, costMult: number=1): number { +export function calculateCoreUpgradeCost(startingCores: number, extraLevels=1, costMult=1): number { const sanitizedLevels = Math.round(extraLevels); if (isNaN(sanitizedLevels) || sanitizedLevels < 1) { return 0; @@ -86,7 +86,7 @@ export function calculateCoreUpgradeCost(startingCores: number, extraLevels: num return totalCost; } -export function calculateCacheUpgradeCost(startingCache: number, extraLevels: number=1): number { +export function calculateCacheUpgradeCost(startingCache: number, extraLevels=1): number { const sanitizedLevels = Math.round(extraLevels); if (isNaN(sanitizedLevels) || sanitizedLevels < 1) { return 0; @@ -108,7 +108,7 @@ export function calculateCacheUpgradeCost(startingCache: number, extraLevels: nu return totalCost; } -export function calculateServerCost(n: number, mult: number=1): number { +export function calculateServerCost(n: number, mult=1): number { if (n-1 >= HacknetServerConstants.MaxServers) { return Infinity; } return HacknetServerConstants.BaseCost * Math.pow(HacknetServerConstants.PurchaseMult, n-1) * mult; diff --git a/src/Hacknet/ui/HacknetNode.jsx b/src/Hacknet/ui/HacknetNode.jsx index 579a5a198..d2321e061 100644 --- a/src/Hacknet/ui/HacknetNode.jsx +++ b/src/Hacknet/ui/HacknetNode.jsx @@ -16,7 +16,6 @@ import { import { Player } from "../../Player"; -import { numeralWrapper } from "../../ui/numeralFormat"; import { Money } from "../../ui/React/Money"; import { MoneyRate } from "../../ui/React/MoneyRate"; diff --git a/src/Hacknet/ui/HacknetServer.jsx b/src/Hacknet/ui/HacknetServer.jsx index 076b17180..2fd02328a 100644 --- a/src/Hacknet/ui/HacknetServer.jsx +++ b/src/Hacknet/ui/HacknetServer.jsx @@ -19,7 +19,6 @@ import { import { Player } from "../../Player"; -import { numeralWrapper } from "../../ui/numeralFormat"; import { Money } from "../../ui/React/Money"; import { Hashes } from "../../ui/React/Hashes"; import { HashRate } from "../../ui/React/HashRate"; diff --git a/src/Hacknet/ui/HashUpgradePopup.jsx b/src/Hacknet/ui/HashUpgradePopup.jsx index 7c79b7e3a..3722941bb 100644 --- a/src/Hacknet/ui/HashUpgradePopup.jsx +++ b/src/Hacknet/ui/HashUpgradePopup.jsx @@ -8,12 +8,9 @@ import { HashManager } from "../HashManager"; import { HashUpgrades } from "../HashUpgrades"; import { Player } from "../../Player"; -import { AllServers } from "../../Server/AllServers"; -import { Server } from "../../Server/Server"; import { numeralWrapper } from "../../ui/numeralFormat"; -import { removePopup } from "../../ui/React/createPopup"; import { PopupCloseButton } from "../../ui/React/PopupCloseButton"; import { ServerDropdown, ServerType } from "../../ui/React/ServerDropdown" @@ -36,7 +33,7 @@ class HashUpgrade extends React.Component { changeTargetServer(e) { this.setState({ - selectedServer: e.target.value + selectedServer: e.target.value, }); } diff --git a/src/Hacknet/ui/PlayerInfo.jsx b/src/Hacknet/ui/PlayerInfo.jsx index 10ca42e3e..0db2cc528 100644 --- a/src/Hacknet/ui/PlayerInfo.jsx +++ b/src/Hacknet/ui/PlayerInfo.jsx @@ -8,7 +8,6 @@ import React from "react"; import { hasHacknetServers } from "../HacknetHelpers"; import { Player } from "../../Player"; -import { numeralWrapper } from "../../ui/numeralFormat"; import { Money } from "../../ui/React/Money"; import { MoneyRate } from "../../ui/React/MoneyRate"; import { HashRate } from "../../ui/React/HashRate"; diff --git a/src/Hacknet/ui/PurchaseButton.jsx b/src/Hacknet/ui/PurchaseButton.jsx index 96831fcb4..363e4e0ba 100644 --- a/src/Hacknet/ui/PurchaseButton.jsx +++ b/src/Hacknet/ui/PurchaseButton.jsx @@ -6,7 +6,6 @@ import React from "react"; import { hasHacknetServers, hasMaxNumberHacknetServers } from "../HacknetHelpers"; import { Player } from "../../Player"; -import { numeralWrapper } from "../../ui/numeralFormat"; import { Money } from "../../ui/React/Money"; export function PurchaseButton(props) { diff --git a/src/Hacknet/ui/Root.jsx b/src/Hacknet/ui/Root.jsx index 886ddae19..4f77bbb07 100644 --- a/src/Hacknet/ui/Root.jsx +++ b/src/Hacknet/ui/Root.jsx @@ -20,7 +20,6 @@ import { Player } from "../../Player"; import { AllServers } from "../../Server/AllServers"; import { createPopup } from "../../ui/React/createPopup"; -import { PopupCloseButton } from "../../ui/React/PopupCloseButton"; export const PurchaseMultipliers = Object.freeze({ "x1": 1, diff --git a/src/Infiltration.js b/src/Infiltration.js index f6bc21ce7..2ac800e29 100644 --- a/src/Infiltration.js +++ b/src/Infiltration.js @@ -490,7 +490,6 @@ function updateInfiltrationLevelText(inst) { BitNodeMultipliers.InfiltrationMoney; } - var expMultiplier = 2 * inst.clearanceLevel / inst.maxClearanceLevel; // TODO: fix this to not rely on
     and whitespace for formatting...
         /* eslint-disable no-irregular-whitespace */
         document.getElementById("infiltration-level-text").innerHTML =
    diff --git a/src/InteractiveTutorial.js b/src/InteractiveTutorial.js
    index 064bcefd0..a8e93b71f 100644
    --- a/src/InteractiveTutorial.js
    +++ b/src/InteractiveTutorial.js
    @@ -42,7 +42,7 @@ const orderedITutorialSteps = [
         "HacknetNodesGoToWorldPage",
         "WorldDescription",
         "TutorialPageInfo",
    -    "End"
    +    "End",
     ]
     
     // Create an 'enum' for the Steps
    @@ -500,13 +500,13 @@ function iTutorialEnd() {
             "Getting Started Guide" +
             "Documentation

    " + "The Beginner's Guide to Hacking was added to your home computer! It contains some tips/pointers for starting out with the game. " + - "To read it, go to Terminal and enter

    cat " + LiteratureNames.HackersStartingHandbook + "To read it, go to Terminal and enter

    cat " + LiteratureNames.HackersStartingHandbook, }); var gotitBtn = createElement("a", { class:"a-link-button", float:"right", padding:"6px", innerText:"Got it!", clickListener:()=>{ removeElementById(popupId); - } + }, }); createPopup(popupId, [txt, gotitBtn]); diff --git a/src/JSInterpreter.js b/src/JSInterpreter.js index 145423c44..179ca0b74 100644 --- a/src/JSInterpreter.js +++ b/src/JSInterpreter.js @@ -85,7 +85,7 @@ var Interpreter = function(code, opt_initFunc, lineOffset=0) { */ Interpreter.PARSE_OPTIONS = { ecmaVersion: 5, - locations: true + locations: true, }; /** @@ -94,7 +94,7 @@ Interpreter.PARSE_OPTIONS = { Interpreter.READONLY_DESCRIPTOR = { configurable: true, enumerable: true, - writable: false + writable: false, }; /** @@ -103,7 +103,7 @@ Interpreter.READONLY_DESCRIPTOR = { Interpreter.NONENUMERABLE_DESCRIPTOR = { configurable: true, enumerable: false, - writable: true + writable: true, }; /** @@ -112,7 +112,7 @@ Interpreter.NONENUMERABLE_DESCRIPTOR = { Interpreter.READONLY_NONENUMERABLE_DESCRIPTOR = { configurable: true, enumerable: false, - writable: false + writable: false, }; /** @@ -121,7 +121,7 @@ Interpreter.READONLY_NONENUMERABLE_DESCRIPTOR = { Interpreter.VARIABLE_DESCRIPTOR = { configurable: false, enumerable: true, - writable: true + writable: true, }; /** @@ -312,7 +312,7 @@ Interpreter.prototype.initGlobalScope = function(scope) { var strFunctions = [ [escape, 'escape'], [unescape, 'unescape'], [decodeURI, 'decodeURI'], [decodeURIComponent, 'decodeURIComponent'], - [encodeURI, 'encodeURI'], [encodeURIComponent, 'encodeURIComponent'] + [encodeURI, 'encodeURI'], [encodeURIComponent, 'encodeURIComponent'], ]; for (var i = 0; i < strFunctions.length; i++) { var wrapper = (function(nativeFunc) { @@ -1985,8 +1985,8 @@ Interpreter.prototype.nativeToPseudo = function(nativeObj) { Array.prototype.slice.call(arguments) .map(function(i) { return interpreter.pseudoToNative(i); - }) - ) + }), + ), ); }; return this.createNativeFunction(wrapper, undefined); @@ -2033,7 +2033,7 @@ Interpreter.prototype.pseudoToNative = function(pseudoObj, opt_cycles) { var cycles = opt_cycles || { pseudo: [], - native: [] + native: [], }; var i = cycles.pseudo.indexOf(pseudoObj); if (i !== -1) { @@ -2610,7 +2610,7 @@ Interpreter.prototype.setValue = function(ref, value) { BREAK: 1, CONTINUE: 2, RETURN: 3, - THROW: 4 + THROW: 4, }; /** @@ -2691,7 +2691,7 @@ Interpreter.prototype.unwind = function(type, value, label, lineNumberMsg="") { 'ReferenceError': ReferenceError, 'SyntaxError': SyntaxError, 'TypeError': TypeError, - 'URIError': URIError + 'URIError': URIError, }; var name = this.getProperty(value, 'name').toString(); var message = this.getProperty(value, 'message').valueOf(); @@ -3485,7 +3485,7 @@ Interpreter.prototype['stepObjectExpression'] = function(stack, state, node) { configurable: true, enumerable: true, get: kinds['get'], - set: kinds['set'] + set: kinds['set'], }; this.setProperty(state.object_, key, null, descriptor); } else { diff --git a/src/Locations/City.ts b/src/Locations/City.ts index 374b70f09..ed02e1933 100644 --- a/src/Locations/City.ts +++ b/src/Locations/City.ts @@ -20,7 +20,7 @@ export class City { */ asciiArt: string; - constructor(name: CityName, locations: LocationName[]=[], asciiArt: string='') { + constructor(name: CityName, locations: LocationName[]=[], asciiArt='') { this.name = name; this.locations = locations; this.asciiArt = asciiArt; diff --git a/src/Locations/Location.ts b/src/Locations/Location.ts index 7c67efc85..f3c421870 100644 --- a/src/Locations/Location.ts +++ b/src/Locations/Location.ts @@ -33,12 +33,12 @@ export class Location { /** * Cost multiplier that influences how expensive a gym/university is */ - costMult: number = 0; + costMult = 0; /** * Exp multiplier that influences how effective a gym/university is */ - expMult: number = 0; + expMult = 0; /** * Companies can be infiltrated. This contains the data required for that @@ -61,13 +61,13 @@ export class Location { * Tech vendors allow you to purchase servers. * This property defines the max RAM server you can purchase from this vendor */ - techVendorMaxRam: number = 0; + techVendorMaxRam = 0; /** * Tech vendors allow you to purchase servers. * This property defines the max RAM server you can purchase from this vendor */ - techVendorMinRam: number = 0; + techVendorMinRam = 0; constructor(p: IConstructorParams) { if (p.city) { this.city = p.city; } diff --git a/src/Locations/LocationsHelpers.tsx b/src/Locations/LocationsHelpers.tsx index 83465a600..217a8d0f0 100644 --- a/src/Locations/LocationsHelpers.tsx +++ b/src/Locations/LocationsHelpers.tsx @@ -15,7 +15,7 @@ import { safetlyCreateUniqueServer } from "../Server/ServerHelpers"; import { getPurchaseServerCost, purchaseRamForHomeComputer, - purchaseServer + purchaseServer, } from "../Server/ServerPurchases"; import { SpecialServerIps } from "../Server/SpecialServerIps"; import { Settings } from "../Settings/Settings"; @@ -32,7 +32,7 @@ import { yesNoTxtInpBoxGetYesButton, yesNoTxtInpBoxGetNoButton, yesNoTxtInpBoxClose, - yesNoTxtInpBoxCreate + yesNoTxtInpBoxCreate, } from "../../utils/YesNoBox"; import { createElement } from "../../utils/uiHelpers/createElement"; @@ -94,8 +94,8 @@ export function createPurchaseServerPopup(ram: number, p: IPlayer): void { return; } - var yesBtn = yesNoTxtInpBoxGetYesButton(); - var noBtn = yesNoTxtInpBoxGetNoButton(); + const yesBtn = yesNoTxtInpBoxGetYesButton(); + const noBtn = yesNoTxtInpBoxGetNoButton(); if (yesBtn == null || noBtn == null) { return; } yesBtn.innerHTML = "Purchase Server"; noBtn.innerHTML = "Cancel"; @@ -116,7 +116,7 @@ export function createPurchaseServerPopup(ram: number, p: IPlayer): void { * Create a popup that lets the player start a Corporation * @param {IPlayer} p - Player object */ -export function createStartCorporationPopup(p: IPlayer) { +export function createStartCorporationPopup(p: IPlayer): void { if (!p.canAccessCorporation() || p.hasCorporation()) { return; } const popupId = "create-corporation-popup"; @@ -158,7 +158,7 @@ export function createStartCorporationPopup(p: IPlayer) { "and manage your company in the City"); removeElementById(popupId); return false; - } + }, }); const seedMoneyButton = createElement("button", { @@ -179,11 +179,11 @@ export function createStartCorporationPopup(p: IPlayer) { } dialogBoxCreate( "Congratulations! You just started your own corporation with government seed money. " + - "You can visit and manage your company in the City" + "You can visit and manage your company in the City", ); removeElementById(popupId); return false; - } + }, }) const cancelBtn = createPopupCloseButton(popupId, { class: "popup-box-button" }); @@ -196,7 +196,7 @@ export function createStartCorporationPopup(p: IPlayer) { * Create a popup that lets the player upgrade the cores on his/her home computer * @param {IPlayer} p - Player object */ -export function createUpgradeHomeCoresPopup(p: IPlayer) { +export function createUpgradeHomeCoresPopup(p: IPlayer): void { const currentCores = p.getHomeComputer().cpuCores; if (currentCores >= 8) { dialogBoxCreate(<> @@ -214,7 +214,7 @@ export function createUpgradeHomeCoresPopup(p: IPlayer) { 100e12, 1e15, 20e15, - 200e15 + 200e15, ]; const cost: number = allCosts[currentCores]; @@ -231,7 +231,7 @@ export function createUpgradeHomeCoresPopup(p: IPlayer) { p.getHomeComputer().cpuCores++; dialogBoxCreate( "You purchased an additional CPU Core for your home computer! It now has " + - p.getHomeComputer().cpuCores + " cores." + p.getHomeComputer().cpuCores + " cores.", ); } yesNoBoxClose(); @@ -252,7 +252,7 @@ cost {Money(cost)}); * Create a popup that lets the player upgrade the RAM on his/her home computer * @param {IPlayer} p - Player object */ -export function createUpgradeHomeRamPopup(p: IPlayer) { +export function createUpgradeHomeRamPopup(p: IPlayer): void { const cost: number = p.getUpgradeHomeRamCost(); const ram: number = p.getHomeComputer().maxRam; @@ -291,7 +291,7 @@ export function createUpgradeHomeRamPopup(p: IPlayer) { * Attempt to purchase a TOR router * @param {IPlayer} p - Player object */ -export function purchaseTorRouter(p: IPlayer) { +export function purchaseTorRouter(p: IPlayer): void { if (p.hasTorRouter()) { dialogBoxCreate(`You already have a TOR Router`); return; @@ -304,7 +304,7 @@ export function purchaseTorRouter(p: IPlayer) { const darkweb = safetlyCreateUniqueServer({ ip: createUniqueRandomIp(), hostname:"darkweb", organizationName:"", - isConnectedTo:false, adminRights:false, purchasedByPlayer:false, maxRam:1 + isConnectedTo:false, adminRights:false, purchasedByPlayer:false, maxRam:1, }); AddToAllServers(darkweb); SpecialServerIps.addIp("Darkweb Server", darkweb.ip); @@ -314,6 +314,6 @@ export function purchaseTorRouter(p: IPlayer) { dialogBoxCreate( "You have purchased a Tor router!
    " + "You now have access to the dark web from your home computer
    " + - "Use the scan/scan-analyze commands to search for the dark web connection." + "Use the scan/scan-analyze commands to search for the dark web connection.", ); } diff --git a/src/Locations/data/LocationNames.ts b/src/Locations/data/LocationNames.ts index 0d9f8d532..dfb48c353 100644 --- a/src/Locations/data/LocationNames.ts +++ b/src/Locations/data/LocationNames.ts @@ -78,4 +78,4 @@ export enum LocationName { // Default name for Location objects Void = "The Void", -}; +} diff --git a/src/Locations/ui/ApplyToJobButton.tsx b/src/Locations/ui/ApplyToJobButton.tsx index 58f464257..1abea2ee3 100644 --- a/src/Locations/ui/ApplyToJobButton.tsx +++ b/src/Locations/ui/ApplyToJobButton.tsx @@ -15,7 +15,7 @@ type IProps = { entryPosType: CompanyPosition; onClick: (e: React.MouseEvent) => void; p: IPlayer; - style?: object; + style?: any; text: string; } @@ -28,14 +28,14 @@ export class ApplyToJobButton extends React.Component { getJobRequirementTooltip(): string { const pos = this.props.p.getNextCompanyPosition(this.props.company, this.props.entryPosType); - if (pos == null) { return "" }; + if (pos == null) { return "" } if (!this.props.company.hasPosition(pos)) { return ""; } return getJobRequirementText(this.props.company, pos, true); } - render() { + render(): React.ReactNode { return ( { - asciiCity() { - const thiscity = this; - const topprop = this.props; - - function LocationLetter(location: LocationName) { + asciiCity(): React.ReactNode { + const LocationLetter = (location: LocationName): JSX.Element => { if (location) - return + return X return * @@ -35,10 +36,9 @@ export class LocationCity extends React.Component { 'P': 15,'Q': 16,'R': 17,'S': 18,'T': 19,'U': 20,'V': 21,'W': 22, 'X': 23,'Y': 24,'Z': 25} - let locI = 0; - function lineElems(s: string) { - let elems: any[] = []; - let matches: any[] = []; + const lineElems = (s: string): JSX.Element[] => { + const elems: any[] = []; + const matches: any[] = []; let match: any; while ((match = locationLettersRegex.exec(s)) !== null) { matches.push(match); @@ -48,20 +48,18 @@ export class LocationCity extends React.Component { return elems; } - let parts: any[] = []; for(let i = 0; i < matches.length; i++) { const startI = i === 0 ? 0 : matches[i-1].index+1; const endI = matches[i].index; elems.push(s.slice(startI, endI)) const locationI = letterMap[s[matches[i].index]]; - elems.push(LocationLetter(thiscity.props.city.locations[locationI])) - locI++; + elems.push(LocationLetter(this.props.city.locations[locationI])) } elems.push(s.slice(matches[matches.length-1].index+1)) return elems; } - let elems: any[] = []; + const elems: JSX.Element[] = []; const lines = this.props.city.asciiArt.split('\n'); for(const i in lines) { elems.push(
    {lineElems(lines[i])}
    ) @@ -70,7 +68,7 @@ export class LocationCity extends React.Component { return elems; } - listCity() { + listCity(): React.ReactNode { const locationButtons = this.props.city.locations.map((locName) => { return (
  • @@ -86,7 +84,7 @@ export class LocationCity extends React.Component { ) } - render() { + render(): React.ReactNode { return ( <> {Settings.DisableASCIIArt ? this.listCity() : this.asciiCity()} diff --git a/src/Locations/ui/CompanyLocation.tsx b/src/Locations/ui/CompanyLocation.tsx index e3bcd1129..dc57c49a5 100644 --- a/src/Locations/ui/CompanyLocation.tsx +++ b/src/Locations/ui/CompanyLocation.tsx @@ -21,7 +21,6 @@ import { CompanyPositions } from "../../Company/CompanyPositions"; import * as posNames from "../../Company/data/companypositionnames"; import { IPlayer } from "../../PersonObjects/IPlayer"; -import { numeralWrapper } from "../../ui/numeralFormat"; import { StdButton } from "../../ui/React/StdButton"; import { Reputation } from "../../ui/React/Reputation"; import { Favor } from "../../ui/React/Favor"; @@ -30,7 +29,7 @@ import { yesNoBoxGetYesButton, yesNoBoxGetNoButton, yesNoBoxClose, - yesNoBoxCreate + yesNoBoxCreate, } from "../../../utils/YesNoBox"; type IProps = { @@ -63,7 +62,7 @@ export class CompanyLocation extends React.Component { /** * Stores button styling that sets them all to block display */ - btnStyle: object; + btnStyle: any; /** * Reference to the Location that this component is being rendered for @@ -112,73 +111,73 @@ export class CompanyLocation extends React.Component { this.checkIfEmployedHere(false); } - applyForAgentJob(e: React.MouseEvent) { - if (!e.isTrusted) { return false; } + applyForAgentJob(e: React.MouseEvent): void { + if (!e.isTrusted) { return; } this.props.p.applyForAgentJob(); this.checkIfEmployedHere(true); } - applyForBusinessConsultantJob(e: React.MouseEvent) { - if (!e.isTrusted) { return false; } + applyForBusinessConsultantJob(e: React.MouseEvent): void { + if (!e.isTrusted) { return; } this.props.p.applyForBusinessConsultantJob(); this.checkIfEmployedHere(true); } - applyForBusinessJob(e: React.MouseEvent) { - if (!e.isTrusted) { return false; } + applyForBusinessJob(e: React.MouseEvent): void { + if (!e.isTrusted) { return; } this.props.p.applyForBusinessJob(); this.checkIfEmployedHere(true); } - applyForEmployeeJob(e: React.MouseEvent) { - if (!e.isTrusted) { return false; } + applyForEmployeeJob(e: React.MouseEvent): void { + if (!e.isTrusted) { return; } this.props.p.applyForEmployeeJob(); this.checkIfEmployedHere(true); } - applyForItJob(e: React.MouseEvent) { - if (!e.isTrusted) { return false; } + applyForItJob(e: React.MouseEvent): void { + if (!e.isTrusted) { return; } this.props.p.applyForItJob(); this.checkIfEmployedHere(true); } - applyForPartTimeEmployeeJob(e: React.MouseEvent) { - if (!e.isTrusted) { return false; } + applyForPartTimeEmployeeJob(e: React.MouseEvent): void { + if (!e.isTrusted) { return; } this.props.p.applyForPartTimeEmployeeJob(); this.checkIfEmployedHere(true); } - applyForPartTimeWaiterJob(e: React.MouseEvent) { - if (!e.isTrusted) { return false; } + applyForPartTimeWaiterJob(e: React.MouseEvent): void { + if (!e.isTrusted) { return; } this.props.p.applyForPartTimeWaiterJob(); this.checkIfEmployedHere(true); } - applyForSecurityJob(e: React.MouseEvent) { - if (!e.isTrusted) { return false; } + applyForSecurityJob(e: React.MouseEvent): void { + if (!e.isTrusted) { return; } this.props.p.applyForSecurityJob(); this.checkIfEmployedHere(true); } - applyForSoftwareConsultantJob(e: React.MouseEvent) { - if (!e.isTrusted) { return false; } + applyForSoftwareConsultantJob(e: React.MouseEvent): void { + if (!e.isTrusted) { return; } this.props.p.applyForSoftwareConsultantJob(); this.checkIfEmployedHere(true); } - applyForSoftwareJob(e: React.MouseEvent) { - if (!e.isTrusted) { return false; } + applyForSoftwareJob(e: React.MouseEvent): void { + if (!e.isTrusted) { return; } this.props.p.applyForSoftwareJob(); this.checkIfEmployedHere(true); } - applyForWaiterJob(e: React.MouseEvent) { - if (!e.isTrusted) { return false; } + applyForWaiterJob(e: React.MouseEvent): void { + if (!e.isTrusted) { return; } this.props.p.applyForWaiterJob(); this.checkIfEmployedHere(true); } - checkIfEmployedHere(updateState=false) { + checkIfEmployedHere(updateState=false): void { this.jobTitle = this.props.p.jobs[this.props.locName]; if (this.jobTitle != null) { this.companyPosition = CompanyPositions[this.jobTitle]; @@ -186,24 +185,24 @@ export class CompanyLocation extends React.Component { if (updateState) { this.setState({ - employedHere: this.jobTitle != null + employedHere: this.jobTitle != null, }); } } - startInfiltration(e: React.MouseEvent) { - if (!e.isTrusted) { return false; } + startInfiltration(e: React.MouseEvent): void { + if (!e.isTrusted) { return; } const loc = this.location; this.props.engine.loadInfiltrationContent(); const data = loc.infiltrationData; - if (data == null) { return false; } + if (data == null) { return; } beginInfiltration(this.props.locName, data.startingSecurityLevel, data.baseRewardValue, data.maxClearanceLevel, data.difficulty); } - work(e: React.MouseEvent) { - if (!e.isTrusted) { return false; } + work(e: React.MouseEvent): void { + if (!e.isTrusted) { return; } const pos = this.companyPosition; if (pos instanceof CompanyPosition) { @@ -215,11 +214,11 @@ export class CompanyLocation extends React.Component { } } - quit(e: React.MouseEvent) { - if (!e.isTrusted) { return false; } + quit(e: React.MouseEvent): void { + if (!e.isTrusted) { return; } - var yesBtn = yesNoBoxGetYesButton(); - var noBtn = yesNoBoxGetNoButton(); + const yesBtn = yesNoBoxGetYesButton(); + const noBtn = yesNoBoxGetNoButton(); if (yesBtn == null || noBtn == null) { return; } yesBtn.innerHTML = "Quit job"; noBtn.innerHTML = "Cancel"; @@ -235,7 +234,7 @@ export class CompanyLocation extends React.Component { yesNoBoxCreate(<>Would you like to quit your job at {this.company.name}?); } - render() { + render(): React.ReactNode { const isEmployedHere = this.jobTitle != null; const favorGain = this.company.getFavorGain(); diff --git a/src/Locations/ui/GenericLocation.tsx b/src/Locations/ui/GenericLocation.tsx index 5de2e7921..ad162ef04 100644 --- a/src/Locations/ui/GenericLocation.tsx +++ b/src/Locations/ui/GenericLocation.tsx @@ -42,7 +42,7 @@ export class GenericLocation extends React.Component { /** * Stores button styling that sets them all to block display */ - btnStyle: object; + btnStyle: any; constructor(props: IProps) { super(props); @@ -64,7 +64,7 @@ export class GenericLocation extends React.Component { key={"companylocation"} locName={this.props.loc.name} p={this.props.p} - /> + />, ) } @@ -74,7 +74,7 @@ export class GenericLocation extends React.Component { key={"gymlocation"} loc={this.props.loc} p={this.props.p} - /> + />, ) } @@ -83,7 +83,7 @@ export class GenericLocation extends React.Component { + />, ) } @@ -92,7 +92,7 @@ export class GenericLocation extends React.Component { + />, ) } @@ -103,7 +103,7 @@ export class GenericLocation extends React.Component { key={"speciallocation"} loc={this.props.loc} p={this.props.p} - /> + />, ) } @@ -113,7 +113,7 @@ export class GenericLocation extends React.Component { key={"techvendorlocation"} loc={this.props.loc} p={this.props.p} - /> + />, ) } @@ -123,7 +123,7 @@ export class GenericLocation extends React.Component { key={"travelagencylocation"} p={this.props.p} travel={this.props.travel} - /> + />, ) } @@ -133,7 +133,7 @@ export class GenericLocation extends React.Component { key={"universitylocation"} loc={this.props.loc} p={this.props.p} - /> + />, ) } @@ -142,14 +142,14 @@ export class GenericLocation extends React.Component { + />, ) } return content; } - render() { + render(): React.ReactNode { const locContent: React.ReactNode[] = this.getLocationSpecificContent(); const ip = SpecialServerIps.getIp(this.props.loc.name); const server = getServer(ip); diff --git a/src/Locations/ui/GymLocation.tsx b/src/Locations/ui/GymLocation.tsx index 89ad4911c..3b284cfba 100644 --- a/src/Locations/ui/GymLocation.tsx +++ b/src/Locations/ui/GymLocation.tsx @@ -13,7 +13,6 @@ import { getServer } from "../../Server/ServerHelpers"; import { Server } from "../../Server/Server"; import { SpecialServerIps } from "../../Server/SpecialServerIps"; -import { numeralWrapper } from "../../ui/numeralFormat"; import { StdButton } from "../../ui/React/StdButton"; import { Money } from "../../ui/React/Money"; @@ -26,7 +25,7 @@ export class GymLocation extends React.Component { /** * Stores button styling that sets them all to block display */ - btnStyle: object; + btnStyle: any; constructor(props: IProps) { super(props); @@ -50,28 +49,28 @@ export class GymLocation extends React.Component { return this.props.loc.costMult * discount; } - train(stat: string) { + train(stat: string): void { const loc = this.props.loc; this.props.p.startClass(this.calculateCost(), loc.expMult, stat); } - trainStrength() { - return this.train(CONSTANTS.ClassGymStrength); + trainStrength(): void { + this.train(CONSTANTS.ClassGymStrength); } - trainDefense() { - return this.train(CONSTANTS.ClassGymDefense); + trainDefense(): void { + this.train(CONSTANTS.ClassGymDefense); } - trainDexterity() { - return this.train(CONSTANTS.ClassGymDexterity); + trainDexterity(): void { + this.train(CONSTANTS.ClassGymDexterity); } - trainAgility() { - return this.train(CONSTANTS.ClassGymAgility); + trainAgility(): void { + this.train(CONSTANTS.ClassGymAgility); } - render() { + render(): React.ReactNode { const cost = CONSTANTS.ClassGymBaseCost * this.calculateCost(); return ( diff --git a/src/Locations/ui/HospitalLocation.tsx b/src/Locations/ui/HospitalLocation.tsx index 975f83525..f8892d0f8 100644 --- a/src/Locations/ui/HospitalLocation.tsx +++ b/src/Locations/ui/HospitalLocation.tsx @@ -5,11 +5,9 @@ */ import * as React from "react"; -import { CONSTANTS } from "../../Constants"; import { IPlayer } from "../../PersonObjects/IPlayer"; import { getHospitalizationCost } from "../../Hospital/Hospital"; -import { numeralWrapper } from "../../ui/numeralFormat"; import { AutoupdatingStdButton } from "../../ui/React/AutoupdatingStdButton"; import { Money } from "../../ui/React/Money"; @@ -27,7 +25,7 @@ export class HospitalLocation extends React.Component { /** * Stores button styling that sets them all to block display */ - btnStyle: object; + btnStyle: any; constructor(props: IProps) { super(props); @@ -65,7 +63,7 @@ export class HospitalLocation extends React.Component { dialogBoxCreate(<>You were healed to full health! The hospital billed you for {Money(cost)}); } - render() { + render(): React.ReactNode { const cost = this.getCost(); return ( diff --git a/src/Locations/ui/Root.tsx b/src/Locations/ui/Root.tsx index 351741c19..1314425db 100644 --- a/src/Locations/ui/Root.tsx +++ b/src/Locations/ui/Root.tsx @@ -136,12 +136,12 @@ export class LocationRoot extends React.Component { if (this.props.p.travel(to)) { this.setState({ inCity: true, - city: to + city: to, }); } } - render() { + render(): React.ReactNode { if (this.state.inCity) { return this.renderCity(); } else { diff --git a/src/Locations/ui/SlumsLocation.tsx b/src/Locations/ui/SlumsLocation.tsx index 7afa53bba..08d2afff1 100644 --- a/src/Locations/ui/SlumsLocation.tsx +++ b/src/Locations/ui/SlumsLocation.tsx @@ -19,7 +19,7 @@ export class SlumsLocation extends React.Component { /** * Stores button styling that sets them all to block display */ - btnStyle: object; + btnStyle: any; constructor(props: IProps) { super(props); @@ -100,7 +100,7 @@ export class SlumsLocation extends React.Component { Crimes.Heist.commit(this.props.p); } - render() { + render(): React.ReactNode { const shopliftChance = Crimes.Shoplift.successRate(this.props.p); const robStoreChance = Crimes.RobStore.successRate(this.props.p); const mugChance = Crimes.Mug.successRate(this.props.p); diff --git a/src/Locations/ui/SpecialLocation.tsx b/src/Locations/ui/SpecialLocation.tsx index ba51d8cfa..a24653857 100644 --- a/src/Locations/ui/SpecialLocation.tsx +++ b/src/Locations/ui/SpecialLocation.tsx @@ -38,7 +38,7 @@ export class SpecialLocation extends React.Component { /** * Stores button styling that sets them all to block display */ - btnStyle: object; + btnStyle: any; constructor(props: IProps) { super(props); @@ -57,14 +57,14 @@ export class SpecialLocation extends React.Component { /** * Click handler for "Create Corporation" button at Sector-12 City Hall */ - createCorporationPopup() { + createCorporationPopup(): void { createStartCorporationPopup(this.props.p); } /** * Click handler for Bladeburner button at Sector-12 NSA */ - handleBladeburner() { + handleBladeburner(): void { const p = this.props.p; if (p.inBladeburner()) { // Enter Bladeburner division @@ -91,7 +91,7 @@ export class SpecialLocation extends React.Component { /** * Click handler for Resleeving button at New Tokyo VitaLife */ - handleResleeving() { + handleResleeving(): void { this.props.engine.loadResleevingContent(); } @@ -130,7 +130,7 @@ export class SpecialLocation extends React.Component { ) } - render() { + render(): React.ReactNode { switch (this.props.loc.name) { case LocationName.NewTokyoVitaLife: { return this.renderResleeving(); diff --git a/src/Locations/ui/TechVendorLocation.tsx b/src/Locations/ui/TechVendorLocation.tsx index d0a13b389..11fb1eecf 100644 --- a/src/Locations/ui/TechVendorLocation.tsx +++ b/src/Locations/ui/TechVendorLocation.tsx @@ -15,7 +15,6 @@ import { CONSTANTS } from "../../Constants"; import { IPlayer } from "../../PersonObjects/IPlayer"; import { getPurchaseServerCost } from "../../Server/ServerPurchases"; -import { numeralWrapper } from "../../ui/numeralFormat"; import { StdButtonPurchased } from "../../ui/React/StdButtonPurchased"; import { StdButton } from "../../ui/React/StdButton"; import { Money } from "../../ui/React/Money"; @@ -29,7 +28,7 @@ export class TechVendorLocation extends React.Component { /** * Stores button styling that sets them all to block display */ - btnStyle: object; + btnStyle: any; constructor(props: IProps) { super(props); @@ -45,22 +44,22 @@ export class TechVendorLocation extends React.Component { this.purchaseTorRouter = this.purchaseTorRouter.bind(this); } - createUpgradeHomeCoresPopup() { + createUpgradeHomeCoresPopup(): void { createUpgradeHomeCoresPopup(this.props.p); } - createUpgradeHomeRamPopup() { + createUpgradeHomeRamPopup(): void { createUpgradeHomeRamPopup(this.props.p); } - purchaseTorRouter() { + purchaseTorRouter(): void { purchaseTorRouter(this.props.p); this.setState({ torPurchased: this.props.p.hasTorRouter(), }); } - render() { + render(): React.ReactNode { const loc: Location = this.props.loc; const purchaseServerButtons: React.ReactNode[] = []; @@ -72,7 +71,7 @@ export class TechVendorLocation extends React.Component { onClick={() => createPurchaseServerPopup(i, this.props.p)} style={this.btnStyle} text={<>Purchase {i}GB Server - {Money(cost)}} - /> + />, ) } diff --git a/src/Locations/ui/TravelAgencyLocation.tsx b/src/Locations/ui/TravelAgencyLocation.tsx index 7d33b4bac..b0931bd17 100644 --- a/src/Locations/ui/TravelAgencyLocation.tsx +++ b/src/Locations/ui/TravelAgencyLocation.tsx @@ -12,7 +12,6 @@ import { CONSTANTS } from "../../Constants"; import { IPlayer } from "../../PersonObjects/IPlayer"; import { Settings } from "../../Settings/Settings"; -import { numeralWrapper } from "../../ui/numeralFormat"; import { StdButton } from "../../ui/React/StdButton"; import { Money } from "../../ui/React/Money"; @@ -25,7 +24,7 @@ export class TravelAgencyLocation extends React.Component { /** * Stores button styling that sets them all to block display */ - btnStyle: object; + btnStyle: any; constructor(props: IProps) { super(props); @@ -33,13 +32,11 @@ export class TravelAgencyLocation extends React.Component { this.btnStyle = { display: "block" }; } - asciiWorldMap() { - const thisTravelAgencyLocation = this; - - function LocationLetter(props: any) { - if(props.city !== thisTravelAgencyLocation.props.p.city) { - return - {props.city} + asciiWorldMap(): React.ReactNode { + const LocationLetter = (props: any): JSX.Element => { + if(props.city !== this.props.p.city) { + return + {props.city} {props.city[0]} } @@ -55,20 +52,20 @@ export class TravelAgencyLocation extends React.Component {
                   ,_   .  ._. _.  .
               , _-\','|~\~      ~/      ;-'_   _-'     ,;_;_,    ~~-
      /~~-\_/-'~'--' \~~| ',    ,'      /  / ~|-_\_/~/~      ~~--~~~~'--_
    -
      /              ,/'-/~ '\ ,' _  , ','|~                   ._/-, /~
    +
      /              ,/'-/~ '\ ,' _  , ','|~                   ._/-, /~
      ~/-'~\_,       '-,| '|. '   ~  ,\ /'~                /    /_  /~
    -
    .-~      '|        '',\~|\       _\~     ,_  ,              /,
    -
              '\       /'~          |_/~\\,-,~  \ "         ,_,/ |
    -
               |       /            ._-~'\_ _~|              \ ) 
    +
    .-~      '|        '',\~|\       _\~     ,_  ,              /,
    +
              '\       /'~          |_/~\\,-,~  \ "         ,_,/ |
    +
               |       /            ._-~'\_ _~|              \ ) 
                \   __-\           '/      ~ |\  \_          /  ~
      .,         '\ |,  ~-_      - |          \\_' ~|  /\  \~ ,
                   ~-_'  _;       '\           '-,   \,' /\/  |
                     '\_,~'\_       \_ _,       /'    '  |, /|'
                       /     \_       ~ |      /         \  ~'; -,_.
                       |       ~\        |    |  ,        '-_, ,; ~ ~\
    -
                        \,     /        \    / /|            ,-, ,   -,
    +
                        \,     /        \    / /|            ,-, ,   -,
                         |    ,/          |  |' |/          ,-   ~ \   '.
    -
                        ,|   ,/           \ ,/              \      |
    +
                        ,|   ,/           \ ,/              \      |
                        /    |             ~                 -~~-, /   _
                        | ,-'                                    ~    /
                        / ,'                                      ~
    @@ -79,7 +76,7 @@ export class TravelAgencyLocation extends React.Component { } - listWorldMap() { + listWorldMap(): React.ReactNode { const travelBtns: React.ReactNode[] = []; for (const key in CityName) { const city: CityName = (CityName as any)[key]; @@ -93,7 +90,7 @@ export class TravelAgencyLocation extends React.Component { onClick={createTravelPopup.bind(null, city, this.props.travel)} style={this.btnStyle} text={`Travel to ${city}`} - /> + />, ) } @@ -108,7 +105,7 @@ export class TravelAgencyLocation extends React.Component { ) } - render() { + render(): React.ReactNode { if (Settings.DisableASCIIArt) { return this.listWorldMap(); } else { diff --git a/src/Locations/ui/UniversityLocation.tsx b/src/Locations/ui/UniversityLocation.tsx index 88f5f18cd..3a360e1f5 100644 --- a/src/Locations/ui/UniversityLocation.tsx +++ b/src/Locations/ui/UniversityLocation.tsx @@ -13,7 +13,6 @@ import { getServer } from "../../Server/ServerHelpers"; import { Server } from "../../Server/Server"; import { SpecialServerIps } from "../../Server/SpecialServerIps"; -import { numeralWrapper } from "../../ui/numeralFormat"; import { StdButton } from "../../ui/React/StdButton"; import { Money } from "../../ui/React/Money"; @@ -26,7 +25,7 @@ export class UniversityLocation extends React.Component { /** * Stores button styling that sets them all to block display */ - btnStyle: object; + btnStyle: any; constructor(props: IProps) { super(props); @@ -53,36 +52,36 @@ export class UniversityLocation extends React.Component { return this.props.loc.costMult * discount; } - take(stat: string) { + take(stat: string): void { const loc = this.props.loc; this.props.p.startClass(this.calculateCost(), loc.expMult, stat); } - study() { - return this.take(CONSTANTS.ClassStudyComputerScience); + study(): void { + this.take(CONSTANTS.ClassStudyComputerScience); } - dataStructures() { - return this.take(CONSTANTS.ClassDataStructures); + dataStructures(): void { + this.take(CONSTANTS.ClassDataStructures); } - networks() { - return this.take(CONSTANTS.ClassNetworks); + networks(): void { + this.take(CONSTANTS.ClassNetworks); } - algorithms() { - return this.take(CONSTANTS.ClassAlgorithms); + algorithms(): void { + this.take(CONSTANTS.ClassAlgorithms); } - management() { - return this.take(CONSTANTS.ClassManagement); + management(): void { + this.take(CONSTANTS.ClassManagement); } - leadership() { - return this.take(CONSTANTS.ClassLeadership); + leadership(): void { + this.take(CONSTANTS.ClassLeadership); } - render() { + render(): React.ReactNode { const costMult: number = this.calculateCost(); const dataStructuresCost = CONSTANTS.ClassDataStructuresBaseCost * costMult; diff --git a/src/Message/Message.ts b/src/Message/Message.ts index 90e24aa2c..737409219 100644 --- a/src/Message/Message.ts +++ b/src/Message/Message.ts @@ -3,19 +3,15 @@ import { Reviver, Generic_fromJSON } from "../../utils/JSONReviver"; export class Message { - // Initializes a Message Object from a JSON save state - static fromJSON(value: any): Message { - return Generic_fromJSON(Message, value.data); - } // Name of Message file - filename: string = ""; + filename = ""; // The text contains in the Message - msg: string = ""; + msg = ""; // Flag indicating whether this Message has been received by the player - recvd: boolean = false; + recvd = false; constructor(filename="", msg="") { this.filename = filename; @@ -27,6 +23,12 @@ export class Message { toJSON(): any { return Generic_toJSON("Message", this); } + + // Initializes a Message Object from a JSON save state + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types + static fromJSON(value: any): Message { + return Generic_fromJSON(Message, value.data); + } } Reviver.constructors.Message = Message; diff --git a/src/Message/MessageHelpers.js b/src/Message/MessageHelpers.js index b3af621ac..4932c7be2 100644 --- a/src/Message/MessageHelpers.js +++ b/src/Message/MessageHelpers.js @@ -1,5 +1,4 @@ import { Message } from "./Message"; -import { Augmentatation } from "../Augmentation/Augmentation"; import { Augmentations } from "../Augmentation/Augmentations"; import { AugmentationNames } from "../Augmentation/data/AugmentationNames"; import { Programs } from "../Programs/Programs"; diff --git a/src/Milestones/MilestoneHelpers.tsx b/src/Milestones/MilestoneHelpers.tsx index 330aee209..e9ddac327 100644 --- a/src/Milestones/MilestoneHelpers.tsx +++ b/src/Milestones/MilestoneHelpers.tsx @@ -7,7 +7,7 @@ import * as ReactDOM from "react-dom"; let milestonesContainer: HTMLElement | null = null; (function(){ - function setContainer() { + function setContainer(): void { milestonesContainer = document.getElementById("milestones-container"); document.removeEventListener("DOMContentLoaded", setContainer); } @@ -15,7 +15,7 @@ let milestonesContainer: HTMLElement | null = null; document.addEventListener("DOMContentLoaded", setContainer); })(); -export function displayMilestonesContent() { +export function displayMilestonesContent(): void { if (!routing.isOn(Page.Milestones)) { return; } @@ -23,7 +23,7 @@ export function displayMilestonesContent() { if (milestonesContainer instanceof HTMLElement) { ReactDOM.render( , - milestonesContainer + milestonesContainer, ); } } \ No newline at end of file diff --git a/src/Milestones/Milestones.ts b/src/Milestones/Milestones.ts index e08b0e297..856c070a9 100644 --- a/src/Milestones/Milestones.ts +++ b/src/Milestones/Milestones.ts @@ -1,12 +1,11 @@ import { Milestone } from "./Milestone"; -import { IMap } from "../types"; import { IPlayer } from "../PersonObjects/IPlayer"; import { Factions } from "../Faction/Factions"; import { Faction } from "../Faction/Faction"; import { GetServerByHostname } from "../Server/ServerHelpers"; function allFactionAugs(p: IPlayer, f: Faction): boolean { - const factionAugs = f.augmentations.slice().filter((aug)=> "NeuroFlux Governor" !== aug); + const factionAugs = f.augmentations.slice().filter((aug)=> aug !== "NeuroFlux Governor"); for(const factionAug of factionAugs) { if(!p.augmentations.some(aug => {return aug.name == factionAug})) return false; } @@ -16,7 +15,7 @@ function allFactionAugs(p: IPlayer, f: Faction): boolean { export const Milestones: Milestone[] = [ { title: "Gain root access on CSEC", - fulfilled: (p: IPlayer) => { + fulfilled: (): boolean => { const server = GetServerByHostname("CSEC"); if(!server || !server.hasOwnProperty('hasAdminRights')) return false; return (server as any).hasAdminRights; @@ -24,7 +23,7 @@ export const Milestones: Milestone[] = [ }, { title: "Install the backdoor on CSEC", - fulfilled: (p: IPlayer) => { + fulfilled: (): boolean => { const server = GetServerByHostname("CSEC"); if(!server || !server.hasOwnProperty('backdoorInstalled')) return false; return (server as any).backdoorInstalled; @@ -32,67 +31,67 @@ export const Milestones: Milestone[] = [ }, { title: "Join the faction hinted at in j1.msg", - fulfilled: (p: IPlayer) => { + fulfilled: (p: IPlayer): boolean => { return p.factions.includes("CyberSec"); }, }, { title: "Install all the Augmentations from CSEC", - fulfilled: (p: IPlayer) => { + fulfilled: (p: IPlayer): boolean => { return allFactionAugs(p, Factions["CyberSec"]); }, }, { title: "Join the faction hinted at in j2.msg", - fulfilled: (p: IPlayer) => { + fulfilled: (p: IPlayer): boolean => { return p.factions.includes("NiteSec"); }, }, { title: "Install all the Augmentations from NiteSec", - fulfilled: (p: IPlayer) => { + fulfilled: (p: IPlayer): boolean => { return allFactionAugs(p, Factions["NiteSec"]); }, }, { title: "Join the faction hinted at in j3.msg", - fulfilled: (p: IPlayer) => { + fulfilled: (p: IPlayer): boolean => { return p.factions.includes("The Black Hand"); }, }, { title: "Install all the Augmentations from The Black Hand", - fulfilled: (p: IPlayer) => { + fulfilled: (p: IPlayer): boolean => { return allFactionAugs(p, Factions["The Black Hand"]); }, }, { title: "Join the faction hinted at in j4.msg", - fulfilled: (p: IPlayer) => { + fulfilled: (p: IPlayer): boolean => { return p.factions.includes("BitRunners"); }, }, { title: "Install all the Augmentations from BitRunners", - fulfilled: (p: IPlayer) => { + fulfilled: (p: IPlayer): boolean => { return allFactionAugs(p, Factions["BitRunners"]); }, }, { title: "Join the final faction", - fulfilled: (p: IPlayer) => { + fulfilled: (p: IPlayer): boolean => { return p.factions.includes("Daedalus"); }, }, { title: "Install the special Augmentation from Daedalus", - fulfilled: (p: IPlayer) => { + fulfilled: (p: IPlayer): boolean => { return p.augmentations.some(aug => aug.name == "The Red Pill") }, }, { title: "Install the final backdoor and free yourself.", - fulfilled: () => { + fulfilled: (): boolean => { return false; }, }, diff --git a/src/Milestones/ui/Root.tsx b/src/Milestones/ui/Root.tsx index bfaf79b1f..bbf191588 100644 --- a/src/Milestones/ui/Root.tsx +++ b/src/Milestones/ui/Root.tsx @@ -16,7 +16,7 @@ function highestMilestone(p: IPlayer, milestones: Milestone[]): number { return n; } -export function Root(props: IProps) { +export function Root(props: IProps): JSX.Element { const n = highestMilestone(props.player, Milestones); const milestones = Milestones.map((milestone: Milestone, i: number) => { if (i<=n+1) { diff --git a/src/Missions.jsx b/src/Missions.jsx index fad515ca2..bbc063dd1 100644 --- a/src/Missions.jsx +++ b/src/Missions.jsx @@ -5,7 +5,6 @@ import { Player } from "./Player"; import { dialogBoxCreate } from "../utils/DialogBox"; import { formatNumber } from "../utils/StringHelperFunctions"; -import { numeralWrapper } from "./ui/numeralFormat"; import { Reputation } from "./ui/React/Reputation"; import { addOffset } from "../utils/helpers/addOffset"; @@ -14,8 +13,6 @@ import { isString } from "../utils/helpers/isString"; import { clearEventListeners } from "../utils/uiHelpers/clearEventListeners"; -import jsplumb from "jsplumb"; - import React from "react"; import ReactDOM from "react-dom"; @@ -65,7 +62,7 @@ let NodeTypes = { Database: "Database Node", // No actions available Spam: "Spam Node", // No actions Available Transfer: "Transfer Node", // Can Weaken, Scan, Fortify and Overflow - Shield: "Shield Node" // Can Fortify + Shield: "Shield Node", // Can Fortify } let NodeActions = { @@ -252,7 +249,7 @@ HackingMission.prototype.init = function() { var stats = { atk: randMult * getRandomInt(80, 86), def: randMult * getRandomInt(5, 10), - hp: randMult * getRandomInt(210, 230) + hp: randMult * getRandomInt(210, 230), } this.enemyCores.push(new Node(NodeTypes.Core, stats)); this.enemyCores[i].setControlledByEnemy(); @@ -262,7 +259,7 @@ HackingMission.prototype.init = function() { var stats = { atk: 0, def: randMult * getRandomInt(10, 20), - hp: randMult * getRandomInt(275, 300) + hp: randMult * getRandomInt(275, 300), } this.enemyNodes.push(new Node(NodeTypes.Firewall, stats)); this.enemyNodes[i].setControlledByEnemy(); @@ -272,7 +269,7 @@ HackingMission.prototype.init = function() { var stats = { atk: 0, def: randMult * getRandomInt(30, 55), - hp: randMult * getRandomInt(210, 275) + hp: randMult * getRandomInt(210, 275), } var node = new Node(NodeTypes.Database, stats); node.setControlledByEnemy(); @@ -674,7 +671,7 @@ HackingMission.prototype.createMap = function() { var stats = { atk: 0, def: averageAttack * 1.1 + getRandomInt(15, 45), - hp: randMult * getRandomInt(200, 225) + hp: randMult * getRandomInt(200, 225), } node = new Node(NodeTypes.Spam, stats); break; @@ -682,7 +679,7 @@ HackingMission.prototype.createMap = function() { var stats = { atk: 0, def: averageAttack * 1.1 + getRandomInt(15, 45), - hp: randMult * getRandomInt(250, 275) + hp: randMult * getRandomInt(250, 275), } node = new Node(NodeTypes.Transfer, stats); break; @@ -691,7 +688,7 @@ HackingMission.prototype.createMap = function() { var stats = { atk: 0, def: averageAttack * 1.1 + getRandomInt(30, 70), - hp: randMult * getRandomInt(300, 320) + hp: randMult * getRandomInt(300, 320), } node = new Node(NodeTypes.Shield, stats); break; @@ -783,11 +780,11 @@ HackingMission.prototype.updateNodeDomElement = function(nodeObj) { return; } - var id = "hacking-mission-node-" + nodeObj.pos[0] + "-" + nodeObj.pos[1]; - var nodeDiv = document.getElementById(id), txtEl = document.getElementById(id + "-txt"); + let id = "hacking-mission-node-" + nodeObj.pos[0] + "-" + nodeObj.pos[1]; + let txtEl = document.getElementById(id + "-txt"); // Set node classes based on type - var txt; + let txt; switch (nodeObj.type) { case NodeTypes.Core: txt = "CPU Core
    " + "HP: " + @@ -901,14 +898,13 @@ HackingMission.prototype.configurePlayerNodeElement = function(el) { if (nodeObj == null) {console.error("Failed getting Node object");} // Add event listener - var self = this; - function selectNodeWrapper() { - selectNode(self, el); + const selectNodeWrapper = () => { + selectNode(this, el); } el.addEventListener("click", selectNodeWrapper); - function multiselectNodeWrapper() { - multiselectNode(self, el); + const multiselectNodeWrapper = () => { + multiselectNode(this, el); } el.addEventListener("dblclick", multiselectNodeWrapper); @@ -971,10 +967,10 @@ HackingMission.prototype.initJsPlumb = function() { PaintStyle: { gradient: { stops: [ [ 0, "#FFFFFF" ], - [ 1, "#FFFFFF" ] + [ 1, "#FFFFFF" ], ] }, stroke: "#FFFFFF", - strokeWidth: 8 + strokeWidth: 8, }, }); @@ -986,7 +982,7 @@ HackingMission.prototype.initJsPlumb = function() { deleteEndpointsOnEmpty:true, maxConnections:1, anchor:"Continuous", - connector:"Flowchart" + connector:"Flowchart", }); } @@ -995,33 +991,33 @@ HackingMission.prototype.initJsPlumb = function() { instance.makeTarget(this.enemyCores[i].el, { maxConnections:-1, anchor:"Continuous", - connector:"Flowchart" + connector:"Flowchart", }); } for (var i = 0; i < this.enemyDatabases.length; ++i) { instance.makeTarget(this.enemyDatabases[i].el, { maxConnections:-1, anchor:"Continuous", - connector:["Flowchart"] + connector:["Flowchart"], }); } for (var i = 0; i < this.enemyNodes.length; ++i) { instance.makeTarget(this.enemyNodes[i].el, { maxConnections:-1, anchor:"Continuous", - connector:"Flowchart" + connector:"Flowchart", }); } for (var i = 0; i < this.miscNodes.length; ++i) { instance.makeTarget(this.miscNodes[i].el, { maxConnections:-1, anchor:"Continuous", - connector:"Flowchart" + connector:"Flowchart", }); } // Clicking a connection drops it - instance.bind("click", (conn, originalEvent) => { + instance.bind("click", (conn) => { // Cannot drop enemy's connections const sourceNode = this.getNodeFromElement(conn.source); if (sourceNode.enmyCtrl) { return; } @@ -1051,7 +1047,7 @@ HackingMission.prototype.initJsPlumb = function() { }); // Detach Connection events - instance.bind("connectionDetached", (info, originalEvent) => { + instance.bind("connectionDetached", (info) => { var sourceNode = this.getNodeFromElement(info.source); sourceNode.conn = null; var targetNode = this.getNodeFromElement(info.target); @@ -1264,7 +1260,7 @@ HackingMission.prototype.processNode = function(nodeObj, numCycles=1) { deleteEndpointsOnEmpty:true, maxConnections:1, anchor:"Continuous", - connector:"Flowchart" + connector:"Flowchart", }); } else { targetNode.setControlledByEnemy(); @@ -1273,7 +1269,7 @@ HackingMission.prototype.processNode = function(nodeObj, numCycles=1) { this.jsplumbinstance.makeTarget(targetNode.el, { maxConnections:-1, anchor:"Continuous", - connector:["Flowchart"] + connector:["Flowchart"], }); } @@ -1393,7 +1389,7 @@ HackingMission.prototype.enemyAISelectAction = function(nodeObj) { // Create connection nodeObj.conn = this.jsplumbinstance.connect({ source:nodeObj.el, - target:node.el + target:node.el, }); ++node.targetedCount; } else { @@ -1409,7 +1405,7 @@ HackingMission.prototype.enemyAISelectAction = function(nodeObj) { // Create connection nodeObj.conn = this.jsplumbinstance.connect({ source:nodeObj.el, - target:node.el + target:node.el, }); ++node.targetedCount; } diff --git a/src/Netscript/Environment.ts b/src/Netscript/Environment.ts index 97de95001..0f3a95219 100644 --- a/src/Netscript/Environment.ts +++ b/src/Netscript/Environment.ts @@ -13,7 +13,7 @@ export class Environment { /** * Whether or not the script that uses this Environment should stop running */ - stopFlag: boolean = false; + stopFlag = false; /** * Environment variables (currently only Netscript functions) @@ -32,6 +32,7 @@ export class Environment { * Finds the scope where the variable with the given name is defined */ lookup(name: string): Environment | null { + // eslint-disable-next-line @typescript-eslint/no-this-alias let scope: Environment | null = this; while (scope) { if (Object.prototype.hasOwnProperty.call(scope.vars, name)) { @@ -53,8 +54,9 @@ export class Environment { } //Sets the value of a variable in any scope - set(name: string, value: any) { - var scope = this.lookup(name); + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types + set(name: string, value: any): any { + const scope = this.lookup(name); //If scope has a value, then this variable is already set in a higher scope, so //set is there. Otherwise, create a new variable in the local scope @@ -66,7 +68,8 @@ export class Environment { } //Creates (or overwrites) a variable in the current scope - def(name: string, value: any) { + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types + def(name: string, value: any): any { return this.vars[name] = value; } } diff --git a/src/Netscript/RamCostGenerator.ts b/src/Netscript/RamCostGenerator.ts index 01cc550c4..9c9d3bb87 100644 --- a/src/Netscript/RamCostGenerator.ts +++ b/src/Netscript/RamCostGenerator.ts @@ -307,7 +307,7 @@ export const RamCosts: IMap = { heart: { // Easter egg function break : () => 0, - } + }, } export function getRamCost(...args: string[]): number { diff --git a/src/Netscript/WorkerScript.ts b/src/Netscript/WorkerScript.ts index 23c5d48e6..6129f0712 100644 --- a/src/Netscript/WorkerScript.ts +++ b/src/Netscript/WorkerScript.ts @@ -24,7 +24,7 @@ export class WorkerScript { /** * Copy of the script's code */ - code: string = ""; + code = ""; /** * Holds the timeoutID (numeric value) for whenever this script is blocked by a @@ -62,7 +62,7 @@ export class WorkerScript { /** * Status message in case of script error. Currently unused I think */ - errorMessage: string = ""; + errorMessage = ""; /** * Used for static RAM calculation. Stores names of all functions that have @@ -78,7 +78,7 @@ export class WorkerScript { /** * Script's output/return value. Currently not used or implemented */ - output: string = ""; + output = ""; /** * Process ID. Must be an integer. Used for efficient script @@ -89,12 +89,12 @@ export class WorkerScript { /** * Script's Static RAM usage. Equivalent to underlying script's RAM usage */ - ramUsage: number = 0; + ramUsage = 0; /** * Whether or not this workerScript is currently running */ - running: boolean = false; + running = false; /** * Reference to underlying RunningScript object @@ -106,7 +106,7 @@ export class WorkerScript { */ serverIp: string; - constructor(runningScriptObj: RunningScript, pid: number, nsFuncsGenerator?: (ws: WorkerScript) => object) { + constructor(runningScriptObj: RunningScript, pid: number, nsFuncsGenerator?: (ws: WorkerScript) => any) { this.name = runningScriptObj.filename; this.serverIp = runningScriptObj.server; @@ -146,8 +146,10 @@ export class WorkerScript { /** * Returns the Server on which this script is running */ - getServer() { - return AllServers[this.serverIp]; + getServer(): BaseServer { + const server = AllServers[this.serverIp]; + if(server == null) throw new Error(`Script ${this.name} pid ${this.pid} is running on non-existent server?`); + return server; } /** @@ -155,7 +157,7 @@ export class WorkerScript { * Returns null if it cannot be found (which would be a bug) */ getScript(): Script | null { - let server = this.getServer(); + const server = this.getServer(); for (let i = 0; i < server.scripts.length; ++i) { if (server.scripts[i].filename === this.name) { return server.scripts[i]; diff --git a/src/Netscript/killWorkerScript.ts b/src/Netscript/killWorkerScript.ts index dc33af1f6..33c91b963 100644 --- a/src/Netscript/killWorkerScript.ts +++ b/src/Netscript/killWorkerScript.ts @@ -50,7 +50,7 @@ export function killWorkerScript(script: RunningScript | WorkerScript | number, } } -function killWorkerScriptByPid(pid: number, rerenderUi: boolean=true): boolean { +function killWorkerScriptByPid(pid: number, rerenderUi=true): boolean { const ws = workerScripts.get(pid); if (ws instanceof WorkerScript) { stopAndCleanUpWorkerScript(ws, rerenderUi); @@ -61,7 +61,7 @@ function killWorkerScriptByPid(pid: number, rerenderUi: boolean=true): boolean { return false; } -function stopAndCleanUpWorkerScript(workerScript: WorkerScript, rerenderUi: boolean=true): void { +function stopAndCleanUpWorkerScript(workerScript: WorkerScript, rerenderUi=true): void { workerScript.env.stopFlag = true; killNetscriptDelay(workerScript); removeWorkerScript(workerScript, rerenderUi); @@ -74,7 +74,7 @@ function stopAndCleanUpWorkerScript(workerScript: WorkerScript, rerenderUi: bool * @param {WorkerScript | number} - Identifier for WorkerScript. Either the object itself, or * its index in the global workerScripts array */ -function removeWorkerScript(workerScript: WorkerScript, rerenderUi: boolean=true): void { +function removeWorkerScript(workerScript: WorkerScript, rerenderUi=true): void { if (workerScript instanceof WorkerScript) { const ip = workerScript.serverIp; const name = workerScript.name; @@ -124,7 +124,7 @@ function removeWorkerScript(workerScript: WorkerScript, rerenderUi: boolean=true * timed, blocked operation (like hack(), sleep(), etc.). This allows scripts to * be killed immediately even if they're in the middle of one of those long operations */ -function killNetscriptDelay(workerScript: WorkerScript) { +function killNetscriptDelay(workerScript: WorkerScript): void { if (workerScript instanceof WorkerScript) { if (workerScript.delay) { clearTimeout(workerScript.delay); diff --git a/src/NetscriptBladeburner.js b/src/NetscriptBladeburner.js index 1ac7d7eb3..c5509fd96 100644 --- a/src/NetscriptBladeburner.js +++ b/src/NetscriptBladeburner.js @@ -1,15 +1,9 @@ -import { Player } from "./Player"; -import { Bladeburner } from "./Bladeburner"; -import { makeRuntimeRejectMsg } from "./NetscriptEvaluator"; - -function unknownBladeburnerActionErrorMessage(functionName, actionType, actionName) { +export function unknownBladeburnerActionErrorMessage(functionName, actionType, actionName) { return `ERROR: bladeburner.${functionName}() failed due to an invalid action specified. ` + `Type: ${actionType}, Name: ${actionName}. Note that for contracts and operations, the ` + `name of the operation is case-sensitive.`; } -function unknownBladeburnerExceptionMessage(functionName, err) { +export function unknownBladeburnerExceptionMessage(functionName, err) { return `bladeburner.${functionName}() failed with exception: ` + err; -} - -export {unknownBladeburnerActionErrorMessage, unknownBladeburnerExceptionMessage, checkBladeburnerAccess}; +} \ No newline at end of file diff --git a/src/NetscriptEvaluator.js b/src/NetscriptEvaluator.js index b61b217c2..8e765591c 100644 --- a/src/NetscriptEvaluator.js +++ b/src/NetscriptEvaluator.js @@ -1,11 +1,10 @@ import { setTimeoutRef } from "./utils/SetTimeoutRef"; -import { isValidIPAddress } from "../utils/helpers/isValidIPAddress"; import { isString } from "../utils/helpers/isString"; import { AllServers } from "./Server/AllServers"; export function netscriptDelay(time, workerScript) { - return new Promise(function(resolve, reject) { + return new Promise(function(resolve) { workerScript.delay = setTimeoutRef(() => { workerScript.delay = null; resolve(); @@ -62,6 +61,5 @@ export function isScriptErrorMessage(msg) { if (splitMsg.length != 4){ return false; } - var ip = splitMsg[1]; return true; } diff --git a/src/NetscriptFunctions.js b/src/NetscriptFunctions.js index 4a3d81986..6c676b8d2 100644 --- a/src/NetscriptFunctions.js +++ b/src/NetscriptFunctions.js @@ -5,11 +5,10 @@ import * as libarg from 'arg'; import { getRamCost } from "./Netscript/RamCostGenerator"; import { WorkerScriptStartStopEventEmitter } from "./Netscript/WorkerScriptStartStopEventEmitter"; -import { Augmentation } from "./Augmentation/Augmentation"; import { Augmentations } from "./Augmentation/Augmentations"; import { augmentationExists, - installAugmentations + installAugmentations, } from "./Augmentation/AugmentationHelpers"; import { prestigeAugmentation } from "./Prestige"; import { AugmentationNames } from "./Augmentation/data/AugmentationNames"; @@ -17,7 +16,7 @@ import { BitNodeMultipliers } from "./BitNode/BitNodeMultipliers"; import { findCrime } from "./Crime/CrimeHelpers"; import { Bladeburner } from "./Bladeburner"; import { Company } from "./Company/Company"; -import { Companies, companyExists } from "./Company/Companies"; +import { Companies } from "./Company/Companies"; import { CompanyPosition } from "./Company/CompanyPosition"; import { CompanyPositions } from "./Company/CompanyPositions"; import { CONSTANTS } from "./Constants"; @@ -28,22 +27,22 @@ import { calculatePercentMoneyHacked, calculateHackingTime, calculateGrowTime, - calculateWeakenTime + calculateWeakenTime, } from "./Hacking"; import { calculateServerGrowth } from "./Server/formulas/grow"; import { AllGangs, GangMemberUpgrades, - GangMemberTasks + GangMemberTasks, + Gang, } from "./Gang"; -import { Faction } from "./Faction/Faction"; import { Factions, factionExists } from "./Faction/Factions"; import { joinFaction, purchaseAugmentation } from "./Faction/FactionHelpers"; import { FactionWorkType } from "./Faction/FactionWorkTypeEnum"; import { netscriptCanGrow, netscriptCanHack, - netscriptCanWeaken + netscriptCanWeaken, } from "./Hacking/netscriptCanHack"; import { @@ -74,7 +73,7 @@ import { calculateServerCost as HScalculateServerCost, } from "./Hacknet/formulas/HacknetServers"; import { HacknetNodeConstants, HacknetServerConstants } from "./Hacknet/data/Constants"; -import { HacknetServer, MaxNumberHacknetServers } from "./Hacknet/HacknetServer"; +import { HacknetServer } from "./Hacknet/HacknetServer"; import { CityName } from "./Locations/data/CityNames"; import { LocationName } from "./Locations/data/LocationNames"; import { Terminal } from "./Terminal"; @@ -84,7 +83,6 @@ import { } from "./PersonObjects/formulas/skill"; import { Message } from "./Message/Message"; -import { Messages } from "./Message/MessageHelpers"; import { inMission } from "./Missions"; import { Player } from "./Player"; import { Programs } from "./Programs/Programs"; @@ -94,15 +92,12 @@ import { findRunningScriptByPid, } from "./Script/ScriptHelpers"; import { isScriptFilename } from "./Script/ScriptHelpersTS"; -import { _getScriptUrls } from "./NetscriptJSEvaluator"; import { AllServers, AddToAllServers, createUniqueRandomIp, } from "./Server/AllServers"; import { RunningScript } from "./Script/RunningScript"; -import { startWorkerScript } from "./NetscriptWorker"; -import { Server } from "./Server/Server"; import { GetServerByHostname, getServer, @@ -114,9 +109,8 @@ import { import { getPurchaseServerCost, getPurchaseServerLimit, - getPurchaseServerMaxRam + getPurchaseServerMaxRam, } from "./Server/ServerPurchases"; -import { Settings } from "./Settings/Settings"; import { SpecialServerIps } from "./Server/SpecialServerIps"; import { SourceFileFlags } from "./SourceFile/SourceFileFlags"; import { @@ -129,7 +123,6 @@ import { influenceStockThroughServerHack, influenceStockThroughServerGrow, } from "./StockMarket/PlayerInfluencing"; -import { Stock } from "./StockMarket/Stock"; import { StockMarket, SymbolToStockMap, @@ -146,18 +139,15 @@ import { PositionTypes } from "./StockMarket/data/PositionTypes"; import { StockSymbols } from "./StockMarket/data/StockSymbols"; import { getStockMarket4SDataCost, - getStockMarket4STixApiCost + getStockMarket4STixApiCost, } from "./StockMarket/StockMarketCosts"; import { isValidFilePath } from "./Terminal/DirectoryHelpers"; import { TextFile, getTextFile, createTextFile } from "./TextFile"; -import { - unknownBladeburnerActionErrorMessage -} from"./NetscriptBladeburner"; -import { Gang } from "./Gang"; import { NetscriptPorts, runScriptFromScript, + startWorkerScript, } from "./NetscriptWorker"; import { killWorkerScript } from "./Netscript/killWorkerScript"; import { workerScripts } from "./Netscript/WorkerScripts"; @@ -172,18 +162,17 @@ import { SleeveTaskType } from "./PersonObjects/Sleeve/SleeveTaskTypesEnum"; import { findSleevePurchasableAugs } from "./PersonObjects/Sleeve/SleeveHelpers"; import { Exploit } from './Exploits/Exploit.ts'; -import { Page, routing } from "./ui/navigationTracking"; import { numeralWrapper } from "./ui/numeralFormat"; import { post } from "./ui/postToTerminal"; import { setTimeoutRef } from "./utils/SetTimeoutRef"; import { is2DArray } from "./utils/helpers/is2DArray"; -import { convertTimeMsToTimeElapsedString } from "../utils/StringHelperFunctions"; +import { + formatNumber, + convertTimeMsToTimeElapsedString, +} from "../utils/StringHelperFunctions"; -import { dialogBoxCreate } from "../utils/DialogBox"; -import { formatNumber, isHTML } from "../utils/StringHelperFunctions"; import { logBoxCreate } from "../utils/LogBox"; import { arrayToString } from "../utils/helpers/arrayToString"; -import { isPowerOfTwo } from "../utils/helpers/isPowerOfTwo"; import { isString } from "../utils/helpers/isString"; import { createElement } from "../utils/uiHelpers/createElement"; @@ -261,7 +250,7 @@ const possibleLogs = { setTerritoryWarfare: true, } -const defaultInterpreter = new Interpreter('', function(){}); +const defaultInterpreter = new Interpreter('', () => undefined); // the acorn interpreter has a bug where it doesn't convert arrays correctly. // so we have to more or less copy it here. @@ -351,7 +340,7 @@ function NetscriptFunctions(workerScript) { throw makeRuntimeRejectMsg( workerScript, `Invalid scriptArgs argument passed into getRunningScript() from ${callingFnName}(). ` + - `This is probably a bug. Please report to game developer` + `This is probably a bug. Please report to game developer`, ); } @@ -489,7 +478,7 @@ function NetscriptFunctions(workerScript) { } return null; } - let call = {line: "-1", func: "unknown"};; + let call = {line: "-1", func: "unknown"}; let chromeCall = parseChromeStackline(stackline); if (chromeCall) { call = chromeCall; @@ -1343,7 +1332,7 @@ function NetscriptFunctions(workerScript) { scriptname.forEach(function(script) { if (NetscriptFunctions(workerScript).scp(script, ip1, ip2)) { res = true; - }; + } }); return res; } @@ -1965,7 +1954,7 @@ function NetscriptFunctions(workerScript) { shares: shares, price: price, type: orderType, - pos: orderPos + pos: orderPos, }; return cancelOrder(params, workerScript); }, @@ -2468,21 +2457,21 @@ function NetscriptFunctions(workerScript) { threads: runningScript.threads, }; }, - getHackTime: function(ip, hack, int) { + getHackTime: function(ip) { updateDynamicRam("getHackTime", getRamCost("getHackTime")); const server = safeGetServer(ip, "getHackTime"); if (failOnHacknetServer(server, "getHackTime")) { return Infinity; } return calculateHackingTime(server, Player); // Returns seconds }, - getGrowTime: function(ip, hack, int) { + getGrowTime: function(ip) { updateDynamicRam("getGrowTime", getRamCost("getGrowTime")); const server = safeGetServer(ip, "getGrowTime"); if (failOnHacknetServer(server, "getGrowTime")) { return Infinity; } return calculateGrowTime(server, Player); // Returns seconds }, - getWeakenTime: function(ip, hack, int) { + getWeakenTime: function(ip) { updateDynamicRam("getWeakenTime", getRamCost("getWeakenTime")); const server = safeGetServer(ip, "getWeakenTime"); if (failOnHacknetServer(server, "getWeakenTime")) { return Infinity; } @@ -2570,7 +2559,7 @@ function NetscriptFunctions(workerScript) { const popupId = `prompt-popup-${txt.slice(0, 20)}`; const textElement = createElement("p", { innerHTML: txt }); - return new Promise(function(resolve, reject) { + return new Promise(function(resolve) { const yesBtn = createElement("button", { class: "popup-box-button", innerText: "Yes", @@ -2598,7 +2587,7 @@ function NetscriptFunctions(workerScript) { return Promise.resolve(false); } var s = safeGetServer(ip, "wget"); - return new Promise(function(resolve, reject) { + return new Promise(function(resolve) { $.get(url, function(data) { let res; if (isScriptFilename(target)) { @@ -2832,7 +2821,7 @@ function NetscriptFunctions(workerScript) { var darkweb = safetlyCreateUniqueServer({ ip: createUniqueRandomIp(), hostname:"darkweb", organizationName:"", - isConnectedTo:false, adminRights:false, purchasedByPlayer:false, maxRam:1 + isConnectedTo:false, adminRights:false, purchasedByPlayer:false, maxRam:1, }); AddToAllServers(darkweb); SpecialServerIps.addIp("Darkweb Server", darkweb.ip); @@ -2943,7 +2932,7 @@ function NetscriptFunctions(workerScript) { dexterity: Player.dexterity, agility: Player.agility, charisma: Player.charisma, - intelligence: Player.intelligence + intelligence: Player.intelligence, } }, getCharacterInformation: function() { @@ -4087,7 +4076,7 @@ function NetscriptFunctions(workerScript) { updateDynamicRam("getBonusTime", getRamCost("bladeburner", "getBonusTime")); checkBladeburnerAccess("getBonusTime"); return Math.round(Player.bladeburner.storedCycles / 5); - } + }, }, // End Bladeburner // Coding Contract API @@ -4373,7 +4362,7 @@ function NetscriptFunctions(workerScript) { } return Player.sleeves[sleeveNumber].tryBuyAugmentation(Player, aug); - } + }, }, // End sleeve formulas: { basic: { @@ -4438,7 +4427,7 @@ function NetscriptFunctions(workerScript) { constants: function() { checkFormulasAccess("hacknetNodes.constants", 5); return Object.assign({}, HacknetNodeConstants, HacknetServerConstants); - } + }, }, hacknetServers: { hashGainRate: function(level, ram, cores, mult=1) { @@ -4476,14 +4465,14 @@ function NetscriptFunctions(workerScript) { constants: function() { checkFormulasAccess("hacknetServers.constants", 9); return Object.assign({}, HacknetServerConstants); - } + }, }, }, // end formulas heart: { // Easter egg function break: function() { return Player.karma; - } + }, }, exploit: function() { Player.giveExploit(Exploit.UndocumentedFunctionCall); @@ -4515,7 +4504,7 @@ function NetscriptFunctions(workerScript) { ret[key.slice(2)] = value; } return ret; - } + }, } // End return } // End NetscriptFunction() diff --git a/src/NetscriptJSEvaluator.js b/src/NetscriptJSEvaluator.js index 257992797..ba8d5f5c3 100644 --- a/src/NetscriptJSEvaluator.js +++ b/src/NetscriptJSEvaluator.js @@ -1,5 +1,4 @@ import { makeRuntimeRejectMsg } from "./NetscriptEvaluator"; -import { Script } from "./Script/Script"; import { ScriptUrl } from "./Script/ScriptUrl"; // Makes a blob that contains the code of a given script. @@ -49,7 +48,7 @@ export async function executeJSScript(scripts = [], workerScript) { if (urls != null) { for (const b in urls) URL.revokeObjectURL(b.url); } - }; + } } /** Returns whether we should compile the script parameter. @@ -121,7 +120,7 @@ export function _getScriptUrls(script, scripts, seen) { // The top url in the stack is the replacement import file for this script. urlStack.push(...urls); return [prefix, urls[urls.length - 1].url, suffix].join(''); - } + }, ); // We automatically define a print function() in the NetscriptJS module so that diff --git a/src/NetscriptPort.ts b/src/NetscriptPort.ts index d9c5ea2a7..9dfcb5e48 100644 --- a/src/NetscriptPort.ts +++ b/src/NetscriptPort.ts @@ -3,8 +3,7 @@ import { Settings } from "./Settings/Settings"; export class NetscriptPort { data: any[] = []; - constructor() {} - + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types write(data: any): any { this.data.push(data); if (this.data.length > Settings.MaxPortCapacity) { @@ -13,6 +12,7 @@ export class NetscriptPort { return null; } + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types tryWrite(data: any): boolean { if (this.data.length >= Settings.MaxPortCapacity) { return false; @@ -32,7 +32,7 @@ export class NetscriptPort { if (this.data.length === 0) { return "NULL PORT DATA"; } else { - var foo = this.data.slice(); + const foo = this.data.slice(); return foo[0]; } } diff --git a/src/NetscriptWorker.js b/src/NetscriptWorker.js index 7b9803ab3..9ab2f1d02 100644 --- a/src/NetscriptWorker.js +++ b/src/NetscriptWorker.js @@ -21,10 +21,7 @@ import { NetscriptPort } from "./NetscriptPort"; import { Player } from "./Player"; import { RunningScript } from "./Script/RunningScript"; import { getRamUsageFromRunningScript } from "./Script/RunningScriptHelpers"; -import { - findRunningScript, - scriptCalculateOfflineProduction, -} from "./Script/ScriptHelpers"; +import { scriptCalculateOfflineProduction } from "./Script/ScriptHelpers"; import { AllServers } from "./Server/AllServers"; import { Settings } from "./Settings/Settings"; import { setTimeoutRef } from "./utils/SetTimeoutRef"; @@ -32,12 +29,11 @@ import { setTimeoutRef } from "./utils/SetTimeoutRef"; import { generate } from "escodegen"; import { dialogBoxCreate } from "../utils/DialogBox"; -import { compareArrays } from "../utils/helpers/compareArrays"; import { arrayToString } from "../utils/helpers/arrayToString"; import { roundToTwo } from "../utils/helpers/roundToTwo"; import { isString } from "../utils/StringHelperFunctions"; -import { parse, Node } from "acorn"; +import { parse } from "acorn"; const walk = require("acorn-walk"); // Netscript Ports are instantiated here @@ -111,7 +107,7 @@ function startNetscript2Script(workerScript) { return result; } } - }; + } for (let prop in workerScript.env.vars) { if (typeof workerScript.env.vars[prop] !== "function") continue; @@ -180,8 +176,8 @@ function startNetscript1Script(workerScript) { let fnPromise = entry.apply(null, fnArgs); fnPromise.then(function(res) { cb(res); - }).catch(function(e) { - // Do nothing? + }).catch(function(err) { + console.error(err); }); } int.setProperty(scope, name, int.createAsyncFunction(tempWrapper)); @@ -330,7 +326,7 @@ function processNetscript1Imports(code, workerScript) { FunctionDeclaration: (node) => { fnNames.push(node.id.name); fnDeclarations.push(node); - } + }, }); //Now we have to generate the code that would create the namespace @@ -370,7 +366,7 @@ function processNetscript1Imports(code, workerScript) { if (fnsToImport.includes(node.id.name)) { fnDeclarations.push(node); } - } + }, }); //Convert FunctionDeclarations into code @@ -379,7 +375,7 @@ function processNetscript1Imports(code, workerScript) { generatedCode += "\n"; }); } - } + }, }); //If there are no imports, just return the original code @@ -408,7 +404,7 @@ function processNetscript1Imports(code, workerScript) { var res = { code: code, - lineOffset: lineOffset + lineOffset: lineOffset, } return res; } @@ -443,8 +439,6 @@ export function startWorkerScript(runningScript, server) { * returns {boolean} indicating whether or not the workerScript was successfully added */ export function createAndAddWorkerScript(runningScriptObj, server) { - const filename = runningScriptObj.filename; - // Update server's ram usage let threads = 1; if (runningScriptObj.threads && !isNaN(runningScriptObj.threads)) { @@ -459,7 +453,7 @@ export function createAndAddWorkerScript(runningScriptObj, server) { `Not enough RAM to run script ${runningScriptObj.filename} with args ` + `${arrayToString(runningScriptObj.args)}. This likely occurred because you re-loaded ` + `the game and the script's RAM usage increased (either because of an update to the game or ` + - `your changes to the script.)` + `your changes to the script.)`, ); return false; } @@ -470,7 +464,7 @@ export function createAndAddWorkerScript(runningScriptObj, server) { if (pid === -1) { throw new Error( `Failed to start script because could not find available PID. This is most ` + - `because you have too many scripts running.` + `because you have too many scripts running.`, ); } diff --git a/src/PersonObjects/IPlayer.ts b/src/PersonObjects/IPlayer.ts index bb1f26a24..1be384676 100644 --- a/src/PersonObjects/IPlayer.ts +++ b/src/PersonObjects/IPlayer.ts @@ -156,7 +156,7 @@ export interface IPlayer { regenerateHp(amt: number): void; recordMoneySource(amt: number, source: string): void; setMoney(amt: number): void; - startBladeburner(p: object): void; + startBladeburner(p: any): void; startClass(costMult: number, expMult: number, className: string): void; startCorporation(corpName: string, additionalShares?: number): void; startCrime(crimeType: string, diff --git a/src/PersonObjects/Person.ts b/src/PersonObjects/Person.ts index 8e6619156..dd4eb1176 100644 --- a/src/PersonObjects/Person.ts +++ b/src/PersonObjects/Person.ts @@ -1,6 +1,5 @@ // Base class representing a person-like object import { Augmentation } from "../Augmentation/Augmentation"; -import { Augmentations } from "../Augmentation/Augmentations"; import { IPlayerOwnedAugmentation } from "../Augmentation/PlayerOwnedAugmentation"; import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; import { CityName } from "../Locations/data/CityNames"; @@ -36,67 +35,67 @@ export abstract class Person { /** * Stats */ - hacking_skill: number = 1; - strength: number = 1; - defense: number = 1; - dexterity: number = 1; - agility: number = 1; - charisma: number = 1; - intelligence: number = 1; - hp: number = 10; - max_hp: number = 10; + hacking_skill = 1; + strength = 1; + defense = 1; + dexterity = 1; + agility = 1; + charisma = 1; + intelligence = 1; + hp = 10; + max_hp = 10; /** * Experience */ - hacking_exp: number = 0; - strength_exp: number = 0; - defense_exp: number = 0; - dexterity_exp: number = 0; - agility_exp: number = 0; - charisma_exp: number = 0; - intelligence_exp: number = 0; + hacking_exp = 0; + strength_exp = 0; + defense_exp = 0; + dexterity_exp = 0; + agility_exp = 0; + charisma_exp = 0; + intelligence_exp = 0; /** * Multipliers */ - hacking_mult: number = 1; - strength_mult: number = 1; - defense_mult: number = 1; - dexterity_mult: number = 1; - agility_mult: number = 1; - charisma_mult: number = 1; + hacking_mult = 1; + strength_mult = 1; + defense_mult = 1; + dexterity_mult = 1; + agility_mult = 1; + charisma_mult = 1; - hacking_exp_mult: number = 1; - strength_exp_mult: number = 1; - defense_exp_mult: number = 1; - dexterity_exp_mult: number = 1; - agility_exp_mult: number = 1; - charisma_exp_mult: number = 1; + hacking_exp_mult = 1; + strength_exp_mult = 1; + defense_exp_mult = 1; + dexterity_exp_mult = 1; + agility_exp_mult = 1; + charisma_exp_mult = 1; - hacking_chance_mult: number = 1; - hacking_speed_mult: number = 1; - hacking_money_mult: number = 1; - hacking_grow_mult: number = 1; + hacking_chance_mult = 1; + hacking_speed_mult = 1; + hacking_money_mult = 1; + hacking_grow_mult = 1; - company_rep_mult: number = 1; - faction_rep_mult: number = 1; + company_rep_mult = 1; + faction_rep_mult = 1; - crime_money_mult: number = 1; - crime_success_mult: number = 1; + crime_money_mult = 1; + crime_success_mult = 1; - work_money_mult: number = 1; + work_money_mult = 1; - hacknet_node_money_mult: number = 1; - hacknet_node_purchase_cost_mult: number = 1; - hacknet_node_ram_cost_mult: number = 1; - hacknet_node_core_cost_mult: number = 1; - hacknet_node_level_cost_mult: number = 1; + hacknet_node_money_mult = 1; + hacknet_node_purchase_cost_mult = 1; + hacknet_node_ram_cost_mult = 1; + hacknet_node_core_cost_mult = 1; + hacknet_node_level_cost_mult = 1; - bladeburner_max_stamina_mult: number = 1; - bladeburner_stamina_gain_mult: number = 1; - bladeburner_analysis_mult: number = 1; - bladeburner_success_chance_mult : number = 1; + bladeburner_max_stamina_mult = 1; + bladeburner_stamina_gain_mult = 1; + bladeburner_analysis_mult = 1; + bladeburner_success_chance_mult = 1; /** * Augmentations @@ -109,12 +108,10 @@ export abstract class Person { */ city: CityName = CityName.Sector12; - constructor() {} - /** * Updates this object's multipliers for the given augmentation */ - applyAugmentation(aug: Augmentation) { + applyAugmentation(aug: Augmentation): void { for (const mult in aug.mults) { if ((this)[mult] == null) { console.warn(`Augmentation has unrecognized multiplier property: ${mult}`); @@ -128,7 +125,7 @@ export abstract class Person { * Given an experience amount and stat multiplier, calculates the * stat level. Stat-agnostic (same formula for every stat) */ - calculateStat(exp: number, mult: number=1): number { + calculateStat(exp: number, mult=1): number { return calculateSkill(exp, mult); } diff --git a/src/PersonObjects/Player/PlayerObject.js b/src/PersonObjects/Player/PlayerObject.js index c3b736719..cf30a50d9 100644 --- a/src/PersonObjects/Player/PlayerObject.js +++ b/src/PersonObjects/Player/PlayerObject.js @@ -12,7 +12,7 @@ import { MoneySourceTracker } from "../../utils/MoneySourceTracker"; import { Reviver, Generic_toJSON, - Generic_fromJSON + Generic_fromJSON, } from "../../../utils/JSONReviver"; import Decimal from "decimal.js"; @@ -203,7 +203,7 @@ export function PlayerObject() { this.scriptProdSinceLastAug = 0; this.exploits = []; -}; +} // Apply player methods to the prototype using Object.assign() Object.assign( @@ -213,7 +213,7 @@ Object.assign( bladeburnerMethods, corporationMethods, gangMethods, - augmentationMethods + augmentationMethods, ); PlayerObject.prototype.toJSON = function() { diff --git a/src/PersonObjects/Player/PlayerObjectCorporationMethods.js b/src/PersonObjects/Player/PlayerObjectCorporationMethods.js index a1d358232..216109d3d 100644 --- a/src/PersonObjects/Player/PlayerObjectCorporationMethods.js +++ b/src/PersonObjects/Player/PlayerObjectCorporationMethods.js @@ -12,7 +12,7 @@ export function hasCorporation() { export function startCorporation(corpName, additionalShares=0) { this.corporation = new Corporation({ - name: corpName + name: corpName, }); this.corporation.totalShares += additionalShares; diff --git a/src/PersonObjects/Player/PlayerObjectGeneralMethods.jsx b/src/PersonObjects/Player/PlayerObjectGeneralMethods.jsx index 922721b61..76f1de7aa 100644 --- a/src/PersonObjects/Player/PlayerObjectGeneralMethods.jsx +++ b/src/PersonObjects/Player/PlayerObjectGeneralMethods.jsx @@ -3,7 +3,6 @@ import { applyAugmentation } from "../../Augmentation/AugmentationHelpers"; import { PlayerOwnedAugmentation } from "../../Augmentation/PlayerOwnedAugmentation"; import { AugmentationNames } from "../../Augmentation/data/AugmentationNames"; import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers"; -import { Bladeburner } from "../../Bladeburner"; import { CodingContractRewardType } from "../../CodingContracts"; import { Company } from "../../Company/Company"; import { Companies } from "../../Company/Companies"; @@ -12,7 +11,6 @@ import { getJobRequirementText } from "../../Company/GetJobRequirementText"; import { CompanyPositions } from "../../Company/CompanyPositions"; import * as posNames from "../../Company/data/companypositionnames"; import {CONSTANTS} from "../../Constants"; -import { Corporation } from "../../Corporation/Corporation"; import { Programs } from "../../Programs/Programs"; import { determineCrimeSuccess } from "../../Crime/CrimeHelpers"; import { Crimes } from "../../Crime/Crimes"; @@ -22,7 +20,6 @@ import { Factions } from "../../Faction/Factions"; import { displayFactionContent } from "../../Faction/FactionHelpers"; import { resetGangs } from "../../Gang"; import { hasHacknetServers } from "../../Hacknet/HacknetHelpers"; -import { HashManager } from "../../Hacknet/HashManager"; import { Cities } from "../../Locations/Cities"; import { Locations } from "../../Locations/Locations"; import { CityName } from "../../Locations/data/CityNames"; @@ -56,12 +53,7 @@ import { numeralWrapper } from "../../ui/numeralFormat"; import { MoneySourceTracker } from "../../utils/MoneySourceTracker"; import { dialogBoxCreate } from "../../../utils/DialogBox"; import { clearEventListeners } from "../../../utils/uiHelpers/clearEventListeners"; -import { - Reviver, - Generic_toJSON, - Generic_fromJSON, -} from "../../../utils/JSONReviver"; -import {convertTimeMsToTimeElapsedString} from "../../../utils/StringHelperFunctions"; +import { convertTimeMsToTimeElapsedString } from "../../../utils/StringHelperFunctions"; import { Reputation } from "../../ui/React/Reputation"; import { Money } from "../../ui/React/Money"; @@ -614,7 +606,6 @@ export function startWork(companyName) { } export function cancelationPenalty() { - const company = Companies[this.companyName]; const specialIp = SpecialServerIps[this.companyName]; if(specialIp) { const server = AllServers[specialIp]; @@ -1226,7 +1217,7 @@ export function createProgramWork(numCycles) { , elem); } -export function finishCreateProgramWork(cancelled, sing=false) { +export function finishCreateProgramWork(cancelled) { var programName = this.createProgramName; if (cancelled === false) { dialogBoxCreate("You've finished creating " + programName + "!
    " + @@ -1313,11 +1304,11 @@ export function startClass(costMult, expMult, className) { this.workMoneyLossRate = cost; this.workHackExpGainRate = hackExp * this.hacking_exp_mult * BitNodeMultipliers.ClassGymExpGain; - this.workStrExpGainRate = strExp * this.strength_exp_mult * BitNodeMultipliers.ClassGymExpGain;; - this.workDefExpGainRate = defExp * this.defense_exp_mult * BitNodeMultipliers.ClassGymExpGain;; - this.workDexExpGainRate = dexExp * this.dexterity_exp_mult * BitNodeMultipliers.ClassGymExpGain;; - this.workAgiExpGainRate = agiExp * this.agility_exp_mult * BitNodeMultipliers.ClassGymExpGain;; - this.workChaExpGainRate = chaExp * this.charisma_exp_mult * BitNodeMultipliers.ClassGymExpGain;; + this.workStrExpGainRate = strExp * this.strength_exp_mult * BitNodeMultipliers.ClassGymExpGain; + this.workDefExpGainRate = defExp * this.defense_exp_mult * BitNodeMultipliers.ClassGymExpGain; + this.workDexExpGainRate = dexExp * this.dexterity_exp_mult * BitNodeMultipliers.ClassGymExpGain; + this.workAgiExpGainRate = agiExp * this.agility_exp_mult * BitNodeMultipliers.ClassGymExpGain; + this.workChaExpGainRate = chaExp * this.charisma_exp_mult * BitNodeMultipliers.ClassGymExpGain; var cancelButton = clearEventListeners("work-in-progress-cancel-button"); if (className == CONSTANTS.ClassGymStrength || @@ -1460,7 +1451,6 @@ export function commitCrime(numCycles) { export function finishCrime(cancelled) { //Determine crime success/failure if (!cancelled) { - var statusText = ""; // TODO, unique message for each crime when you succeed if (determineCrimeSuccess(this, this.crimeType)) { //Handle Karma and crime statistics let crime = null; @@ -1580,7 +1570,7 @@ export function singularityStopWork() { res = this.finishFactionWork(true, true); break; case CONSTANTS.WorkTypeCreateProgram: - res = this.finishCreateProgramWork(true, true); + res = this.finishCreateProgramWork(true); break; case CONSTANTS.WorkTypeCrime: res = this.finishCrime(true); diff --git a/src/PersonObjects/Player/PlayerObjectServerMethods.ts b/src/PersonObjects/Player/PlayerObjectServerMethods.ts index 84ec0a79f..e2053c392 100644 --- a/src/PersonObjects/Player/PlayerObjectServerMethods.ts +++ b/src/PersonObjects/Player/PlayerObjectServerMethods.ts @@ -6,6 +6,7 @@ import { IPlayer } from "../IPlayer"; import { CONSTANTS } from "../../Constants"; import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers"; +import { Server } from "../../Server/Server"; import { HacknetServer } from "../../Hacknet/HacknetServer"; import { AddToAllServers, @@ -14,19 +15,19 @@ import { } from "../../Server/AllServers"; import { SpecialServerIps } from "../../Server/SpecialServerIps"; -export function hasTorRouter(this: IPlayer) { +export function hasTorRouter(this: IPlayer): boolean { return SpecialServerIps.hasOwnProperty("Darkweb Server"); } -export function getCurrentServer(this: IPlayer) { +export function getCurrentServer(this: IPlayer): Server | HacknetServer | null { return AllServers[this.currentServer]; } -export function getHomeComputer(this: IPlayer) { +export function getHomeComputer(this: IPlayer): Server | HacknetServer | null { return AllServers[this.homeComputer]; } -export function getUpgradeHomeRamCost(this: IPlayer) { +export function getUpgradeHomeRamCost(this: IPlayer): number { //Calculate how many times ram has been upgraded (doubled) const currentRam = this.getHomeComputer().maxRam; const numUpgrades = Math.log2(currentRam); @@ -34,7 +35,7 @@ export function getUpgradeHomeRamCost(this: IPlayer) { //Calculate cost //Have cost increase by some percentage each time RAM has been upgraded const mult = Math.pow(1.58, numUpgrades); - var cost = currentRam * CONSTANTS.BaseCostFor1GBOfRamHome * mult * BitNodeMultipliers.HomeComputerRamCost; + const cost = currentRam * CONSTANTS.BaseCostFor1GBOfRamHome * mult * BitNodeMultipliers.HomeComputerRamCost; return cost; } diff --git a/src/PersonObjects/Resleeving/Resleeve.ts b/src/PersonObjects/Resleeving/Resleeve.ts index 0cd330ad0..c289ac7ab 100644 --- a/src/PersonObjects/Resleeving/Resleeve.ts +++ b/src/PersonObjects/Resleeving/Resleeve.ts @@ -10,12 +10,6 @@ import { Augmentations } from "../../Augmentation/Augmentations"; import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../../utils/JSONReviver"; export class Resleeve extends Person { - /** - * Initiatizes a Resleeve object from a JSON save state. - */ - static fromJSON(value: any): Resleeve { - return Generic_fromJSON(Resleeve, value.data); - } constructor() { super(); @@ -23,13 +17,13 @@ export class Resleeve extends Person { getCost(): number { // Each experience point adds this to the cost - const CostPerExp: number = 25e3; + const CostPerExp = 25e3; // Final cost is multiplied by this constant ^ # Augs - const NumAugsExponent: number = 1.2; + const NumAugsExponent = 1.2; // Get total exp in this re-sleeve - let totalExp: number = this.hacking_exp + + const totalExp: number = this.hacking_exp + this.strength_exp + this.defense_exp + this.dexterity_exp + @@ -37,14 +31,14 @@ export class Resleeve extends Person { this.charisma_exp; // Get total base Augmentation cost for this re-sleeve - let totalAugmentationCost: number = 0; + let totalAugmentationCost = 0; for (let i = 0; i < this.augmentations.length; ++i) { const aug: Augmentation | null = Augmentations[this.augmentations[i].name]; if (aug == null) { console.error(`Could not find Augmentation ${this.augmentations[i].name}`); continue; } - totalAugmentationCost += aug!.startingCost; + totalAugmentationCost += aug.startingCost; } return (totalExp * CostPerExp) + (totalAugmentationCost * Math.pow(NumAugsExponent, this.augmentations.length)); @@ -56,6 +50,14 @@ export class Resleeve extends Person { toJSON(): any { return Generic_toJSON("Resleeve", this); } + + /** + * Initiatizes a Resleeve object from a JSON save state. + */ + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types + static fromJSON(value: any): Resleeve { + return Generic_fromJSON(Resleeve, value.data); + } } Reviver.constructors.Resleeve = Resleeve; diff --git a/src/PersonObjects/Resleeving/Resleeving.ts b/src/PersonObjects/Resleeving/Resleeving.ts index 9b158145c..1c09b9cbf 100644 --- a/src/PersonObjects/Resleeving/Resleeving.ts +++ b/src/PersonObjects/Resleeving/Resleeving.ts @@ -76,12 +76,12 @@ export function purchaseResleeve(r: Resleeve, p: IPlayer): boolean { // Creates all of the Re-sleeves that will be available for purchase at VitaLife export function generateResleeves(): Resleeve[] { - const NumResleeves: number = 40; // Total number of Resleeves to generate + const NumResleeves = 40; // Total number of Resleeves to generate - let ret: Resleeve[] = []; + const ret: Resleeve[] = []; for (let i = 0; i < NumResleeves; ++i) { // i will be a number indicating how "powerful" the Re-sleeve should be - let r: Resleeve = new Resleeve(); + const r: Resleeve = new Resleeve(); // Generate experience const expMult: number = (5 * i) + 1; @@ -108,7 +108,8 @@ export function generateResleeves(): Resleeve[] { } const randAug: Augmentation | null = Augmentations[randKey]; - r.augmentations.push({name: randAug!.name, level: 1}); + if(randAug === null) throw new Error(`null augmentation: ${randKey}`) + r.augmentations.push({name: randAug.name, level: 1}); r.applyAugmentation(Augmentations[randKey]); r.updateStatLevels(); diff --git a/src/PersonObjects/Resleeving/ResleevingUI.tsx b/src/PersonObjects/Resleeving/ResleevingUI.tsx index 4957e6dd1..23b3da192 100644 --- a/src/PersonObjects/Resleeving/ResleevingUI.tsx +++ b/src/PersonObjects/Resleeving/ResleevingUI.tsx @@ -61,7 +61,7 @@ const UIElems: IPageUIElems = { let playerRef: IPlayer | null; -export function createResleevesPage(p: IPlayer) { +export function createResleevesPage(p: IPlayer): void { if (!routing.isOn(Page.Resleeves)) { return; } try { @@ -98,7 +98,7 @@ export function createResleevesPage(p: IPlayer) { // Create a selector for sorting the list of Resleeves UIElems.sortTag = createElement("p", { display: "inline-block", - innerText: "Sort By: " + innerText: "Sort By: ", }); UIElems.sortSelector = createElement("select", { class: "dropdown" }) as HTMLSelectElement; @@ -115,25 +115,25 @@ export function createResleevesPage(p: IPlayer) { TotalNumAugmentations = "TotalNumAugmentations", } - UIElems.sortSelector!.add(createOptionElement("Cost", SortOption.Cost)); - UIElems.sortSelector!.add(createOptionElement("Hacking Level", SortOption.Hacking)); - UIElems.sortSelector!.add(createOptionElement("Strength Level", SortOption.Strength)); - UIElems.sortSelector!.add(createOptionElement("Defense Level", SortOption.Defense)); - UIElems.sortSelector!.add(createOptionElement("Dexterity Level", SortOption.Dexterity)); - UIElems.sortSelector!.add(createOptionElement("Agility Level", SortOption.Agility)); - UIElems.sortSelector!.add(createOptionElement("Charisma Level", SortOption.Charisma)); - UIElems.sortSelector!.add(createOptionElement("Average Combat Stats", SortOption.AverageCombatStats)); - UIElems.sortSelector!.add(createOptionElement("Average Stats", SortOption.AverageAllStats)); - UIElems.sortSelector!.add(createOptionElement("Number of Augmentations", SortOption.TotalNumAugmentations)); + UIElems.sortSelector.add(createOptionElement("Cost", SortOption.Cost)); + UIElems.sortSelector.add(createOptionElement("Hacking Level", SortOption.Hacking)); + UIElems.sortSelector.add(createOptionElement("Strength Level", SortOption.Strength)); + UIElems.sortSelector.add(createOptionElement("Defense Level", SortOption.Defense)); + UIElems.sortSelector.add(createOptionElement("Dexterity Level", SortOption.Dexterity)); + UIElems.sortSelector.add(createOptionElement("Agility Level", SortOption.Agility)); + UIElems.sortSelector.add(createOptionElement("Charisma Level", SortOption.Charisma)); + UIElems.sortSelector.add(createOptionElement("Average Combat Stats", SortOption.AverageCombatStats)); + UIElems.sortSelector.add(createOptionElement("Average Stats", SortOption.AverageAllStats)); + UIElems.sortSelector.add(createOptionElement("Number of Augmentations", SortOption.TotalNumAugmentations)); UIElems.resleeveList = createElement("ul"); - UIElems.sortSelector!.onchange = () => { + UIElems.sortSelector.onchange = () => { removeChildrenFromElement(UIElems.resleeveList); UIElems.resleeves = []; // Helper function for averaging - function getAverage(...values: number[]) { - let sum: number = 0; + function getAverage(...values: number[]): number { + let sum = 0; for (let i = 0; i < values.length; ++i) { sum += values[i]; } @@ -141,7 +141,7 @@ export function createResleevesPage(p: IPlayer) { return sum / values.length; } - const sortOpt = getSelectValue(UIElems.sortSelector!); + const sortOpt = getSelectValue(UIElems.sortSelector); switch (sortOpt) { case SortOption.Hacking: p.resleeves.sort((a, b) => { @@ -175,16 +175,16 @@ export function createResleevesPage(p: IPlayer) { break; case SortOption.AverageCombatStats: p.resleeves.sort((a, b) => { - let aAvg = getAverage(a.strength, a.defense, a.dexterity, a.agility); - let bAvg = getAverage(b.strength, b.defense, b.dexterity, b.agility); + const aAvg = getAverage(a.strength, a.defense, a.dexterity, a.agility); + const bAvg = getAverage(b.strength, b.defense, b.dexterity, b.agility); return aAvg - bAvg; }); break; case SortOption.AverageAllStats: p.resleeves.sort((a, b) => { - let aAvg = getAverage(a.hacking_skill, a.strength, a.defense, a.dexterity, a.agility, a.charisma); - let bAvg = getAverage(b.hacking_skill, b.strength, b.defense, b.dexterity, b.agility, b.charisma); + const aAvg = getAverage(a.hacking_skill, a.strength, a.defense, a.dexterity, a.agility, a.charisma); + const bAvg = getAverage(b.hacking_skill, b.strength, b.defense, b.dexterity, b.agility, b.charisma); return aAvg - bAvg; }); @@ -202,14 +202,18 @@ export function createResleevesPage(p: IPlayer) { break; } + if(UIElems.resleeveList == null) throw new Error("UIElems.resleeveList is null in sortSelector.click()"); + if(UIElems.resleeves == null) throw new Error("UIElems.resleeves is null in sortSelector.click()"); + // Create UI for all Resleeves for (const resleeve of p.resleeves) { const resleeveUi = createResleeveUi(resleeve); - UIElems.resleeveList!.appendChild(resleeveUi.container!); - UIElems.resleeves!.push(resleeveUi); + if(resleeveUi.container == null) throw new Error("resleeveUi.container is null in sortSelector.click()"); + UIElems.resleeveList.appendChild(resleeveUi.container); + UIElems.resleeves.push(resleeveUi); } } - UIElems.sortSelector!.dispatchEvent(new Event('change')); // Force onchange event + UIElems.sortSelector.dispatchEvent(new Event('change')); // Force onchange event UIElems.container.appendChild(UIElems.info); UIElems.container.appendChild(createElement("br")); @@ -217,13 +221,15 @@ export function createResleevesPage(p: IPlayer) { UIElems.container.appendChild(UIElems.sortSelector); UIElems.container.appendChild(UIElems.resleeveList); - document.getElementById("entire-game-container")!.appendChild(UIElems.container); + const container = document.getElementById("entire-game-container"); + if(container == null) throw new Error("Could not find entire-game-container in createResleevesPage()"); + container.appendChild(UIElems.container); } catch(e) { exceptionAlert(e); } } -export function clearResleevesPage() { +export function clearResleevesPage(): void { if (UIElems.container instanceof HTMLElement) { removeElement(UIElems.container); } @@ -304,10 +310,10 @@ function createResleeveUi(resleeve: Resleeve): IResleeveUIElems { `Bladeburner Max Stamina multiplier: ${numeralWrapper.formatPercentage(resleeve.bladeburner_max_stamina_mult)}`, `Bladeburner Stamina Gain multiplier: ${numeralWrapper.formatPercentage(resleeve.bladeburner_stamina_gain_mult)}`, `Bladeburner Field Analysis multiplier: ${numeralWrapper.formatPercentage(resleeve.bladeburner_analysis_mult)}`, - `Bladeburner Success Chance multiplier: ${numeralWrapper.formatPercentage(resleeve.bladeburner_success_chance_mult)}` - ].join("
    "), false + `Bladeburner Success Chance multiplier: ${numeralWrapper.formatPercentage(resleeve.bladeburner_success_chance_mult)}`, + ].join("
    "), false, ) - } + }, }); elems.statsPanel.appendChild(elems.stats); elems.statsPanel.appendChild(elems.multipliersButton); @@ -317,7 +323,7 @@ function createResleeveUi(resleeve: Resleeve): IResleeveUIElems { elems.augDescription = createElement("p"); for (let i = 0; i < resleeve.augmentations.length; ++i) { elems.augSelector.add(createOptionElement(resleeve.augmentations[i].name)); - }; + } elems.augSelector.addEventListener("change", () => { updateAugDescription(elems); }); @@ -335,12 +341,13 @@ function createResleeveUi(resleeve: Resleeve): IResleeveUIElems { class: "std-button", innerText: "Purchase", clickListener: () => { - if (purchaseResleeve(resleeve, playerRef!)) { + if(playerRef == null) throw new Error("playerRef is null in buyButton.click()"); + if (purchaseResleeve(resleeve, playerRef)) { dialogBoxCreate((<>You re-sleeved for {Money(cost)}!), false); } else { dialogBoxCreate(`You cannot afford to re-sleeve into this body`, false); } - } + }, }); elems.costPanel.appendChild(elems.costText); elems.costPanel.appendChild(elems.buyButton); @@ -352,7 +359,8 @@ function createResleeveUi(resleeve: Resleeve): IResleeveUIElems { return elems; } -function updateAugDescription(elems: IResleeveUIElems) { +function updateAugDescription(elems: IResleeveUIElems): void { + if(elems.augDescription == null) throw new Error("elems.augDescription is null in updateAugDescription()"); const augName: string = getSelectValue(elems.augSelector); const aug: Augmentation | null = Augmentations[augName]; if (aug == null) { @@ -360,5 +368,5 @@ function updateAugDescription(elems: IResleeveUIElems) { return; } - elems.augDescription!.innerHTML = aug!.info; + elems.augDescription.innerHTML = aug.info; } diff --git a/src/PersonObjects/Sleeve/Sleeve.ts b/src/PersonObjects/Sleeve/Sleeve.ts index 34f63312d..6cd07e3c4 100644 --- a/src/PersonObjects/Sleeve/Sleeve.ts +++ b/src/PersonObjects/Sleeve/Sleeve.ts @@ -12,7 +12,7 @@ import { IPlayer } from "../IPlayer"; import { Person, ITaskTracker, - createTaskTracker + createTaskTracker, } from "../Person"; import { Augmentation } from "../../Augmentation/Augmentation"; @@ -39,23 +39,17 @@ import { LocationName } from "../../Locations/data/LocationNames"; import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../../utils/JSONReviver"; export class Sleeve extends Person { - /** - * Initiatizes a Sleeve object from a JSON save state. - */ - static fromJSON(value: any): Sleeve { - return Generic_fromJSON(Sleeve, value.data); - } /** * Stores the name of the class that the player is currently taking */ - className: string = ""; + className = ""; /** * Stores the type of crime the sleeve is currently attempting * Must match the name of a Crime object */ - crimeType: string = ""; + crimeType = ""; /** * Enum value for current task @@ -70,17 +64,17 @@ export class Sleeve extends Person { * Crime: Money earned if successful * Class/Gym: Name of university/gym */ - currentTaskLocation: string = ""; + currentTaskLocation = ""; /** * Maximum amount of time (in milliseconds) that can be spent on current task. */ - currentTaskMaxTime: number = 0; + currentTaskMaxTime = 0; /** * Milliseconds spent on current task */ - currentTaskTime: number = 0; + currentTaskTime = 0; /** * Keeps track of experience earned for other sleeves @@ -110,7 +104,7 @@ export class Sleeve extends Person { /** * String that stores what stat the sleeve is training at the gym */ - gymStatType: string = ""; + gymStatType = ""; /** * Keeps track of events/notifications for this sleeve @@ -120,7 +114,7 @@ export class Sleeve extends Person { /** * Clone retains 'memory' synchronization (and maybe exp?) upon prestige/installing Augs */ - memory: number = 1; + memory = 1; /** * Sleeve shock. Number between 0 and 100 @@ -129,19 +123,19 @@ export class Sleeve extends Person { * * Reputation earned is also multiplied by shock% */ - shock: number = 1; + shock = 1; /** * Stored number of game "loop" cycles */ - storedCycles: number = 0; + storedCycles = 0; /** * Synchronization. Number between 0 and 100 * When experience is earned by sleeve, both the player and the sleeve get * sync% of the experience earned. Other sleeves get sync^2% of exp */ - sync: number = 1; + sync = 1; constructor(p: IPlayer | null = null) { super(); @@ -228,7 +222,7 @@ export class Sleeve extends Person { * Earn experience for any stats (supports multiple) * This function also handles experience propogating to Player and other sleeves */ - gainExperience(p: IPlayer, exp: ITaskTracker, numCycles: number=1, fromOtherSleeve: boolean=false): ITaskTracker { + gainExperience(p: IPlayer, exp: ITaskTracker, numCycles=1, fromOtherSleeve=false): ITaskTracker { // If the experience is coming from another sleeve, it is not multiplied by anything. // Also the player does not earn anything if (fromOtherSleeve) { @@ -335,7 +329,7 @@ export class Sleeve extends Person { /** * Earn money for player */ - gainMoney(p: IPlayer, task: ITaskTracker, numCycles: number=1): void { + gainMoney(p: IPlayer, task: ITaskTracker, numCycles=1): void { const gain: number = (task.money * numCycles); this.earningsForTask.money += gain; this.earningsForPlayer.money += gain; @@ -373,10 +367,10 @@ export class Sleeve extends Person { */ getRepGain(p: IPlayer): number { if (this.currentTask === SleeveTaskType.Faction) { - let favorMult: number = 1; + let favorMult = 1; const fac: Faction | null = Factions[this.currentTaskLocation]; if (fac != null) { - favorMult = 1 + (fac!.favor / 100); + favorMult = 1 + (fac.favor / 100); } switch (this.factionWorkType) { @@ -404,10 +398,10 @@ export class Sleeve extends Person { return 0; } - const jobPerformance: number = companyPosition!.calculateJobPerformance(this.hacking_skill, this.strength, + const jobPerformance: number = companyPosition.calculateJobPerformance(this.hacking_skill, this.strength, this.defense, this.dexterity, this.agility, this.charisma); - const favorMult = 1 + (company!.favor / 100); + const favorMult = 1 + (company.favor / 100); return jobPerformance * this.company_rep_mult * favorMult; } else { @@ -429,7 +423,7 @@ export class Sleeve extends Person { } log(entry: string): void { - const MaxLogSize: number = 50; + const MaxLogSize = 50; this.logs.push(entry); if (this.logs.length > MaxLogSize) { this.logs.shift(); @@ -439,7 +433,7 @@ export class Sleeve extends Person { /** * Called on every sleeve for a Source File prestige */ - prestige(p: IPlayer) { + prestige(p: IPlayer): void { // Reset exp this.hacking_exp = 0; this.strength_exp = 0; @@ -471,7 +465,7 @@ export class Sleeve extends Person { * Returns an object containing the amount of experience that should be * transferred to all other sleeves */ - process(p: IPlayer, numCycles: number=1): ITaskTracker | null { + process(p: IPlayer, numCycles=1): ITaskTracker | null { // Only process once every second (5 cycles) const CyclesPerSecond = 1000 / CONSTANTS.MilliPerCycle; this.storedCycles += numCycles; @@ -504,7 +498,7 @@ export class Sleeve extends Person { retValue = this.gainExperience(p, this.gainRatesForTask, cyclesUsed); this.gainMoney(p, this.gainRatesForTask, cyclesUsed); break; - case SleeveTaskType.Faction: + case SleeveTaskType.Faction: { retValue = this.gainExperience(p, this.gainRatesForTask, cyclesUsed); this.gainMoney(p, this.gainRatesForTask, cyclesUsed); @@ -517,7 +511,8 @@ export class Sleeve extends Person { fac.playerReputation += (this.getRepGain(p) * cyclesUsed); break; - case SleeveTaskType.Company: + } + case SleeveTaskType.Company: { retValue = this.gainExperience(p, this.gainRatesForTask, cyclesUsed); this.gainMoney(p, this.gainRatesForTask, cyclesUsed); @@ -527,8 +522,9 @@ export class Sleeve extends Person { break; } - company!.playerReputation += (this.getRepGain(p) * cyclesUsed); + company.playerReputation += (this.getRepGain(p) * cyclesUsed); break; + } case SleeveTaskType.Recovery: this.shock = Math.min(100, this.shock + (0.0002 * cyclesUsed)); break; @@ -605,7 +601,7 @@ export class Sleeve extends Person { // Set exp/money multipliers based on which university. // Also check that the sleeve is in the right city - let costMult: number = 1; + let costMult = 1; switch (universityName.toLowerCase()) { case LocationName.AevumSummitUniversity.toLowerCase(): if (this.city !== CityName.Aevum) { return false; } @@ -676,7 +672,7 @@ export class Sleeve extends Person { updateTaskGainRates(p: IPlayer): void { if (this.currentTask === SleeveTaskType.Class) { - let expMult: number = 1; + let expMult = 1; switch (this.currentTaskLocation.toLowerCase()) { case LocationName.AevumSummitUniversity.toLowerCase(): expMult = 3; @@ -720,7 +716,7 @@ export class Sleeve extends Person { if (this.currentTask === SleeveTaskType.Gym) { // Get gym exp multiplier - let expMult: number = 1; + let expMult = 1; switch (this.currentTaskLocation.toLowerCase()) { case LocationName.AevumCrushFitnessGym.toLowerCase(): expMult = 2; @@ -742,7 +738,7 @@ export class Sleeve extends Person { } // Set stat gain rate - const baseGymExp: number = 1; + const baseGymExp = 1; const totalExpMultiplier = p.hashManager.getTrainingMult() * expMult; const sanitizedStat: string = this.gymStatType.toLowerCase(); if (sanitizedStat.includes("str")) { @@ -889,7 +885,7 @@ export class Sleeve extends Person { // Set exp/money multipliers based on which university. // Also check that the sleeve is in the right city - let costMult: number = 1; + let costMult = 1; switch (gymName.toLowerCase()) { case LocationName.AevumCrushFitnessGym.toLowerCase(): if (this.city != CityName.Aevum) { return false; } @@ -947,6 +943,14 @@ export class Sleeve extends Person { toJSON(): any { return Generic_toJSON("Sleeve", this); } + + /** + * Initiatizes a Sleeve object from a JSON save state. + */ + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types + static fromJSON(value: any): Sleeve { + return Generic_fromJSON(Sleeve, value.data); + } } Reviver.constructors.Sleeve = Sleeve; diff --git a/src/PersonObjects/Sleeve/SleeveAugmentationsUI.ts b/src/PersonObjects/Sleeve/SleeveAugmentationsUI.ts index 756987369..41604e766 100644 --- a/src/PersonObjects/Sleeve/SleeveAugmentationsUI.ts +++ b/src/PersonObjects/Sleeve/SleeveAugmentationsUI.ts @@ -10,7 +10,6 @@ import { IPlayer } from "../IPlayer"; import { Augmentation } from "../../Augmentation/Augmentation"; import { Augmentations } from "../../Augmentation/Augmentations"; -import { numeralWrapper } from "../../ui/numeralFormat"; import { Money } from "../../ui/React/Money"; import { dialogBoxCreate } from "../../../utils/DialogBox"; @@ -22,7 +21,7 @@ import { removeElementById } from "../../../utils/uiHelpers/removeElementById"; import { renderToStaticMarkup } from "react-dom/server" -export function createSleevePurchaseAugsPopup(sleeve: Sleeve, p: IPlayer) { +export function createSleevePurchaseAugsPopup(sleeve: Sleeve, p: IPlayer): void { // Array of all owned Augmentations. Names only const ownedAugNames: string[] = sleeve.augmentations.map((e) => {return e.name}); @@ -73,7 +72,7 @@ export function createSleevePurchaseAugsPopup(sleeve: Sleeve, p: IPlayer) { `that you have unlocked through Factions.

    `, `When purchasing an Augmentation for a Duplicate Sleeve, they are immediately`, `installed. This means that the Duplicate Sleeve will immediately lose all of`, - `its stat experience.` + `its stat experience.`, ].join(" "), }); @@ -90,7 +89,7 @@ export function createSleevePurchaseAugsPopup(sleeve: Sleeve, p: IPlayer) { [ `

    ${aug.name}


    `, `Cost: ${renderToStaticMarkup(Money(aug.startingCost))}

    `, - `${aug.info}` + `${aug.info}`, ].join(" "), padding: "2px", clickListener: () => { @@ -101,7 +100,7 @@ export function createSleevePurchaseAugsPopup(sleeve: Sleeve, p: IPlayer) { } else { dialogBoxCreate(`You cannot afford ${aug.name}`, false); } - } + }, })); popupElems.push(div); diff --git a/src/PersonObjects/Sleeve/SleeveCovenantPurchases.ts b/src/PersonObjects/Sleeve/SleeveCovenantPurchases.ts index 1ead77eeb..4ccd0a772 100644 --- a/src/PersonObjects/Sleeve/SleeveCovenantPurchases.ts +++ b/src/PersonObjects/Sleeve/SleeveCovenantPurchases.ts @@ -8,11 +8,11 @@ import { CovenantPurchasesRoot } from "./ui/CovenantPurchasesRoot"; import { createPopup, removePopup } from "../../ui/React/createPopup"; -export const MaxSleevesFromCovenant: number = 5; -export const BaseCostPerSleeve: number = 10e12; -export const PopupId: string = "covenant-sleeve-purchases-popup"; +export const MaxSleevesFromCovenant = 5; +export const BaseCostPerSleeve = 10e12; +export const PopupId = "covenant-sleeve-purchases-popup"; -export function createSleevePurchasesFromCovenantPopup(p: IPlayer) { +export function createSleevePurchasesFromCovenantPopup(p: IPlayer): void { const removePopupFn = removePopup.bind(null, PopupId); createPopup(PopupId, CovenantPurchasesRoot, { p: p, closeFn: removePopupFn }); } diff --git a/src/PersonObjects/Sleeve/SleeveUI.tsx b/src/PersonObjects/Sleeve/SleeveUI.tsx index 405a94095..8fd8d7888 100644 --- a/src/PersonObjects/Sleeve/SleeveUI.tsx +++ b/src/PersonObjects/Sleeve/SleeveUI.tsx @@ -46,7 +46,6 @@ import { ReputationRate } from "../../ui/React/ReputationRate"; import { StatsElement } from "./ui/StatsElement"; import { MoreStatsContent } from "./ui/MoreStatsContent"; import { MoreEarningsContent } from "./ui/MoreEarningsContent"; -import * as React from "react"; import * as ReactDOM from "react-dom"; import { renderToStaticMarkup } from "react-dom/server" @@ -91,7 +90,7 @@ const UIElems: IPageUIElems = { // Creates the UI for the entire Sleeves page let playerRef: IPlayer | null; -export function createSleevesPage(p: IPlayer) { +export function createSleevesPage(p: IPlayer): void { if (!routing.isOn(Page.Sleeves)) { return; } try { @@ -117,7 +116,7 @@ export function createSleevesPage(p: IPlayer) { innerText: "FAQ", clickListener: () => { dialogBoxCreate(SleeveFaq, false); - } + }, }); UIElems.docButton = createElement("a", { @@ -134,7 +133,8 @@ export function createSleevesPage(p: IPlayer) { // Create UI modules for all Sleeve for (const sleeve of p.sleeves) { const sleeveUi = createSleeveUi(sleeve, p.sleeves); - UIElems.sleeveList.appendChild(sleeveUi.container!); + if(sleeveUi.container == null) throw new Error("sleeveUi.container is null in createSleevesPage()"); + UIElems.sleeveList.appendChild(sleeveUi.container); UIElems.sleeves.push(sleeveUi); } @@ -143,28 +143,33 @@ export function createSleevesPage(p: IPlayer) { UIElems.container.appendChild(UIElems.docButton); UIElems.container.appendChild(UIElems.sleeveList); - document.getElementById("entire-game-container")!.appendChild(UIElems.container); + + const container = document.getElementById("entire-game-container"); + if(container === null) throw new Error("entire-game-container not found in createSleevesPage()"); + container.appendChild(UIElems.container); } catch(e) { exceptionAlert(e); } } // Updates the UI for the entire Sleeves page -export function updateSleevesPage() { +export function updateSleevesPage(): void { if (!routing.isOn(Page.Sleeves)) { return; } + if (playerRef === null) throw new Error("playerRef is null in updateSleevesPage()"); + if (UIElems.sleeves === null) throw new Error("UIElems.sleeves is null in updateSleevesPage()"); - try { - for (let i = 0; i < playerRef!.sleeves.length; ++i) { - const sleeve: Sleeve = playerRef!.sleeves[i]; - const elems: ISleeveUIElems = UIElems.sleeves![i]; - updateSleeveUi(sleeve!, elems!); - } - } catch(e) { - exceptionAlert(e); - } + try { + for (let i = 0; i < playerRef.sleeves.length; ++i) { + const sleeve: Sleeve = playerRef.sleeves[i]; + const elems: ISleeveUIElems = UIElems.sleeves[i]; + updateSleeveUi(sleeve, elems); + } + } catch(e) { + exceptionAlert(e); + } } -export function clearSleevesPage() { +export function clearSleevesPage(): void { if (UIElems.container instanceof HTMLElement) { removeElement(UIElems.container); } @@ -212,13 +217,13 @@ function createSleeveUi(sleeve: Sleeve, allSleeves: Sleeve[]): ISleeveUIElems { innerText: "More Stats", clickListener: () => { dialogBoxCreate(MoreStatsContent(sleeve)); - } + }, }); elems.travelButton = createElement("button", { class: "std-button", innerText: "Travel", clickListener: () => { - const popupId: string = "sleeve-travel-popup"; + const popupId = "sleeve-travel-popup"; const popupArguments: HTMLElement[] = []; popupArguments.push(createPopupCloseButton(popupId, { class: "std-button" })); popupArguments.push(createElement("p", { @@ -236,32 +241,34 @@ function createSleeveUi(sleeve: Sleeve, allSleeves: Sleeve[]): ISleeveUIElems { class: "cmpy-mgmt-find-employee-option", innerText: cityName, clickListener: () => { - if (!playerRef!.canAfford(CONSTANTS.TravelCost)) { + if(playerRef == null) throw new Error("playerRef is null in popupArguments.click()"); + if (!playerRef.canAfford(CONSTANTS.TravelCost)) { dialogBoxCreate("You cannot afford to have this sleeve travel to another city", false); return false; } sleeve.city = cityName as CityName; - playerRef!.loseMoney(CONSTANTS.TravelCost); + playerRef.loseMoney(CONSTANTS.TravelCost); sleeve.resetTaskStatus(); removeElementById(popupId); updateSleeveUi(sleeve, elems); updateSleeveTaskSelector(sleeve, elems, allSleeves); return false; - } + }, })); })(sleeve, cityName); } createPopup(popupId, popupArguments); - } + }, }); elems.purchaseAugsButton = createElement("button", { class: "std-button", display: "block", innerText: "Manage Augmentations", clickListener: () => { - createSleevePurchaseAugsPopup(sleeve, playerRef!); - } + if(playerRef == null) throw new Error("playerRef is null in purchaseAugsButton.click()"); + createSleevePurchaseAugsPopup(sleeve, playerRef); + }, }); elems.statsPanel.appendChild(elems.stats); elems.statsPanel.appendChild(elems.moreStatsButton); @@ -296,7 +303,7 @@ function createSleeveUi(sleeve: Sleeve, allSleeves: Sleeve[]): ISleeveUIElems { innerText: "Set Task", clickListener: () => { setSleeveTask(sleeve, elems); - } + }, }); elems.taskPanel.appendChild(elems.taskSelector); elems.taskPanel.appendChild(elems.taskDetailsSelector); @@ -312,7 +319,7 @@ function createSleeveUi(sleeve: Sleeve, allSleeves: Sleeve[]): ISleeveUIElems { innerText: "More Earnings Info", clickListener: () => { dialogBoxCreate(MoreEarningsContent(sleeve)); - } + }, }); elems.earningsPanel.appendChild(elems.currentEarningsInfo); @@ -328,10 +335,14 @@ function createSleeveUi(sleeve: Sleeve, allSleeves: Sleeve[]): ISleeveUIElems { } // Updates the UI for a single Sleeve -function updateSleeveUi(sleeve: Sleeve, elems: ISleeveUIElems) { +function updateSleeveUi(sleeve: Sleeve, elems: ISleeveUIElems): void { if (!routing.isOn(Page.Sleeves)) { return; } + if(playerRef == null) throw new Error("playerRef is null in updateSleeveUi()"); + if(elems.taskProgressBar == null) throw new Error("elems.taskProgressBar is null"); + if(elems.stats == null) throw new Error("elems.stats is null"); + if(elems.currentEarningsInfo == null) throw new Error("elems.currentEarningsInfo is null"); - ReactDOM.render(StatsElement(sleeve), elems.stats!); + ReactDOM.render(StatsElement(sleeve), elems.stats); if (sleeve.currentTask === SleeveTaskType.Crime) { const data = [ @@ -341,11 +352,11 @@ function updateSleeveUi(sleeve: Sleeve, elems: ISleeveUIElems) { [`Defense Exp`, numeralWrapper.formatExp(sleeve.gainRatesForTask.def), `(2x on success)`], [`Dexterity Exp`, numeralWrapper.formatExp(sleeve.gainRatesForTask.dex), `(2x on success)`], [`Agility Exp`, numeralWrapper.formatExp(sleeve.gainRatesForTask.agi), `(2x on success)`], - [`Charisma Exp`, numeralWrapper.formatExp(sleeve.gainRatesForTask.cha), `(2x on success)`] + [`Charisma Exp`, numeralWrapper.formatExp(sleeve.gainRatesForTask.cha), `(2x on success)`], ]; - ReactDOM.render(EarningsTableElement('Earnings (Pre-Synchronization)', data), elems.currentEarningsInfo!) + ReactDOM.render(EarningsTableElement('Earnings (Pre-Synchronization)', data), elems.currentEarningsInfo) - elems.taskProgressBar!.innerText = createProgressBarText({ + elems.taskProgressBar.innerText = createProgressBarText({ progress: sleeve.currentTaskTime / sleeve.currentTaskMaxTime, totalTicks: 25, }); @@ -357,16 +368,15 @@ function updateSleeveUi(sleeve: Sleeve, elems: ISleeveUIElems) { [`Defense Exp:`, `${numeralWrapper.formatExp(5 * sleeve.gainRatesForTask.def)} / s`], [`Dexterity Exp:`, `${numeralWrapper.formatExp(5 * sleeve.gainRatesForTask.dex)} / s`], [`Agility Exp:`, `${numeralWrapper.formatExp(5 * sleeve.gainRatesForTask.agi)} / s`], - [`Charisma Exp:`, `${numeralWrapper.formatExp(5 * sleeve.gainRatesForTask.cha)} / s`] + [`Charisma Exp:`, `${numeralWrapper.formatExp(5 * sleeve.gainRatesForTask.cha)} / s`], ]; - let repGainText: string = ""; if (sleeve.currentTask === SleeveTaskType.Company || sleeve.currentTask === SleeveTaskType.Faction) { - const repGain: number = sleeve.getRepGain(playerRef!); + const repGain: number = sleeve.getRepGain(playerRef); data.push([`Reputation:`, ReputationRate(5 * repGain)]); } - ReactDOM.render(EarningsTableElement('Earnings (Pre-Synchronization)', data), elems.currentEarningsInfo!) + ReactDOM.render(EarningsTableElement('Earnings (Pre-Synchronization)', data), elems.currentEarningsInfo) - elems.taskProgressBar!.innerText = ""; + elems.taskProgressBar.innerText = ""; } } @@ -376,18 +386,18 @@ const universitySelectorOptions: string[] = [ "Networks", "Algorithms", "Management", - "Leadership" + "Leadership", ]; const gymSelectorOptions: string[] = [ "Train Strength", "Train Defense", "Train Dexterity", - "Train Agility" + "Train Agility", ]; // Whenever a new task is selected, the "details" selector must update accordingly -function updateSleeveTaskSelector(sleeve: Sleeve, elems: ISleeveUIElems, allSleeves: Sleeve[]) { +function updateSleeveTaskSelector(sleeve: Sleeve, elems: ISleeveUIElems, allSleeves: Sleeve[]): void { if (playerRef == null) { throw new Error(`playerRef is null in updateSleeveTaskSelector()`); } @@ -410,41 +420,50 @@ function updateSleeveTaskSelector(sleeve: Sleeve, elems: ISleeveUIElems, allSlee } } + if(elems.taskDetailsSelector === null) { + throw new Error("elems.taskDetailsSelector is null"); + } + if(elems.taskDetailsSelector2 === null) { + throw new Error("elems.taskDetailsSelector is null"); + } + + + // Reset Selectors removeChildrenFromElement(elems.taskDetailsSelector); removeChildrenFromElement(elems.taskDetailsSelector2); - elems.taskDetailsSelector2 = clearEventListeners(elems.taskDetailsSelector2!) as HTMLSelectElement; + elems.taskDetailsSelector2 = clearEventListeners(elems.taskDetailsSelector2) as HTMLSelectElement; const value: string = getSelectValue(elems.taskSelector); switch(value) { - case "Work for Company": - let companyCount: number = 0; - const allJobs: string[] = Object.keys(playerRef!.jobs!); + case "Work for Company": { + let companyCount = 0; + const allJobs: string[] = Object.keys(playerRef.jobs); for (let i = 0; i < allJobs.length; ++i) { if (!forbiddenCompanies.includes(allJobs[i])) { - elems.taskDetailsSelector!.add(createOptionElement(allJobs[i])); + elems.taskDetailsSelector.add(createOptionElement(allJobs[i])); // Set initial value of the 'Details' selector if (sleeve.currentTaskLocation === allJobs[i]) { - elems.taskDetailsSelector!.selectedIndex = companyCount; + elems.taskDetailsSelector.selectedIndex = companyCount; } ++companyCount; } - elems.taskDetailsSelector2!.add(createOptionElement("------")); + elems.taskDetailsSelector2.add(createOptionElement("------")); } break; - case "Work for Faction": - let factionCount: number = 0; - for (let i = 0; i < playerRef!.factions!.length; ++i) { - const fac: string = playerRef!.factions[i]!; + } + case "Work for Faction": { + let factionCount = 0; + for (const fac of playerRef.factions) { if (!forbiddenFactions.includes(fac)) { - elems.taskDetailsSelector!.add(createOptionElement(fac)); + elems.taskDetailsSelector.add(createOptionElement(fac)); // Set initial value of the 'Details' Selector if (sleeve.currentTaskLocation === fac) { - elems.taskDetailsSelector!.selectedIndex = factionCount; + elems.taskDetailsSelector.selectedIndex = factionCount; } ++factionCount; @@ -452,94 +471,98 @@ function updateSleeveTaskSelector(sleeve: Sleeve, elems: ISleeveUIElems, allSlee } // The available faction work types depends on the faction - elems.taskDetailsSelector!.addEventListener("change", () => { - const facName = getSelectValue(elems.taskDetailsSelector!); + elems.taskDetailsSelector.addEventListener("change", () => { + if(elems.taskDetailsSelector2 === null) + throw new Error("elems.taskDetailsSelector2 is null"); + const facName = getSelectValue(elems.taskDetailsSelector); const faction: Faction | null = Factions[facName]; if (faction == null) { console.warn(`Invalid faction name when trying to update Sleeve Task Selector: ${facName}`); return; } const facInfo = faction.getInfo(); - removeChildrenFromElement(elems.taskDetailsSelector2!); + removeChildrenFromElement(elems.taskDetailsSelector2); let numOptionsAdded = 0; if (facInfo.offerHackingWork) { - elems.taskDetailsSelector2!.add(createOptionElement("Hacking Contracts")); + elems.taskDetailsSelector2.add(createOptionElement("Hacking Contracts")); if (sleeve.factionWorkType === FactionWorkType.Hacking) { - elems.taskDetailsSelector2!.selectedIndex = numOptionsAdded; + elems.taskDetailsSelector2.selectedIndex = numOptionsAdded; } ++numOptionsAdded; } if (facInfo.offerFieldWork) { - elems.taskDetailsSelector2!.add(createOptionElement("Field Work")); + elems.taskDetailsSelector2.add(createOptionElement("Field Work")); if (sleeve.factionWorkType === FactionWorkType.Field) { - elems.taskDetailsSelector2!.selectedIndex = numOptionsAdded; + elems.taskDetailsSelector2.selectedIndex = numOptionsAdded; } ++numOptionsAdded; } if (facInfo.offerSecurityWork) { - elems.taskDetailsSelector2!.add(createOptionElement("Security Work")); + elems.taskDetailsSelector2.add(createOptionElement("Security Work")); if (sleeve.factionWorkType === FactionWorkType.Security) { - elems.taskDetailsSelector2!.selectedIndex = numOptionsAdded; + elems.taskDetailsSelector2.selectedIndex = numOptionsAdded; } ++numOptionsAdded; } }); - elems.taskDetailsSelector!.dispatchEvent(new Event("change")); + elems.taskDetailsSelector.dispatchEvent(new Event("change")); break; - case "Commit Crime": + } + case "Commit Crime": { let i = 0; for (const crimeLabel in Crimes) { const name: string = Crimes[crimeLabel].name; - elems.taskDetailsSelector!.add(createOptionElement(name, crimeLabel)); + elems.taskDetailsSelector.add(createOptionElement(name, crimeLabel)); // Set initial value for crime type if (sleeve.crimeType === "") { continue; } const crime: Crime | null = Crimes[sleeve.crimeType]; - if (crime == null) { continue; } - if (name === crime!.name) { - elems.taskDetailsSelector!.selectedIndex = i; + if (crime === null) { continue; } + if (name === crime.name) { + elems.taskDetailsSelector.selectedIndex = i; } ++i; } - elems.taskDetailsSelector2!.add(createOptionElement("------")); + elems.taskDetailsSelector2.add(createOptionElement("------")); break; + } case "Take University Course": // First selector has class type for (let i = 0; i < universitySelectorOptions.length; ++i) { - elems.taskDetailsSelector!.add(createOptionElement(universitySelectorOptions[i])); + elems.taskDetailsSelector.add(createOptionElement(universitySelectorOptions[i])); // Set initial value if (sleeve.className === universitySelectorOptions[i]) { - elems.taskDetailsSelector!.selectedIndex = i; + elems.taskDetailsSelector.selectedIndex = i; } } // Second selector has which university switch (sleeve.city) { case CityName.Aevum: - elems.taskDetailsSelector2!.add(createOptionElement(LocationName.AevumSummitUniversity)); + elems.taskDetailsSelector2.add(createOptionElement(LocationName.AevumSummitUniversity)); break; case CityName.Sector12: - elems.taskDetailsSelector2!.add(createOptionElement(LocationName.Sector12RothmanUniversity)); + elems.taskDetailsSelector2.add(createOptionElement(LocationName.Sector12RothmanUniversity)); break; case CityName.Volhaven: - elems.taskDetailsSelector2!.add(createOptionElement(LocationName.VolhavenZBInstituteOfTechnology)); + elems.taskDetailsSelector2.add(createOptionElement(LocationName.VolhavenZBInstituteOfTechnology)); break; default: - elems.taskDetailsSelector2!.add(createOptionElement("No university available in city!")); + elems.taskDetailsSelector2.add(createOptionElement("No university available in city!")); break; } break; case "Workout at Gym": // First selector has what stat is being trained for (let i = 0; i < gymSelectorOptions.length; ++i) { - elems.taskDetailsSelector!.add(createOptionElement(gymSelectorOptions[i])); + elems.taskDetailsSelector.add(createOptionElement(gymSelectorOptions[i])); // Set initial value if (sleeve.gymStatType === gymSelectorOptions[i]) { - elems.taskDetailsSelector!.selectedIndex = i; + elems.taskDetailsSelector.selectedIndex = i; } } @@ -547,32 +570,32 @@ function updateSleeveTaskSelector(sleeve: Sleeve, elems: ISleeveUIElems, allSlee // In this switch statement we also set the initial value of the second selector switch (sleeve.city) { case CityName.Aevum: - elems.taskDetailsSelector2!.add(createOptionElement(LocationName.AevumCrushFitnessGym)); - elems.taskDetailsSelector2!.add(createOptionElement(LocationName.AevumSnapFitnessGym)); + elems.taskDetailsSelector2.add(createOptionElement(LocationName.AevumCrushFitnessGym)); + elems.taskDetailsSelector2.add(createOptionElement(LocationName.AevumSnapFitnessGym)); // Set initial value if (sleeve.currentTaskLocation === LocationName.AevumCrushFitnessGym) { - elems.taskDetailsSelector2!.selectedIndex = 0; + elems.taskDetailsSelector2.selectedIndex = 0; } else if (sleeve.currentTaskLocation === LocationName.AevumSnapFitnessGym) { - elems.taskDetailsSelector2!.selectedIndex = 1; + elems.taskDetailsSelector2.selectedIndex = 1; } break; case CityName.Sector12: - elems.taskDetailsSelector2!.add(createOptionElement(LocationName.Sector12IronGym)); - elems.taskDetailsSelector2!.add(createOptionElement(LocationName.Sector12PowerhouseGym)); + elems.taskDetailsSelector2.add(createOptionElement(LocationName.Sector12IronGym)); + elems.taskDetailsSelector2.add(createOptionElement(LocationName.Sector12PowerhouseGym)); // Set initial value if (sleeve.currentTaskLocation === LocationName.Sector12IronGym) { - elems.taskDetailsSelector2!.selectedIndex = 0; + elems.taskDetailsSelector2.selectedIndex = 0; } else if (sleeve.currentTaskLocation === LocationName.Sector12PowerhouseGym) { - elems.taskDetailsSelector2!.selectedIndex = 1; + elems.taskDetailsSelector2.selectedIndex = 1; } break; case CityName.Volhaven: - elems.taskDetailsSelector2!.add(createOptionElement(LocationName.VolhavenMilleniumFitnessGym)); + elems.taskDetailsSelector2.add(createOptionElement(LocationName.VolhavenMilleniumFitnessGym)); break; default: - elems.taskDetailsSelector2!.add(createOptionElement("No gym available in city!")); + elems.taskDetailsSelector2.add(createOptionElement("No gym available in city!")); break; } @@ -581,8 +604,8 @@ function updateSleeveTaskSelector(sleeve: Sleeve, elems: ISleeveUIElems, allSlee case "Synchronize": case "------": // No options in "Details" selector - elems.taskDetailsSelector!.add(createOptionElement("------")); - elems.taskDetailsSelector2!.add(createOptionElement("------")); + elems.taskDetailsSelector.add(createOptionElement("------")); + elems.taskDetailsSelector2.add(createOptionElement("------")); return; default: break; @@ -594,37 +617,38 @@ function setSleeveTask(sleeve: Sleeve, elems: ISleeveUIElems): boolean { if (playerRef == null) { throw new Error("playerRef is null in Sleeve UI's setSleeveTask()"); } + if(elems.taskDescription == null) throw new Error("elems.taskDescription is null"); const taskValue: string = getSelectValue(elems.taskSelector); const detailValue: string = getSelectValue(elems.taskDetailsSelector); const detailValue2: string = getSelectValue(elems.taskDetailsSelector2); - let res: boolean = false; + let res = false; switch(taskValue) { case "------": - elems.taskDescription!.innerText = "This sleeve is currently idle"; + elems.taskDescription.innerText = "This sleeve is currently idle"; break; case "Work for Company": - res = sleeve.workForCompany(playerRef!, detailValue); + res = sleeve.workForCompany(playerRef, detailValue); break; case "Work for Faction": - res = sleeve.workForFaction(playerRef!, detailValue, detailValue2); + res = sleeve.workForFaction(playerRef, detailValue, detailValue2); break; case "Commit Crime": - res = sleeve.commitCrime(playerRef!, detailValue); + res = sleeve.commitCrime(playerRef, detailValue); break; case "Take University Course": - res = sleeve.takeUniversityCourse(playerRef!, detailValue2, detailValue); + res = sleeve.takeUniversityCourse(playerRef, detailValue2, detailValue); break; case "Workout at Gym": - res = sleeve.workoutAtGym(playerRef!, detailValue2, detailValue); + res = sleeve.workoutAtGym(playerRef, detailValue2, detailValue); break; case "Shock Recovery": sleeve.currentTask = SleeveTaskType.Recovery; - res = sleeve.shockRecovery(playerRef!); + res = sleeve.shockRecovery(playerRef); break; case "Synchronize": - res = sleeve.synchronize(playerRef!); + res = sleeve.synchronize(playerRef); break; default: console.error(`Invalid/Unrecognized taskValue in setSleeveTask(): ${taskValue}`); @@ -635,10 +659,10 @@ function setSleeveTask(sleeve: Sleeve, elems: ISleeveUIElems): boolean { } else { switch (taskValue) { case "Work for Faction": - elems.taskDescription!.innerText = "Failed to assign sleeve to task. This is most likely because the selected faction does not offer the selected work type."; + elems.taskDescription.innerText = "Failed to assign sleeve to task. This is most likely because the selected faction does not offer the selected work type."; break; default: - elems.taskDescription!.innerText = "Failed to assign sleeve to task. Invalid choice(s)."; + elems.taskDescription.innerText = "Failed to assign sleeve to task. Invalid choice(s)."; break; } @@ -648,8 +672,10 @@ function setSleeveTask(sleeve: Sleeve, elems: ISleeveUIElems): boolean { updateSleevesPage(); // Update the task selector for all sleeves by triggering a change event - for (const e of UIElems.sleeves!) { - e.taskSelector!.dispatchEvent(new Event('change')); + if(UIElems.sleeves == null) throw new Error("UIElems.sleeves is null"); + for (const e of UIElems.sleeves) { + if(e.taskSelector == null) throw new Error("e.taskSelector is null"); + e.taskSelector.dispatchEvent(new Event('change')); } } @@ -670,32 +696,33 @@ function updateSleeveTaskDescription(sleeve: Sleeve, elems: ISleeveUIElems): voi const taskValue: string = getSelectValue(elems.taskSelector); const detailValue: string = getSelectValue(elems.taskDetailsSelector); const detailValue2: string = getSelectValue(elems.taskDetailsSelector2); + if(elems.taskDescription == null) throw new Error("elems.taskDescription should not be null") switch(taskValue) { case "------": - elems.taskDescription!.innerText = "This sleeve is currently idle"; + elems.taskDescription.innerText = "This sleeve is currently idle"; break; case "Work for Company": - elems.taskDescription!.innerText = `This sleeve is currently working your job at ${sleeve.currentTaskLocation}.`; + elems.taskDescription.innerText = `This sleeve is currently working your job at ${sleeve.currentTaskLocation}.`; break; case "Work for Faction": - elems.taskDescription!.innerText = `This sleeve is currently doing ${detailValue2} for ${sleeve.currentTaskLocation}.`; + elems.taskDescription.innerText = `This sleeve is currently doing ${detailValue2} for ${sleeve.currentTaskLocation}.`; break; case "Commit Crime": - elems.taskDescription!.innerText = `This sleeve is currently attempting to ${Crimes[detailValue].type} (Success Rate: ${numeralWrapper.formatPercentage(Crimes[detailValue].successRate(sleeve))}).`; + elems.taskDescription.innerText = `This sleeve is currently attempting to ${Crimes[detailValue].type} (Success Rate: ${numeralWrapper.formatPercentage(Crimes[detailValue].successRate(sleeve))}).`; break; case "Take University Course": - elems.taskDescription!.innerText = `This sleeve is currently studying/taking a course at ${sleeve.currentTaskLocation}.`; + elems.taskDescription.innerText = `This sleeve is currently studying/taking a course at ${sleeve.currentTaskLocation}.`; break; case "Workout at Gym": - elems.taskDescription!.innerText = `This sleeve is currently working out at ${sleeve.currentTaskLocation}.`; + elems.taskDescription.innerText = `This sleeve is currently working out at ${sleeve.currentTaskLocation}.`; break; case "Shock Recovery": - elems.taskDescription!.innerText = "This sleeve is currently set to focus on shock recovery. This causes " + + elems.taskDescription.innerText = "This sleeve is currently set to focus on shock recovery. This causes " + "the Sleeve's shock to decrease at a faster rate."; break; case "Synchronize": - elems.taskDescription!.innerText = "This sleeve is currently set to synchronize with the original consciousness. " + + elems.taskDescription.innerText = "This sleeve is currently set to synchronize with the original consciousness. " + "This causes the Sleeve's synchronization to increase." break; default: diff --git a/src/PersonObjects/Sleeve/ui/CovenantPurchasesRoot.tsx b/src/PersonObjects/Sleeve/ui/CovenantPurchasesRoot.tsx index 1a5c707ae..cfe8d9801 100644 --- a/src/PersonObjects/Sleeve/ui/CovenantPurchasesRoot.tsx +++ b/src/PersonObjects/Sleeve/ui/CovenantPurchasesRoot.tsx @@ -12,8 +12,6 @@ import { BaseCostPerSleeve, PopupId } from "../SleeveCovenantPurchases"; import { IPlayer } from "../../IPlayer"; -import { numeralWrapper } from "../../../ui/numeralFormat"; - import { PopupCloseButton } from "../../../ui/React/PopupCloseButton"; import { StdButton } from "../../../ui/React/StdButton"; import { Money } from "../../../ui/React/Money"; @@ -51,13 +49,13 @@ export class CovenantPurchasesRoot extends React.Component { /** * Force a rerender by just changing an arbitrary state value */ - rerender() { + rerender(): void { this.setState((state: IState) => ({ update: state.update + 1, })); } - render() { + render(): React.ReactNode { // Purchasing a new Duplicate Sleeve let purchaseDisabled = false; if (!this.props.p.canAfford(this.purchaseCost())) { @@ -66,7 +64,7 @@ export class CovenantPurchasesRoot extends React.Component { if (this.props.p.sleevesFromCovenant >= MaxSleevesFromCovenant) { purchaseDisabled = true; } - const purchaseOnClick = () => { + const purchaseOnClick = (): void => { if (this.props.p.sleevesFromCovenant >= MaxSleevesFromCovenant) { return; } if (this.props.p.canAfford(this.purchaseCost())) { @@ -84,7 +82,7 @@ export class CovenantPurchasesRoot extends React.Component { for (let i = 0; i < this.props.p.sleeves.length; ++i) { const sleeve = this.props.p.sleeves[i]; upgradePanels.push( - + , ) } diff --git a/src/PersonObjects/Sleeve/ui/CovenantSleeveMemoryUpgrade.tsx b/src/PersonObjects/Sleeve/ui/CovenantSleeveMemoryUpgrade.tsx index 5424e8bff..37fed827c 100644 --- a/src/PersonObjects/Sleeve/ui/CovenantSleeveMemoryUpgrade.tsx +++ b/src/PersonObjects/Sleeve/ui/CovenantSleeveMemoryUpgrade.tsx @@ -60,7 +60,7 @@ export class CovenantSleeveMemoryUpgrade extends React.Component } } - render() { + render(): React.ReactNode { const inputId = `sleeve-${this.props.index}-memory-upgrade-input`; // Memory cannot go above 100 @@ -83,7 +83,7 @@ export class CovenantSleeveMemoryUpgrade extends React.Component

    Upgrade Memory

    Purchase a memory upgrade for your sleeve. Note that a sleeve's max memory - is 100 (current: {numeralWrapper.formatMemory(this.props.sleeve.memory)}) + is 100 (current: {numeralWrapper.formatSleeveMemory(this.props.sleeve.memory)})

  • void; + cancelOrder: (params: any) => void; order: Order; } @@ -21,11 +21,11 @@ export class StockTickerOrder extends React.Component { this.handleCancelOrderClick = this.handleCancelOrderClick.bind(this); } - handleCancelOrderClick() { + handleCancelOrderClick(): void { this.props.cancelOrder({ order: this.props.order }); } - render() { + render(): React.ReactNode { const order = this.props.order; const posTxt = order.pos === PositionTypes.Long ? "Long Position" : "Short Position"; diff --git a/src/StockMarket/ui/StockTickerOrderList.tsx b/src/StockMarket/ui/StockTickerOrderList.tsx index beb21f940..77f239fb4 100644 --- a/src/StockMarket/ui/StockTickerOrderList.tsx +++ b/src/StockMarket/ui/StockTickerOrderList.tsx @@ -12,14 +12,14 @@ import { Stock } from "../Stock"; import { IPlayer } from "../../PersonObjects/IPlayer"; type IProps = { - cancelOrder: (params: object) => void; + cancelOrder: (params: any) => void; orders: Order[]; p: IPlayer; stock: Stock; } export class StockTickerOrderList extends React.Component { - render() { + render(): React.ReactNode { const orders: React.ReactElement[] = []; for (let i = 0; i < this.props.orders.length; ++i) { const o = this.props.orders[i]; diff --git a/src/StockMarket/ui/StockTickerPositionText.tsx b/src/StockMarket/ui/StockTickerPositionText.tsx index 282965ce2..dbb1977aa 100644 --- a/src/StockMarket/ui/StockTickerPositionText.tsx +++ b/src/StockMarket/ui/StockTickerPositionText.tsx @@ -87,7 +87,7 @@ export class StockTickerPositionText extends React.Component { } } - render() { + render(): React.ReactNode { const stock = this.props.stock; return ( diff --git a/src/StockMarket/ui/StockTickerTxButton.tsx b/src/StockMarket/ui/StockTickerTxButton.tsx index 927320a4e..00fadb6b6 100644 --- a/src/StockMarket/ui/StockTickerTxButton.tsx +++ b/src/StockMarket/ui/StockTickerTxButton.tsx @@ -10,10 +10,6 @@ type IProps = { tooltip?: JSX.Element | null; } -type IInnerHTMLMarkup = { - __html: string; -} - export function StockTickerTxButton(props: IProps): React.ReactElement { let className = "stock-market-input std-button"; @@ -26,8 +22,8 @@ export function StockTickerTxButton(props: IProps): React.ReactElement { ) diff --git a/src/StockMarket/ui/StockTickers.tsx b/src/StockMarket/ui/StockTickers.tsx index 1771b7679..130c09b67 100644 --- a/src/StockMarket/ui/StockTickers.tsx +++ b/src/StockMarket/ui/StockTickers.tsx @@ -24,7 +24,7 @@ export type placeOrderFn = (stock: Stock, shares: number, price: number, ordType type IProps = { buyStockLong: txFn; buyStockShort: txFn; - cancelOrder: (params: object) => void; + cancelOrder: (params: any) => void; eventEmitterForReset?: EventEmitter; p: IPlayer; placeOrder: placeOrderFn; @@ -62,7 +62,7 @@ export class StockTickers extends React.Component { this.listRef = React.createRef(); } - changeDisplayMode() { + changeDisplayMode(): void { if (this.state.tickerDisplayMode === TickerDisplayMode.AllStocks) { this.setState({ tickerDisplayMode: TickerDisplayMode.Portfolio, @@ -74,7 +74,7 @@ export class StockTickers extends React.Component { } } - changeWatchlistFilter(e: React.ChangeEvent) { + changeWatchlistFilter(e: React.ChangeEvent): void { const watchlist = e.target.value; const sanitizedWatchlist = watchlist.replace(/\s/g, ''); @@ -93,7 +93,7 @@ export class StockTickers extends React.Component { } } - collapseAllTickers() { + collapseAllTickers(): void { const ul = this.listRef.current; if (ul == null) { return; } const tickers = ul.getElementsByClassName("accordion-header"); @@ -109,7 +109,7 @@ export class StockTickers extends React.Component { } } - expandAllTickers() { + expandAllTickers(): void { const ul = this.listRef.current; if (ul == null) { return; } const tickers = ul.getElementsByClassName("accordion-header"); @@ -125,7 +125,7 @@ export class StockTickers extends React.Component { } } - rerender() { + rerender(): void { this.setState((prevState) => { return { rerenderFlag: !prevState.rerenderFlag, @@ -133,7 +133,7 @@ export class StockTickers extends React.Component { }); } - render() { + render(): React.ReactNode { const tickers: React.ReactElement[] = []; for (const stockMarketProp in this.props.stockMarket) { const val = this.props.stockMarket[stockMarketProp]; @@ -168,7 +168,7 @@ export class StockTickers extends React.Component { sellStockLong={this.props.sellStockLong} sellStockShort={this.props.sellStockShort} stock={val} - /> + />, ) } } diff --git a/src/StockMarket/ui/StockTickersConfig.tsx b/src/StockMarket/ui/StockTickersConfig.tsx index 115da22b8..d4c3144b4 100644 --- a/src/StockMarket/ui/StockTickersConfig.tsx +++ b/src/StockMarket/ui/StockTickersConfig.tsx @@ -25,9 +25,9 @@ export class StockTickersConfig extends React.Component { super(props); } - renderDisplayModeButton() { - let txt: string = ""; - let tooltip: string = ""; + renderDisplayModeButton(): React.ReactNode { + let txt = ""; + let tooltip = ""; if (this.props.tickerDisplayMode === TickerDisplayMode.Portfolio) { txt = "Switch to 'All Stocks' Mode"; tooltip = "Displays all stocks on the WSE"; @@ -45,7 +45,7 @@ export class StockTickersConfig extends React.Component { ) } - render() { + render(): React.ReactNode { return (
    {this.renderDisplayModeButton()} diff --git a/src/Terminal.jsx b/src/Terminal.jsx index cfe596851..20ea87ef4 100644 --- a/src/Terminal.jsx +++ b/src/Terminal.jsx @@ -4,37 +4,30 @@ import { getFirstParentDirectory, isInRootDirectory, isValidDirectoryPath, - isValidFilename, removeLeadingSlash, - removeTrailingSlash + removeTrailingSlash, } from "./Terminal/DirectoryHelpers"; import { determineAllPossibilitiesForTabCompletion } from "./Terminal/determineAllPossibilitiesForTabCompletion"; import { TerminalHelpText, HelpTexts } from "./Terminal/HelpText"; import { tabCompletion } from "./Terminal/tabCompletion"; import { - Aliases, - GlobalAliases, parseAliasDeclaration, printAliases, removeAlias, - substituteAliases + substituteAliases, } from "./Alias"; import { BitNodeMultipliers } from "./BitNode/BitNodeMultipliers"; import { - CodingContract, CodingContractResult, - CodingContractRewardType } from "./CodingContracts"; import { CONSTANTS } from "./Constants"; import { Programs } from "./Programs/Programs"; import { executeDarkwebTerminalCommand, - checkIfConnectedToDarkweb + checkIfConnectedToDarkweb, } from "./DarkWeb/DarkWeb"; -import { DarkWebItems } from "./DarkWeb/DarkWebItems"; import { Engine } from "./engine"; -import { parseFconfSettings, createFconf } from "./Fconf/Fconf"; import { FconfSettings } from "./Fconf/FconfSettings"; import { calculateHackingChance, @@ -42,13 +35,13 @@ import { calculatePercentMoneyHacked, calculateHackingTime, calculateGrowTime, - calculateWeakenTime + calculateWeakenTime, } from "./Hacking"; import { HacknetServer } from "./Hacknet/HacknetServer"; import { iTutorialNextStep, iTutorialSteps, - ITutorial + ITutorial, } from "./InteractiveTutorial"; import { showLiterature } from "./Literature/LiteratureHelpers"; import { Message } from "./Message/Message"; @@ -63,24 +56,19 @@ import { getRamUsageFromRunningScript } from "./Script/RunningScriptHelpers"; import { getCurrentEditor, findRunningScript } from "./Script/ScriptHelpers"; import { isScriptFilename } from "./Script/ScriptHelpersTS"; import { AllServers } from "./Server/AllServers"; -import { Server } from "./Server/Server"; import { GetServerByHostname, getServer, - getServerOnNetwork + getServerOnNetwork, } from "./Server/ServerHelpers"; -import { Settings } from "./Settings/Settings"; import { SpecialServerIps, - SpecialServerNames + SpecialServerNames, } from "./Server/SpecialServerIps"; -import { getTextFile } from "./TextFile"; import { setTimeoutRef } from "./utils/SetTimeoutRef"; import { Page, routing } from "./ui/navigationTracking"; import { numeralWrapper } from "./ui/numeralFormat"; import { KEY } from "../utils/helpers/keyCodes"; -import { addOffset } from "../utils/helpers/addOffset"; -import { isString } from "../utils/helpers/isString"; import { arrayToString } from "../utils/helpers/arrayToString"; import { getTimestamp } from "../utils/helpers/getTimestamp"; import { logBoxCreate } from "../utils/LogBox"; @@ -88,7 +76,7 @@ import { yesNoBoxCreate, yesNoBoxGetYesButton, yesNoBoxGetNoButton, - yesNoBoxClose + yesNoBoxClose, } from "../utils/YesNoBox"; import { post, @@ -96,7 +84,7 @@ import { postContent, postError, hackProgressBarPost, - hackProgressPost + hackProgressPost, } from "./ui/postToTerminal"; import { convertTimeMsToTimeElapsedString } from "../utils/StringHelperFunctions"; import { Money } from "./ui/React/Money"; @@ -136,7 +124,7 @@ $(document).keydown(function(event) { "[" + (FconfSettings.ENABLE_TIMESTAMPS ? getTimestamp() + " " : "") + Player.getCurrentServer().hostname + - ` ~${dir}]> ${command}` + ` ~${dir}]> ${command}`, ); if (command.length > 0) { @@ -393,7 +381,6 @@ let Terminal = { var inputLength = terminalInput.value.length; var start = terminalInput.selectionStart; - var end = terminalInput.selectionEnd; var inputText = terminalInput.value; switch(mod.toLowerCase()) { @@ -436,7 +423,6 @@ let Terminal = { var inputLength = terminalInput.value.length; var start = terminalInput.selectionStart; - var end = terminalInput.selectionEnd; switch(loc.toLowerCase()) { case "home": @@ -1543,7 +1529,7 @@ let Terminal = { spacesPid, script.threads, spacesThread, - ramUsage + ramUsage, ].join(""); post(entry); } @@ -1778,7 +1764,6 @@ let Terminal = { return; } - const s = Player.getCurrentServer(); const scriptName = commandArray[1]; let numThreads = 1; if (commandArray.length === 4 && commandArray[2] === "-t") { @@ -1960,7 +1945,6 @@ let Terminal = { postError(`Invalid destination. ${commandArray[2]} not found`); return; } - const ip = destServer.ip; const currServ = Player.getCurrentServer(); // Scp for lit files diff --git a/src/Terminal/DirectoryHelpers.ts b/src/Terminal/DirectoryHelpers.ts index 0a3692e54..700e72b3f 100644 --- a/src/Terminal/DirectoryHelpers.ts +++ b/src/Terminal/DirectoryHelpers.ts @@ -99,7 +99,7 @@ export function isValidDirectoryPath(path: string): boolean { */ export function isValidFilePath(path: string): boolean { if (path == null || typeof path !== "string") { return false; } - let t_path = path; + const t_path = path; // Impossible for filename to have less than length of 3 if (t_path.length < 3) { return false; } @@ -132,7 +132,7 @@ export function getFirstParentDirectory(path: string): string { if (t_path.lastIndexOf("/") === -1) { return "/"; } - let dirs = t_path.split("/"); + const dirs = t_path.split("/"); if (dirs.length === 0) { return "/"; } return dirs[0] + "/"; @@ -146,7 +146,7 @@ export function getFirstParentDirectory(path: string): string { * If there are no parent directories, it returns the empty string */ export function getAllParentDirectories(path: string): string { - let t_path = path; + const t_path = path; const lastSlash = t_path.lastIndexOf("/"); if (lastSlash === -1) { return ""; } diff --git a/src/Terminal/DirectoryServerHelpers.ts b/src/Terminal/DirectoryServerHelpers.ts index 69a77f89f..8757e7066 100644 --- a/src/Terminal/DirectoryServerHelpers.ts +++ b/src/Terminal/DirectoryServerHelpers.ts @@ -26,7 +26,7 @@ export function getSubdirectories(serv: BaseServer, dir: string): string[] { let t_dir = dir; if (!t_dir.endsWith("/")) { t_dir += "/"; } - function processFile(fn: string) { + function processFile(fn: string): void { if (t_dir === "/" && isInRootDirectory(fn)) { const subdir = getFirstParentDirectory(fn); if (subdir !== "/" && !res.includes(subdir)) { diff --git a/src/Terminal/determineAllPossibilitiesForTabCompletion.ts b/src/Terminal/determineAllPossibilitiesForTabCompletion.ts index 2753c5267..ffe356cf4 100644 --- a/src/Terminal/determineAllPossibilitiesForTabCompletion.ts +++ b/src/Terminal/determineAllPossibilitiesForTabCompletion.ts @@ -6,7 +6,7 @@ import { getSubdirectories } from "./DirectoryServerHelpers"; import { Aliases, - GlobalAliases + GlobalAliases, } from "../Alias"; import { DarkWebItems } from "../DarkWeb/DarkWebItems"; import { Message } from "../Message/Message"; @@ -48,26 +48,26 @@ const commands = [ "sudov", "tail", "theme", - "top" + "top", ]; -export function determineAllPossibilitiesForTabCompletion(p: IPlayer, input: string, index: number, currPath: string=""): string[] { +export function determineAllPossibilitiesForTabCompletion(p: IPlayer, input: string, index: number, currPath=""): string[] { let allPos: string[] = []; allPos = allPos.concat(Object.keys(GlobalAliases)); const currServ = p.getCurrentServer(); const homeComputer = p.getHomeComputer(); - let parentDirPath: string = ""; + let parentDirPath = ""; let evaledParentDirPath: string | null = null; // Helper functions - function addAllCodingContracts() { + function addAllCodingContracts(): void { for (const cct of currServ.contracts) { allPos.push(cct.fn); } } - function addAllLitFiles() { + function addAllLitFiles(): void { for (const file of currServ.messages) { if (!(file instanceof Message)) { allPos.push(file); @@ -75,7 +75,7 @@ export function determineAllPossibilitiesForTabCompletion(p: IPlayer, input: str } } - function addAllMessages() { + function addAllMessages(): void { for (const file of currServ.messages) { if (file instanceof Message) { allPos.push(file.filename); @@ -83,13 +83,13 @@ export function determineAllPossibilitiesForTabCompletion(p: IPlayer, input: str } } - function addAllPrograms() { + function addAllPrograms(): void { for (const program of homeComputer.programs) { allPos.push(program); } } - function addAllScripts() { + function addAllScripts(): void { for (const script of currServ.scripts) { const res = processFilepath(script.filename); if (res) { @@ -98,7 +98,7 @@ export function determineAllPossibilitiesForTabCompletion(p: IPlayer, input: str } } - function addAllTextFiles() { + function addAllTextFiles(): void { for (const txt of currServ.textFiles) { const res = processFilepath(txt.fn); if (res) { @@ -107,7 +107,7 @@ export function determineAllPossibilitiesForTabCompletion(p: IPlayer, input: str } } - function addAllDirectories() { + function addAllDirectories(): void { // Directories are based on the currently evaluated path const subdirs = getSubdirectories(currServ, evaledParentDirPath == null ? "/" : evaledParentDirPath); @@ -157,7 +157,7 @@ export function determineAllPossibilitiesForTabCompletion(p: IPlayer, input: str return null; } - function isCommand(cmd: string) { + function isCommand(cmd: string): boolean { let t_cmd = cmd; if (!t_cmd.endsWith(" ")) { t_cmd += " "; @@ -173,12 +173,12 @@ export function determineAllPossibilitiesForTabCompletion(p: IPlayer, input: str */ if (isCommand("./") && index == -1) { //All programs and scripts - for (var i = 0; i < currServ.scripts.length; ++i) { + for (let i = 0; i < currServ.scripts.length; ++i) { allPos.push("./" + currServ.scripts[i].filename); } //Programs are on home computer - for(var i = 0; i < homeComputer.programs.length; ++i) { + for(let i = 0; i < homeComputer.programs.length; ++i) { allPos.push("./" + homeComputer.programs[i]); } return allPos; @@ -208,7 +208,7 @@ export function determineAllPossibilitiesForTabCompletion(p: IPlayer, input: str } if (isCommand("buy")) { - let options = []; + const options = []; for (const i in DarkWebItems) { const item = DarkWebItems[i] options.push(item.program); @@ -237,8 +237,8 @@ export function determineAllPossibilitiesForTabCompletion(p: IPlayer, input: str if (isCommand("connect")) { // All network connections - for (var i = 0; i < currServ.serversOnNetwork.length; ++i) { - var serv = AllServers[currServ.serversOnNetwork[i]]; + for (let i = 0; i < currServ.serversOnNetwork.length; ++i) { + const serv = AllServers[currServ.serversOnNetwork[i]]; if (serv == null) { continue; } allPos.push(serv.ip); allPos.push(serv.hostname); diff --git a/src/Terminal/tabCompletion.ts b/src/Terminal/tabCompletion.ts index 033323d2d..19b6bd479 100644 --- a/src/Terminal/tabCompletion.ts +++ b/src/Terminal/tabCompletion.ts @@ -1,10 +1,10 @@ import { - post + post, } from "../ui/postToTerminal"; import { containsAllStrings, - longestCommonStart + longestCommonStart, } from "../../utils/StringHelperFunctions"; /** diff --git a/src/TextFile.ts b/src/TextFile.ts index 0e5a6bd3e..67442d3f7 100644 --- a/src/TextFile.ts +++ b/src/TextFile.ts @@ -3,7 +3,7 @@ import { dialogBoxCreate } from "../utils/DialogBox"; import { Generic_fromJSON, Generic_toJSON, - Reviver + Reviver, } from "../utils/JSONReviver"; @@ -11,13 +11,6 @@ import { * Represents a plain text file that is typically stored on a server. */ export class TextFile { - /** - * Initiatizes a TextFile from a JSON save state. - */ - static fromJSON(value: any): TextFile { - return Generic_fromJSON(TextFile, value.data); - } - /** * The full file name. */ @@ -28,7 +21,7 @@ export class TextFile { */ text: string; - constructor(fn: string = "", txt: string = "") { + constructor(fn = "", txt = "") { this.fn = (fn.endsWith(".txt") ? fn : `${fn}.txt`).replace(/\s+/g, ""); this.text = txt; } @@ -92,6 +85,14 @@ export class TextFile { write(txt: string): void { this.text = txt; } + + /** + * Initiatizes a TextFile from a JSON save state. + */ + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types + static fromJSON(value: any): TextFile { + return Generic_fromJSON(TextFile, value.data); + } } Reviver.constructors.TextFile = TextFile; @@ -102,6 +103,7 @@ Reviver.constructors.TextFile = TextFile; * @param server The server object to look in * @returns The file object, or null if it couldn't find it. */ +// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export function getTextFile(fn: string, server: any): TextFile | null { const filename: string = !fn.endsWith(".txt") ? `${fn}.txt` : fn; @@ -121,6 +123,7 @@ export function getTextFile(fn: string, server: any): TextFile | null { * @param server The server that the file should be created on. * @returns The instance of the file. */ +// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export function createTextFile(fn: string, txt: string, server: any): TextFile | undefined { if (getTextFile(fn, server) !== null) { // This should probably be a `throw`... @@ -134,18 +137,3 @@ export function createTextFile(fn: string, txt: string, server: any): TextFile | return file; } - -/* tslint:disable-next-line:no-unused-variable */ -function deleteTextFile(fn: string, server: any): boolean { - const filename: string = !fn.endsWith(".txt") ? `${fn}.txt` : fn; - /* tslint:disable-next-line:typedef */ - for (let i = 0; i < server.textFiles.length; ++i) { - if (server.textFiles[i].fn === filename) { - server.textFiles.splice(i, 1); - - return true; - } - } - - return false; -} diff --git a/src/ThirdParty/Treant.js b/src/ThirdParty/Treant.js index d6c70e515..2ac51885a 100644 --- a/src/ThirdParty/Treant.js +++ b/src/ThirdParty/Treant.js @@ -17,7 +17,7 @@ * Dave Goodchild, https://github.com/dlgoodchild */ -;( function() { +( function() { // Polyfill for IE to use startsWith if (!String.prototype.startsWith) { String.prototype.startsWith = function(searchString, position){ @@ -161,7 +161,7 @@ + UTIL.getStyle( element, 'border-bottom-width', true ) + UTIL.getStyle( element, 'padding-top', true ) + UTIL.getStyle( element, 'padding-bottom', true ) - + nRoundingCompensation + + nRoundingCompensation, ); } }, @@ -181,7 +181,7 @@ + UTIL.getStyle( element, 'border-right-width', true ) + UTIL.getStyle( element, 'padding-left', true ) + UTIL.getStyle( element, 'padding-right', true ) - + nRoundingCompensation + + nRoundingCompensation, ); } }, @@ -195,7 +195,7 @@ strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1){ return p1.toUpperCase(); - } + }, ); strValue = element.currentStyle[strCssRule]; } @@ -332,7 +332,7 @@ */ isNotLoading: function() { return ( this.loading.length === 0 ); - } + }, }; /** @@ -392,7 +392,7 @@ this.store[treeId] = null; } return this; - } + }, }; /** @@ -513,7 +513,7 @@ function() { root.toggleCollapse(); }, - this.CONFIG.animateOnInitDelay + this.CONFIG.animateOnInitDelay, ); } @@ -531,7 +531,7 @@ setTimeout( function() { self.positionTree( callback ); - }, 10 + }, 10, ); } return this; @@ -751,7 +751,7 @@ var self = this, treeSize = { x: self.nodeDB.getMinMaxCoord('X', null, null), - y: self.nodeDB.getMinMaxCoord('Y', null, null) + y: self.nodeDB.getMinMaxCoord('Y', null, null), }, treeWidth = treeSize.x.max - treeSize.x.min, @@ -759,7 +759,7 @@ treeCenter = { x: treeSize.x.max - treeWidth/2, - y: treeSize.y.max - treeHeight/2 + y: treeSize.y.max - treeHeight/2, }; this.handleOverflow(treeWidth, treeHeight); @@ -767,7 +767,7 @@ var containerCenter = { x: self.drawArea.clientWidth/2, - y: self.drawArea.clientHeight/2 + y: self.drawArea.clientHeight/2, }, deltaX = containerCenter.x - treeCenter.x, @@ -857,7 +857,7 @@ if (jq_drawArea.hasClass('ps-container')) { // znaci da je 'fancy' vec inicijaliziran, treba updateat jq_drawArea.find('.Treant').css({ width: viewWidth, - height: viewHeight + height: viewHeight, }); jq_drawArea.perfectScrollbar('update'); @@ -868,7 +868,7 @@ child.css({ width: viewWidth, - height: viewHeight + height: viewHeight, }); mainContainer.perfectScrollbar(); @@ -948,7 +948,7 @@ { path: pathString.charAt(0) === "_"? pathString.substring(1): - pathString // remove the "_" prefix if it exists + pathString, // remove the "_" prefix if it exists }, this.CONFIG.animation.connectorsSpeed, this.CONFIG.animation.connectorsAnimation, @@ -957,7 +957,7 @@ path.hide(); path.hidden = true; } - } + }, ); return this; }, @@ -1064,7 +1064,7 @@ calcLevelDim: function( node, level ) { // root node is on level 0 this.levelMaxDim[level] = { width: Math.max( this.levelMaxDim[level]? this.levelMaxDim[level].width: 0, node.width ), - height: Math.max( this.levelMaxDim[level]? this.levelMaxDim[level].height: 0, node.height ) + height: Math.max( this.levelMaxDim[level]? this.levelMaxDim[level].height: 0, node.height ), }; return this; }, @@ -1083,7 +1083,7 @@ */ root: function() { return this.nodeDB.get( 0 ); - } + }, }; /** @@ -1232,7 +1232,7 @@ else { parent.children.splice( Math.max( position, parent.children.length - 1 ), - 0, node.id + 0, node.id, ); } } @@ -1256,7 +1256,7 @@ MinMax = MinMax || { // start with root node dimensions min: parent[dim], - max: parent[dim] + ( ( dim === 'X' )? parent.width: parent.height ) + max: parent[dim] + ( ( dim === 'X' )? parent.width: parent.height ), }; var i = parent.childrenCount(); @@ -1290,7 +1290,7 @@ } } return false; - } + }, }; /** @@ -1622,7 +1622,7 @@ self.toggleCollapse(); self.getTreeConfig().callback.onAfterClickCollapseSwitch.apply( self, [ nodeSwitch, e ] ); - } + }, ); }, @@ -1669,7 +1669,7 @@ }, ( oTree.CONFIG.animation.nodeSpeed > oTree.CONFIG.animation.connectorsSpeed )? oTree.CONFIG.animation.nodeSpeed: - oTree.CONFIG.animation.connectorsSpeed + oTree.CONFIG.animation.connectorsSpeed, ); } return this; @@ -1686,7 +1686,7 @@ var tree = this.getTree(), config = this.getTreeConfig(), oNewState = { - opacity: 0 + opacity: 0, }; if ( collapse_to_point ) { @@ -1713,7 +1713,7 @@ oNewState, config.animation.nodeSpeed, config.animation.nodeAnimation, function () { this.style.visibility = 'hidden'; - } + }, ); } else { @@ -1752,7 +1752,7 @@ oPath.animate( { 'opacity': 0 }, oTree.CONFIG.animation.connectorsSpeed, - oTree.CONFIG.animation.connectorsAnimation + oTree.CONFIG.animation.connectorsAnimation, ); } return this; @@ -1769,7 +1769,7 @@ var oNewState = { left: this.X, top: this.Y, - opacity: 1 + opacity: 1, }, config = this.getTreeConfig(); @@ -1781,7 +1781,7 @@ function () { // $.animate applies "overflow:hidden" to the node, remove it to avoid visual problems this.style.overflow = ""; - } + }, ); } else { @@ -1810,11 +1810,11 @@ oPath.animate( { 'opacity': 1 }, oTree.CONFIG.animation.connectorsSpeed, - oTree.CONFIG.animation.connectorsAnimation + oTree.CONFIG.animation.connectorsAnimation, ); } return this; - } + }, }; @@ -1868,8 +1868,8 @@ textElement.className = "node-"+key; textElement.appendChild(document.createTextNode( this.text[key].val ? this.text[key].val : - this.text[key] instanceof Object ? "'val' param missing!" : this.text[key] - ) + this.text[key] instanceof Object ? "'val' param missing!" : this.text[key], + ), ); node.appendChild(textElement); @@ -1941,7 +1941,7 @@ } else { node.data = { - 'treenode': this + 'treenode': this, }; } @@ -2017,9 +2017,9 @@ connectors: { type: 'curve', // 'curve' || 'step' || 'straight' || 'bCurve' style: { - stroke: 'black' + stroke: 'black', }, - stackIndent: 15 + stackIndent: 15, }, node: { // each node inherits this, it can all be overridden in node config @@ -2028,15 +2028,15 @@ // drawLineThrough: false, // collapsable: false, link: { - target: '_self' - } + target: '_self', + }, }, animation: { // each node inherits this, it can all be overridden in node config nodeSpeed: 450, nodeAnimation: 'linear', connectorsSpeed: 450, - connectorsAnimation: 'linear' + connectorsAnimation: 'linear', }, callback: { @@ -2049,12 +2049,12 @@ onToggleCollapseFinished: function ( treeNode, bIsCollapsed ) {}, // this = Tree onAfterClickCollapseSwitch: function( nodeSwitch, event ) {}, // this = TreeNode onBeforeClickCollapseSwitch: function( nodeSwitch, event ) {}, // this = TreeNode - onTreeLoaded: function( rootTreeNode ) {} // this = Tree - } + onTreeLoaded: function( rootTreeNode ) {}, // this = Tree + }, }; TreeNode.CONFIG = { - nodeHTMLclass: 'node' + nodeHTMLclass: 'node', }; // ############################################# @@ -2068,7 +2068,7 @@ this.jsonStructure = { chart: null, - nodeStructure: null + nodeStructure: null, }; //fist loop: find config, find root; while(i--) { @@ -2141,7 +2141,7 @@ return i++; }; } - )() + )(), }; /** diff --git a/src/ThirdParty/raphael.min.js b/src/ThirdParty/raphael.min.js index 75a545b54..16fd7b4b0 100644 --- a/src/ThirdParty/raphael.min.js +++ b/src/ThirdParty/raphael.min.js @@ -1 +1 @@ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Raphael=e():t.Raphael=e()}(window,function(){return function(t){var e={};function r(i){if(e[i])return e[i].exports;var n=e[i]={i:i,l:!1,exports:{}};return t[i].call(n.exports,n,n.exports,r),n.l=!0,n.exports}return r.m=t,r.c=e,r.d=function(t,e,i){r.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:i})},r.r=function(t){Object.defineProperty(t,"__esModule",{value:!0})},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=4)}([function(t,e,r){var i,n;i=[r(3)],void 0===(n=function(t){function e(i){if(e.is(i,"function"))return r?i():t.on("raphael.DOMload",i);if(e.is(i,T))return e._engine.create[c](e,i.splice(0,3+e.is(i[0],A))).add(i);var n=Array.prototype.slice.call(arguments,0);if(e.is(n[n.length-1],"function")){var a=n.pop();return r?a.call(e._engine.create[c](e,n)):t.on("raphael.DOMload",function(){a.call(e._engine.create[c](e,n))})}return e._engine.create[c](e,arguments)}e.version="2.2.0",e.eve=t;var r,i,n=/[, ]+/,a={circle:1,rect:1,path:1,ellipse:1,text:1,image:1},s=/\{(\d+)\}/g,o="hasOwnProperty",l={doc:document,win:window},h={was:Object.prototype[o].call(l.win,"Raphael"),is:l.win.Raphael},u=function(){this.ca=this.customAttributes={}},c="apply",f="concat",p="ontouchstart"in l.win||l.win.DocumentTouch&&l.doc instanceof DocumentTouch,d="",g=" ",x=String,v="split",y="click dblclick mousedown mousemove mouseout mouseover mouseup touchstart touchmove touchend touchcancel"[v](g),m={mousedown:"touchstart",mousemove:"touchmove",mouseup:"touchend"},b=x.prototype.toLowerCase,_=Math,w=_.max,k=_.min,B=_.abs,C=_.pow,S=_.PI,A="number",T="array",M=Object.prototype.toString,E=(e._ISURL=/^url\(['"]?(.+?)['"]?\)$/i,/^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+%?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+%?(?:\s*,\s*[\d\.]+%?)?)\s*\)|hsba?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\)|hsla?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\))\s*$/i),N={NaN:1,Infinity:1,"-Infinity":1},L=/^(?:cubic-)?bezier\(([^,]+),([^,]+),([^,]+),([^\)]+)\)/,P=_.round,z=parseFloat,F=parseInt,R=x.prototype.toUpperCase,j=e._availableAttrs={"arrow-end":"none","arrow-start":"none",blur:0,"clip-rect":"0 0 1e9 1e9",cursor:"default",cx:0,cy:0,fill:"#fff","fill-opacity":1,font:'10px "Arial"',"font-family":'"Arial"',"font-size":"10","font-style":"normal","font-weight":400,gradient:0,height:0,href:"http://raphaeljs.com/","letter-spacing":0,opacity:1,path:"M0,0",r:0,rx:0,ry:0,src:"",stroke:"#000","stroke-dasharray":"","stroke-linecap":"butt","stroke-linejoin":"butt","stroke-miterlimit":0,"stroke-opacity":1,"stroke-width":1,target:"_blank","text-anchor":"middle",title:"Raphael",transform:"",width:0,x:0,y:0,class:""},I=e._availableAnimAttrs={blur:A,"clip-rect":"csv",cx:A,cy:A,fill:"colour","fill-opacity":A,"font-size":A,height:A,opacity:A,path:"path",r:A,rx:A,ry:A,stroke:"colour","stroke-opacity":A,"stroke-width":A,transform:"transform",width:A,x:A,y:A},D=/[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*/,q={hs:1,rg:1},O=/,?([achlmqrstvxz]),?/gi,V=/([achlmrqstvz])[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*)+)/gi,Y=/([rstm])[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*)+)/gi,W=/(-?\d*\.?\d*(?:e[\-+]?\d+)?)[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*/gi,G=(e._radial_gradient=/^r(?:\(([^,]+?)[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*([^\)]+?)\))?/,{}),H=function(t,e){return z(t)-z(e)},X=function(t){return t},U=e._rectPath=function(t,e,r,i,n){return n?[["M",t+n,e],["l",r-2*n,0],["a",n,n,0,0,1,n,n],["l",0,i-2*n],["a",n,n,0,0,1,-n,n],["l",2*n-r,0],["a",n,n,0,0,1,-n,-n],["l",0,2*n-i],["a",n,n,0,0,1,n,-n],["z"]]:[["M",t,e],["l",r,0],["l",0,i],["l",-r,0],["z"]]},$=function(t,e,r,i){return null==i&&(i=r),[["M",t,e],["m",0,-i],["a",r,i,0,1,1,0,2*i],["a",r,i,0,1,1,0,-2*i],["z"]]},Z=e._getPath={path:function(t){return t.attr("path")},circle:function(t){var e=t.attrs;return $(e.cx,e.cy,e.r)},ellipse:function(t){var e=t.attrs;return $(e.cx,e.cy,e.rx,e.ry)},rect:function(t){var e=t.attrs;return U(e.x,e.y,e.width,e.height,e.r)},image:function(t){var e=t.attrs;return U(e.x,e.y,e.width,e.height)},text:function(t){var e=t._getBBox();return U(e.x,e.y,e.width,e.height)},set:function(t){var e=t._getBBox();return U(e.x,e.y,e.width,e.height)}},Q=e.mapPath=function(t,e){if(!e)return t;var r,i,n,a,s,o,l;for(n=0,s=(t=At(t)).length;n',(J=K.firstChild).style.behavior="url(#default#VML)",!J||"object"!=typeof J.adj)return e.type=d;K=null}function tt(t){if("function"==typeof t||Object(t)!==t)return t;var e=new t.constructor;for(var r in t)t[o](r)&&(e[r]=tt(t[r]));return e}e.svg=!(e.vml="VML"==e.type),e._Paper=u,e.fn=i=u.prototype=e.prototype,e._id=0,e.is=function(t,e){return"finite"==(e=b.call(e))?!N[o](+t):"array"==e?t instanceof Array:"null"==e&&null===t||e==typeof t&&null!==t||"object"==e&&t===Object(t)||"array"==e&&Array.isArray&&Array.isArray(t)||M.call(t).slice(8,-1).toLowerCase()==e},e.angle=function(t,r,i,n,a,s){if(null==a){var o=t-i,l=r-n;return o||l?(180+180*_.atan2(-l,-o)/S+360)%360:0}return e.angle(t,r,a,s)-e.angle(i,n,a,s)},e.rad=function(t){return t%360*S/180},e.deg=function(t){return Math.round(180*t/S%360*1e3)/1e3},e.snapTo=function(t,r,i){if(i=e.is(i,"finite")?i:10,e.is(t,T)){for(var n=t.length;n--;)if(B(t[n]-r)<=i)return t[n]}else{var a=r%(t=+t);if(at-i)return r-a+t}return r};var et,rt;e.createUUID=(et=/[xy]/g,rt=function(t){var e=16*_.random()|0;return("x"==t?e:3&e|8).toString(16)},function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(et,rt).toUpperCase()});e.setWindow=function(r){t("raphael.setWindow",e,l.win,r),l.win=r,l.doc=l.win.document,e._engine.initWin&&e._engine.initWin(l.win)};var it=function(t){if(e.vml){var r,i=/^\s+|\s+$/g;try{var n=new ActiveXObject("htmlfile");n.write(""),n.close(),r=n.body}catch(t){r=createPopup().document.body}var a=r.createTextRange();it=ht(function(t){try{r.style.color=x(t).replace(i,d);var e=a.queryCommandValue("ForeColor");return"#"+("000000"+(e=(255&e)<<16|65280&e|(16711680&e)>>>16).toString(16)).slice(-6)}catch(t){return"none"}})}else{var s=l.doc.createElement("i");s.title="Raphaël Colour Picker",s.style.display="none",l.doc.body.appendChild(s),it=ht(function(t){return s.style.color=t,l.doc.defaultView.getComputedStyle(s,d).getPropertyValue("color")})}return it(t)},nt=function(){return"hsb("+[this.h,this.s,this.b]+")"},at=function(){return"hsl("+[this.h,this.s,this.l]+")"},st=function(){return this.hex},ot=function(t,r,i){if(null==r&&e.is(t,"object")&&"r"in t&&"g"in t&&"b"in t&&(i=t.b,r=t.g,t=t.r),null==r&&e.is(t,"string")){var n=e.getRGB(t);t=n.r,r=n.g,i=n.b}return(t>1||r>1||i>1)&&(t/=255,r/=255,i/=255),[t,r,i]},lt=function(t,r,i,n){var a={r:t*=255,g:r*=255,b:i*=255,hex:e.rgb(t,r,i),toString:st};return e.is(n,"finite")&&(a.opacity=n),a};function ht(t,e,r){return function i(){var n=Array.prototype.slice.call(arguments,0),a=n.join("␀"),s=i.cache=i.cache||{},l=i.count=i.count||[];return s[o](a)?(function(t,e){for(var r=0,i=t.length;r=1e3&&delete s[l.shift()],l.push(a),s[a]=t[c](e,n),r?r(s[a]):s[a])}}e.color=function(t){var r;return e.is(t,"object")&&"h"in t&&"s"in t&&"b"in t?(r=e.hsb2rgb(t),t.r=r.r,t.g=r.g,t.b=r.b,t.hex=r.hex):e.is(t,"object")&&"h"in t&&"s"in t&&"l"in t?(r=e.hsl2rgb(t),t.r=r.r,t.g=r.g,t.b=r.b,t.hex=r.hex):(e.is(t,"string")&&(t=e.getRGB(t)),e.is(t,"object")&&"r"in t&&"g"in t&&"b"in t?(r=e.rgb2hsl(t),t.h=r.h,t.s=r.s,t.l=r.l,r=e.rgb2hsb(t),t.v=r.b):(t={hex:"none"}).r=t.g=t.b=t.h=t.s=t.v=t.l=-1),t.toString=st,t},e.hsb2rgb=function(t,e,r,i){var n,a,s,o,l;return this.is(t,"object")&&"h"in t&&"s"in t&&"b"in t&&(r=t.b,e=t.s,i=t.o,t=t.h),o=(l=r*e)*(1-B((t=(t*=360)%360/60)%2-1)),n=a=s=r-l,lt(n+=[l,o,0,0,o,l][t=~~t],a+=[o,l,l,o,0,0][t],s+=[0,0,o,l,l,o][t],i)},e.hsl2rgb=function(t,e,r,i){var n,a,s,o,l;return this.is(t,"object")&&"h"in t&&"s"in t&&"l"in t&&(r=t.l,e=t.s,t=t.h),(t>1||e>1||r>1)&&(t/=360,e/=100,r/=100),t=(t*=360)%360/60,o=(l=2*e*(r<.5?r:1-r))*(1-B(t%2-1)),n=a=s=r-l/2,lt(n+=[l,o,0,0,o,l][t=~~t],a+=[o,l,l,o,0,0][t],s+=[0,0,o,l,l,o][t],i)},e.rgb2hsb=function(t,e,r){var i,n;return t=(r=ot(t,e,r))[0],e=r[1],r=r[2],{h:((0==(n=(i=w(t,e,r))-k(t,e,r))?null:i==t?(e-r)/n:i==e?(r-t)/n+2:(t-e)/n+4)+360)%6*60/360,s:0==n?0:n/i,b:i,toString:nt}},e.rgb2hsl=function(t,e,r){var i,n,a,s;return t=(r=ot(t,e,r))[0],e=r[1],r=r[2],i=((n=w(t,e,r))+(a=k(t,e,r)))/2,{h:((0==(s=n-a)?null:n==t?(e-r)/s:n==e?(r-t)/s+2:(t-e)/s+4)+360)%6*60/360,s:0==s?0:i<.5?s/(2*i):s/(2-2*i),l:i,toString:at}},e._path2string=function(){return this.join(",").replace(O,"$1")};e._preload=function(t,e){var r=l.doc.createElement("img");r.style.cssText="position:absolute;left:-9999em;top:-9999em",r.onload=function(){e.call(this),this.onload=null,l.doc.body.removeChild(this)},r.onerror=function(){l.doc.body.removeChild(this)},l.doc.body.appendChild(r),r.src=t};function ut(){return this.hex}function ct(t,e){for(var r=[],i=0,n=t.length;n-2*!e>i;i+=2){var a=[{x:+t[i-2],y:+t[i-1]},{x:+t[i],y:+t[i+1]},{x:+t[i+2],y:+t[i+3]},{x:+t[i+4],y:+t[i+5]}];e?i?n-4==i?a[3]={x:+t[0],y:+t[1]}:n-2==i&&(a[2]={x:+t[0],y:+t[1]},a[3]={x:+t[2],y:+t[3]}):a[0]={x:+t[n-2],y:+t[n-1]}:n-4==i?a[3]=a[2]:i||(a[0]={x:+t[i],y:+t[i+1]}),r.push(["C",(-a[0].x+6*a[1].x+a[2].x)/6,(-a[0].y+6*a[1].y+a[2].y)/6,(a[1].x+6*a[2].x-a[3].x)/6,(a[1].y+6*a[2].y-a[3].y)/6,a[2].x,a[2].y])}return r}e.getRGB=ht(function(t){if(!t||(t=x(t)).indexOf("-")+1)return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:ut};if("none"==t)return{r:-1,g:-1,b:-1,hex:"none",toString:ut};!q[o](t.toLowerCase().substring(0,2))&&"#"!=t.charAt()&&(t=it(t));var r,i,n,a,s,l,h=t.match(E);return h?(h[2]&&(n=F(h[2].substring(5),16),i=F(h[2].substring(3,5),16),r=F(h[2].substring(1,3),16)),h[3]&&(n=F((s=h[3].charAt(3))+s,16),i=F((s=h[3].charAt(2))+s,16),r=F((s=h[3].charAt(1))+s,16)),h[4]&&(l=h[4][v](D),r=z(l[0]),"%"==l[0].slice(-1)&&(r*=2.55),i=z(l[1]),"%"==l[1].slice(-1)&&(i*=2.55),n=z(l[2]),"%"==l[2].slice(-1)&&(n*=2.55),"rgba"==h[1].toLowerCase().slice(0,4)&&(a=z(l[3])),l[3]&&"%"==l[3].slice(-1)&&(a/=100)),h[5]?(l=h[5][v](D),r=z(l[0]),"%"==l[0].slice(-1)&&(r*=2.55),i=z(l[1]),"%"==l[1].slice(-1)&&(i*=2.55),n=z(l[2]),"%"==l[2].slice(-1)&&(n*=2.55),("deg"==l[0].slice(-3)||"°"==l[0].slice(-1))&&(r/=360),"hsba"==h[1].toLowerCase().slice(0,4)&&(a=z(l[3])),l[3]&&"%"==l[3].slice(-1)&&(a/=100),e.hsb2rgb(r,i,n,a)):h[6]?(l=h[6][v](D),r=z(l[0]),"%"==l[0].slice(-1)&&(r*=2.55),i=z(l[1]),"%"==l[1].slice(-1)&&(i*=2.55),n=z(l[2]),"%"==l[2].slice(-1)&&(n*=2.55),("deg"==l[0].slice(-3)||"°"==l[0].slice(-1))&&(r/=360),"hsla"==h[1].toLowerCase().slice(0,4)&&(a=z(l[3])),l[3]&&"%"==l[3].slice(-1)&&(a/=100),e.hsl2rgb(r,i,n,a)):((h={r:r,g:i,b:n,toString:ut}).hex="#"+(16777216|n|i<<8|r<<16).toString(16).slice(1),e.is(a,"finite")&&(h.opacity=a),h)):{r:-1,g:-1,b:-1,hex:"none",error:1,toString:ut}},e),e.hsb=ht(function(t,r,i){return e.hsb2rgb(t,r,i).hex}),e.hsl=ht(function(t,r,i){return e.hsl2rgb(t,r,i).hex}),e.rgb=ht(function(t,e,r){function i(t){return t+.5|0}return"#"+(16777216|i(r)|i(e)<<8|i(t)<<16).toString(16).slice(1)}),e.getColor=function(t){var e=this.getColor.start=this.getColor.start||{h:0,s:1,b:t||.75},r=this.hsb2rgb(e.h,e.s,e.b);return e.h+=.075,e.h>1&&(e.h=0,e.s-=.2,e.s<=0&&(this.getColor.start={h:0,s:1,b:e.b})),r.hex},e.getColor.reset=function(){delete this.start},e.parsePathString=function(t){if(!t)return null;var r=ft(t);if(r.arr)return mt(r.arr);var i={a:7,c:6,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,z:0},n=[];return e.is(t,T)&&e.is(t[0],T)&&(n=mt(t)),n.length||x(t).replace(V,function(t,e,r){var a=[],s=e.toLowerCase();if(r.replace(W,function(t,e){e&&a.push(+e)}),"m"==s&&a.length>2&&(n.push([e][f](a.splice(0,2))),s="l",e="m"==e?"l":"L"),"r"==s)n.push([e][f](a));else for(;a.length>=i[s]&&(n.push([e][f](a.splice(0,i[s]))),i[s]););}),n.toString=e._path2string,r.arr=mt(n),n},e.parseTransformString=ht(function(t){if(!t)return null;var r=[];return e.is(t,T)&&e.is(t[0],T)&&(r=mt(t)),r.length||x(t).replace(Y,function(t,e,i){var n=[];b.call(e);i.replace(W,function(t,e){e&&n.push(+e)}),r.push([e][f](n))}),r.toString=e._path2string,r});var ft=function(t){var e=ft.ps=ft.ps||{};return e[t]?e[t].sleep=100:e[t]={sleep:100},setTimeout(function(){for(var r in e)e[o](r)&&r!=t&&(e[r].sleep--,!e[r].sleep&&delete e[r])}),e[t]};function pt(t,e,r,i,n){return t*(t*(-3*e+9*r-9*i+3*n)+6*e-12*r+6*i)-3*e+3*r}function dt(t,e,r,i,n,a,s,o,l){null==l&&(l=1);for(var h=(l=l>1?1:l<0?0:l)/2,u=[-.1252,.1252,-.3678,.3678,-.5873,.5873,-.7699,.7699,-.9041,.9041,-.9816,.9816],c=[.2491,.2491,.2335,.2335,.2032,.2032,.1601,.1601,.1069,.1069,.0472,.0472],f=0,p=0;p<12;p++){var d=h*u[p]+h,g=pt(d,t,r,n,s),x=pt(d,e,i,a,o),v=g*g+x*x;f+=c[p]*_.sqrt(v)}return h*f}function gt(t,e,r,i,n,a,s,o){if(!(w(t,r)w(n,s)||w(e,i)w(a,o))){var l=(t-r)*(a-o)-(e-i)*(n-s);if(l){var h=((t*i-e*r)*(n-s)-(t-r)*(n*o-a*s))/l,u=((t*i-e*r)*(a-o)-(e-i)*(n*o-a*s))/l,c=+h.toFixed(2),f=+u.toFixed(2);if(!(c<+k(t,r).toFixed(2)||c>+w(t,r).toFixed(2)||c<+k(n,s).toFixed(2)||c>+w(n,s).toFixed(2)||f<+k(e,i).toFixed(2)||f>+w(e,i).toFixed(2)||f<+k(a,o).toFixed(2)||f>+w(a,o).toFixed(2)))return{x:h,y:u}}}}function xt(t,r,i){var n=e.bezierBBox(t),a=e.bezierBBox(r);if(!e.isBBoxIntersect(n,a))return i?0:[];for(var s=dt.apply(0,t),o=dt.apply(0,r),l=w(~~(s/5),1),h=w(~~(o/5),1),u=[],c=[],f={},p=i?0:[],d=0;d=0&&A<=1.001&&T>=0&&T<=1.001&&(i?p++:p.push({x:S.x,y:S.y,t1:k(A,1),t2:k(T,1)}))}}return p}function vt(t,r,i){t=e._path2curve(t),r=e._path2curve(r);for(var n,a,s,o,l,h,u,c,f,p,d=i?0:[],g=0,x=t.length;gy||v=t.x&&e<=t.x2&&r>=t.y&&r<=t.y2},e.isBBoxIntersect=function(t,r){var i=e.isPointInsideBBox;return i(r,t.x,t.y)||i(r,t.x2,t.y)||i(r,t.x,t.y2)||i(r,t.x2,t.y2)||i(t,r.x,r.y)||i(t,r.x2,r.y)||i(t,r.x,r.y2)||i(t,r.x2,r.y2)||(t.xr.x||r.xt.x)&&(t.yr.y||r.yt.y)},e.pathIntersection=function(t,e){return vt(t,e)},e.pathIntersectionNumber=function(t,e){return vt(t,e,1)},e.isPointInsidePath=function(t,r,i){var n=e.pathBBox(t);return e.isPointInsideBBox(n,r,i)&&vt(t,[["M",r,i],["H",n.x2+10]],1)%2==1},e._removedFactory=function(e){return function(){t("raphael.log",null,"Raphaël: you are calling to method “"+e+"” of removed object",e)}};var yt=e.pathBBox=function(t){var e=ft(t);if(e.bbox)return tt(e.bbox);if(!t)return{x:0,y:0,width:0,height:0,x2:0,y2:0};for(var r,i=0,n=0,a=[],s=[],o=0,l=(t=At(t)).length;o1&&(r*=m=_.sqrt(m),i*=m);var b=r*r,w=i*i,k=(a==s?-1:1)*_.sqrt(B((b*w-b*y*y-w*x*x)/(b*y*y+w*x*x))),C=k*r*y/i+(t+o)/2,A=k*-i*x/r+(e+l)/2,T=_.asin(((e-A)/i).toFixed(9)),M=_.asin(((l-A)/i).toFixed(9));T=tM&&(T-=2*S),!s&&M>T&&(M-=2*S)}var E=M-T;if(B(E)>c){var N=M,L=o,P=l;M=T+c*(s&&M>T?1:-1),o=C+r*_.cos(M),l=A+i*_.sin(M),d=Bt(o,l,r,i,n,0,s,L,P,[M,N,C,A])}E=M-T;var z=_.cos(T),F=_.sin(T),R=_.cos(M),j=_.sin(M),I=_.tan(E/4),D=4/3*r*I,q=4/3*i*I,O=[t,e],V=[t+D*F,e-q*z],Y=[o+D*j,l-q*R],W=[o,l];if(V[0]=2*O[0]-V[0],V[1]=2*O[1]-V[1],h)return[V,Y,W][f](d);for(var G=[],H=0,X=(d=[V,Y,W][f](d).join()[v](",")).length;H"1e12"&&(p=.5),B(d)>"1e12"&&(d=.5),p>0&&p<1&&(l=Ct(t,e,r,i,n,a,s,o,p),x.push(l.x),g.push(l.y)),d>0&&d<1&&(l=Ct(t,e,r,i,n,a,s,o,d),x.push(l.x),g.push(l.y)),h=a-2*i+e-(o-2*a+i),f=e-i,p=(-(u=2*(i-e)-2*(a-i))+_.sqrt(u*u-4*h*f))/2/h,d=(-u-_.sqrt(u*u-4*h*f))/2/h,B(p)>"1e12"&&(p=.5),B(d)>"1e12"&&(d=.5),p>0&&p<1&&(l=Ct(t,e,r,i,n,a,s,o,p),x.push(l.x),g.push(l.y)),d>0&&d<1&&(l=Ct(t,e,r,i,n,a,s,o,d),x.push(l.x),g.push(l.y)),{min:{x:k[c](0,x),y:k[c](0,g)},max:{x:w[c](0,x),y:w[c](0,g)}}}),At=e._path2curve=ht(function(t,e){var r=!e&&ft(t);if(!e&&r.curve)return mt(r.curve);for(var i=_t(t),n=e&&_t(e),a={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},s={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},o=function(t,e,r){var i,n;if(!t)return["C",e.x,e.y,e.x,e.y,e.x,e.y];switch(!(t[0]in{T:1,Q:1})&&(e.qx=e.qy=null),t[0]){case"M":e.X=t[1],e.Y=t[2];break;case"A":t=["C"][f](Bt[c](0,[e.x,e.y][f](t.slice(1))));break;case"S":"C"==r||"S"==r?(i=2*e.x-e.bx,n=2*e.y-e.by):(i=e.x,n=e.y),t=["C",i,n][f](t.slice(1));break;case"T":"Q"==r||"T"==r?(e.qx=2*e.x-e.qx,e.qy=2*e.y-e.qy):(e.qx=e.x,e.qy=e.y),t=["C"][f](kt(e.x,e.y,e.qx,e.qy,t[1],t[2]));break;case"Q":e.qx=t[1],e.qy=t[2],t=["C"][f](kt(e.x,e.y,t[1],t[2],t[3],t[4]));break;case"L":t=["C"][f](wt(e.x,e.y,t[1],t[2]));break;case"H":t=["C"][f](wt(e.x,e.y,t[1],e.y));break;case"V":t=["C"][f](wt(e.x,e.y,e.x,t[1]));break;case"Z":t=["C"][f](wt(e.x,e.y,e.X,e.Y))}return t},l=function(t,e){if(t[e].length>7){t[e].shift();for(var r=t[e];r.length;)u[e]="A",n&&(p[e]="A"),t.splice(e++,0,["C"][f](r.splice(0,6)));t.splice(e,1),v=w(i.length,n&&n.length||0)}},h=function(t,e,r,a,s){t&&e&&"M"==t[s][0]&&"M"!=e[s][0]&&(e.splice(s,0,["M",a.x,a.y]),r.bx=0,r.by=0,r.x=t[s][1],r.y=t[s][2],v=w(i.length,n&&n.length||0))},u=[],p=[],d="",g="",x=0,v=w(i.length,n&&n.length||0);x.01;)u/=2,h=dt(t,e,r,i,n,a,s,o,c+=(hn){if(r&&!f.start){if(c+=["C"+(u=Xt(s,o,l[1],l[2],l[3],l[4],l[5],l[6],n-p)).start.x,u.start.y,u.m.x,u.m.y,u.x,u.y],a)return c;f.start=c,c=["M"+u.x,u.y+"C"+u.n.x,u.n.y,u.end.x,u.end.y,l[5],l[6]].join(),p+=h,s=+l[5],o=+l[6];continue}if(!t&&!r)return{x:(u=Xt(s,o,l[1],l[2],l[3],l[4],l[5],l[6],n-p)).x,y:u.y,alpha:u.alpha}}p+=h,s=+l[5],o=+l[6]}c+=l.shift()+l}return f.end=c,(u=t?p:r?f:e.findDotsAtSegment(s,o,l[0],l[1],l[2],l[3],l[4],l[5],1)).alpha&&(u={x:u.x,y:u.y,alpha:u.alpha}),u}},$t=Ut(1),Zt=Ut(),Qt=Ut(0,1);e.getTotalLength=$t,e.getPointAtLength=Zt,e.getSubpath=function(t,e,r){if(this.getTotalLength(t)-r<1e-6)return Qt(t,e).end;var i=Qt(t,r,1);return e?Qt(i,e).end:i},Yt.getTotalLength=function(){var t=this.getPath();if(t)return this.node.getTotalLength?this.node.getTotalLength():$t(t)},Yt.getPointAtLength=function(t){var e=this.getPath();if(e)return Zt(e,t)},Yt.getPath=function(){var t,r=e._getPath[this.type];if("text"!=this.type&&"set"!=this.type)return r&&(t=r(this)),t},Yt.getSubpath=function(t,r){var i=this.getPath();if(i)return e.getSubpath(i,t,r)};var Jt=e.easing_formulas={linear:function(t){return t},"<":function(t){return C(t,1.7)},">":function(t){return C(t,.48)},"<>":function(t){var e=.48-t/1.04,r=_.sqrt(.1734+e*e),i=r-e,n=-r-e,a=C(B(i),1/3)*(i<0?-1:1)+C(B(n),1/3)*(n<0?-1:1)+.5;return 3*(1-a)*a*a+a*a*a},backIn:function(t){var e=1.70158;return t*t*((e+1)*t-e)},backOut:function(t){var e=1.70158;return(t-=1)*t*((e+1)*t+e)+1},elastic:function(t){return t==!!t?t:C(2,-10*t)*_.sin(2*S*(t-.075)/.3)+1},bounce:function(t){var e=7.5625,r=2.75;return t<1/r?e*t*t:t<2/r?e*(t-=1.5/r)*t+.75:t<2.5/r?e*(t-=2.25/r)*t+.9375:e*(t-=2.625/r)*t+.984375}};Jt.easeIn=Jt["ease-in"]=Jt["<"],Jt.easeOut=Jt["ease-out"]=Jt[">"],Jt.easeInOut=Jt["ease-in-out"]=Jt["<>"],Jt["back-in"]=Jt.backIn,Jt["back-out"]=Jt.backOut;var Kt=[],te=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){setTimeout(t,16)},ee=function(){for(var r=+new Date,i=0;i1&&!n.next){for(s in d)d[o](s)&&(y[s]=n.totalOrigin[s]);n.el.attr(y),ae(n.anim,n.el,n.anim.percents[0],null,n.totalOrigin,n.repeat-1)}n.next&&!n.stop&&ae(n.anim,n.el,n.next,null,n.totalOrigin,n.repeat)}}}Kt.length&&te(ee)},re=function(t){return t>255?255:t<0?0:t};function ie(t,e,r,i,n,a){var s=3*e,o=3*(i-e)-s,l=1-s-o,h=3*r,u=3*(n-r)-h,c=1-h-u;function f(t){return((l*t+o)*t+s)*t}return function(t,e){var r=function(t,e){var r,i,n,a,h,u;for(n=t,u=0;u<8;u++){if(a=f(n)-t,B(a)i)return i;for(;ra?r=n:i=n,n=(i-r)/2+r}return n}(t,e);return((c*r+u)*r+h)*r}(t,1/(200*a))}function ne(t,e){var r=[],i={};if(this.ms=e,this.times=1,t){for(var n in t)t[o](n)&&(i[z(n)]=t[n],r.push(z(n)));r.sort(H)}this.anim=i,this.top=r[r.length-1],this.percents=r}function ae(r,i,a,s,l,h){a=z(a);var u,c,p,d,g,y,m=r.ms,b={},_={},w={};if(s)for(B=0,C=Kt.length;Bs*r.top){a=r.percents[B],g=r.percents[B-1]||0,m=m/r.top*(a-g),d=r.percents[B+1],u=r.anim[a];break}s&&i.attr(r.anim[r.percents[B]])}if(u){if(c)c.initstatus=s,c.start=new Date-c.ms*s;else{for(var S in u)if(u[o](S)&&(I[o](S)||i.paper.customAttributes[o](S)))switch(b[S]=i.attr(S),null==b[S]&&(b[S]=j[S]),_[S]=u[S],I[S]){case A:w[S]=(_[S]-b[S])/m;break;case"colour":b[S]=e.getRGB(b[S]);var T=e.getRGB(_[S]);w[S]={r:(T.r-b[S].r)/m,g:(T.g-b[S].g)/m,b:(T.b-b[S].b)/m};break;case"path":var M=At(b[S],_[S]),E=M[1];for(b[S]=M[0],w[S]=[],B=0,C=b[S].length;Bh&&(h=c)}!t[h+="%"].callback&&(t[h].callback=n)}return new ne(t,r)},Yt.animate=function(t,r,i,n){if(this.removed)return n&&n.call(this),this;var a=t instanceof ne?t:e.animation(t,r,i,n);return ae(a,this,a.percents[0],null,this.attr()),this},Yt.setTime=function(t,e){return t&&null!=e&&this.status(t,k(e,t.ms)/t.ms),this},Yt.status=function(t,e){var r,i,n=[],a=0;if(null!=e)return ae(t,this,-1,k(e,1)),this;for(r=Kt.length;a"));var U=H.getBoundingClientRect();A.W=g.w=(U.right-U.left)/100,A.H=g.h=(U.bottom-U.top)/100,A.X=g.x,A.Y=g.y+A.H/2,("x"in l||"y"in l)&&(A.path.v=t.format("m{0},{1}l{2},{1}",a(g.x*y),a(g.y*y),a(g.x*y)+1));for(var $=["x","y","text","font","font-family","font-weight","font-style","font-size"],Z=0,Q=$.length;Z.25&&(r=n.sqrt(.25-o(e-.5,2))*(2*(r>.5)-1)+.5),h=e+c+r),f})).split(/\s*\-\s*/),"linear"==l){var u=a.shift();if(u=-i(u),isNaN(u))return null}var p=t._parseDots(a);if(!p)return null;if(e=e.shape||e.node,p.length){e.removeChild(s),s.on=!0,s.method="none",s.color=p[0].color,s.color2=p[p.length-1].color;for(var d=[],g=0,x=p.length;g')}}catch(t){k=function(t){return e.createElement("<"+t+' xmlns="urn:schemas-microsoft.com:vml" class="rvml">')}}},t._engine.initWin(t._g.win),t._engine.create=function(){var e=t._getContainer.apply(0,arguments),r=e.container,i=e.height,n=e.width,a=e.x,s=e.y;if(!r)throw new Error("VML container not found.");var o=new t._Paper,l=o.canvas=t._g.doc.createElement("div"),h=l.style;return a=a||0,s=s||0,n=n||512,i=i||342,o.width=n,o.height=i,n==+n&&(n+="px"),i==+i&&(i+="px"),o.coordsize=216e5+c+216e5,o.coordorigin="0 0",o.span=t._g.doc.createElement("span"),o.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;",l.appendChild(o.span),h.cssText=t.format("top:0;left:0;width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden",n,i),1==r?(t._g.doc.body.appendChild(l),h.left=a+"px",h.top=s+"px",h.position="absolute"):r.firstChild?r.insertBefore(l,r.firstChild):r.appendChild(l),o.renderfix=function(){},o},t.prototype.clear=function(){t.eve("raphael.clear",this),this.canvas.innerHTML=f,this.span=t._g.doc.createElement("span"),this.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;",this.canvas.appendChild(this.span),this.bottom=this.top=null},t.prototype.remove=function(){for(var e in t.eve("raphael.remove",this),this.canvas.parentNode.removeChild(this.canvas),this)this[e]="function"==typeof this[e]?t._removedFactory(e):null;return!0};var M=t.st;for(var E in T)T[e](E)&&!M[e](E)&&(M[E]=function(t){return function(){var e=arguments;return this.forEach(function(r){r[t].apply(r,e)})}}(E))}}.apply(e,i))||(t.exports=n)},function(t,e,r){var i,n;i=[r(0)],void 0===(n=function(t){if(!t||t.svg){var e="hasOwnProperty",r=String,i=parseFloat,n=parseInt,a=Math,s=a.max,o=a.abs,l=a.pow,h=/[, ]+/,u=t.eve,c="",f=" ",p="http://www.w3.org/1999/xlink",d={block:"M5,0 0,2.5 5,5z",classic:"M5,0 0,2.5 5,5 3.5,3 3.5,2z",diamond:"M2.5,0 5,2.5 2.5,5 0,2.5z",open:"M6,1 1,3.5 6,6",oval:"M2.5,0A2.5,2.5,0,0,1,2.5,5 2.5,2.5,0,0,1,2.5,0z"},g={};t.toString=function(){return"Your browser supports SVG.\nYou are running Raphaël "+this.version};var x=function(i,n){if(n)for(var a in"string"==typeof i&&(i=x(i)),n)n[e](a)&&("xlink:"==a.substring(0,6)?i.setAttributeNS(p,a.substring(6),r(n[a])):i.setAttribute(a,r(n[a])));else(i=t._g.doc.createElementNS("http://www.w3.org/2000/svg",i)).style&&(i.style.webkitTapHighlightColor="rgba(0,0,0,0)");return i},v=function(e,n){var h="linear",u=e.id+n,f=.5,p=.5,d=e.node,g=e.paper,v=d.style,m=t._g.doc.getElementById(u);if(!m){if(n=(n=r(n).replace(t._radial_gradient,function(t,e,r){if(h="radial",e&&r){f=i(e);var n=2*((p=i(r))>.5)-1;l(f-.5,2)+l(p-.5,2)>.25&&(p=a.sqrt(.25-l(f-.5,2))*n+.5)&&.5!=p&&(p=p.toFixed(5)-1e-5*n)}return c})).split(/\s*\-\s*/),"linear"==h){var b=n.shift();if(b=-i(b),isNaN(b))return null;var _=[0,0,a.cos(t.rad(b)),a.sin(t.rad(b))],w=1/(s(o(_[2]),o(_[3]))||1);_[2]*=w,_[3]*=w,_[2]<0&&(_[0]=-_[2],_[2]=0),_[3]<0&&(_[1]=-_[3],_[3]=0)}var k=t._parseDots(n);if(!k)return null;if(u=u.replace(/[\(\)\s,\xb0#]/g,"_"),e.gradient&&u!=e.gradient.id&&(g.defs.removeChild(e.gradient),delete e.gradient),!e.gradient){m=x(h+"Gradient",{id:u}),e.gradient=m,x(m,"radial"==h?{fx:f,fy:p}:{x1:_[0],y1:_[1],x2:_[2],y2:_[3],gradientTransform:e.matrix.invert()}),g.defs.appendChild(m);for(var B=0,C=k.length;B1?P.opacity/100:P.opacity});case"stroke":P=t.getRGB(g),l.setAttribute(d,P.hex),"stroke"==d&&P[e]("opacity")&&x(l,{"stroke-opacity":P.opacity>1?P.opacity/100:P.opacity}),"stroke"==d&&i._.arrows&&("startString"in i._.arrows&&b(i,i._.arrows.startString),"endString"in i._.arrows&&b(i,i._.arrows.endString,1));break;case"gradient":("circle"==i.type||"ellipse"==i.type||"r"!=r(g).charAt())&&v(i,g);break;case"opacity":u.gradient&&!u[e]("stroke-opacity")&&x(l,{"stroke-opacity":g>1?g/100:g});case"fill-opacity":if(u.gradient){(z=t._g.doc.getElementById(l.getAttribute("fill").replace(/^url\(#|\)$/g,c)))&&(F=z.getElementsByTagName("stop"),x(F[F.length-1],{"stop-opacity":g}));break}default:"font-size"==d&&(g=n(g,10)+"px");var R=d.replace(/(\-.)/g,function(t){return t.substring(1).toUpperCase()});l.style[R]=g,i._.dirty=1,l.setAttribute(d,g)}}B(i,a),l.style.visibility=f},B=function(i,a){if("text"==i.type&&(a[e]("text")||a[e]("font")||a[e]("font-size")||a[e]("x")||a[e]("y"))){var s=i.attrs,o=i.node,l=o.firstChild?n(t._g.doc.defaultView.getComputedStyle(o.firstChild,c).getPropertyValue("font-size"),10):10;if(a[e]("text")){for(s.text=a.text;o.firstChild;)o.removeChild(o.firstChild);for(var h,u=r(a.text).split("\n"),f=[],p=0,d=u.length;p1)for(var i=0,n=r.length;i',(J=K.firstChild).style.behavior="url(#default#VML)",!J||typeof J.adj!="object")return e.type=d;K=null}function tt(t){if(typeof t=="function"||Object(t)!==t)return t;var e=new t.constructor;for(var r in t)t[o](r)&&(e[r]=tt(t[r]));return e}e.svg=!(e.vml=e.type=="VML"),e._Paper=u,e.fn=i=u.prototype=e.prototype,e._id=0,e.is=function(t,e){return(e=b.call(e))=="finite"?!N[o](+t):e=="array"?t instanceof Array:e=="null"&&t===null||e==typeof t&&t!==null||e=="object"&&t===Object(t)||e=="array"&&Array.isArray&&Array.isArray(t)||M.call(t).slice(8,-1).toLowerCase()==e},e.angle=function(t,r,i,n,a,s){if(a==null){var o=t-i,l=r-n;return o||l?(180+180*_.atan2(-l,-o)/S+360)%360:0}return e.angle(t,r,a,s)-e.angle(i,n,a,s)},e.rad=function(t){return t%360*S/180},e.deg=function(t){return Math.round(180*t/S%360*1e3)/1e3},e.snapTo=function(t,r,i){if(i=e.is(i,"finite")?i:10,e.is(t,T)){for(var n=t.length;n--;)if(B(t[n]-r)<=i)return t[n]}else{var a=r%(t=+t);if(at-i)return r-a+t}return r};var et,rt;e.createUUID=(et=/[xy]/g,rt=function(t){var e=16*_.random()|0;return(t=="x"?e:3&e|8).toString(16)},function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(et,rt).toUpperCase()});e.setWindow=function(r){t("raphael.setWindow",e,l.win,r),l.win=r,l.doc=l.win.document,e._engine.initWin&&e._engine.initWin(l.win)};var it=function(t){if(e.vml){var r,i=/^\s+|\s+$/g;try{var n=new ActiveXObject("htmlfile");n.write(""),n.close(),r=n.body}catch(t){r=createPopup().document.body}var a=r.createTextRange();it=ht(function(t){try{r.style.color=x(t).replace(i,d);var e=a.queryCommandValue("ForeColor");return"#"+("000000"+(e=(255&e)<<16|65280&e|(16711680&e)>>>16).toString(16)).slice(-6)}catch(t){return"none"}})}else{var s=l.doc.createElement("i");s.title="Raphaël Colour Picker",s.style.display="none",l.doc.body.appendChild(s),it=ht(function(t){return s.style.color=t,l.doc.defaultView.getComputedStyle(s,d).getPropertyValue("color")})}return it(t)},nt=function(){return"hsb("+[this.h,this.s,this.b]+")"},at=function(){return"hsl("+[this.h,this.s,this.l]+")"},st=function(){return this.hex},ot=function(t,r,i){if(r==null&&e.is(t,"object")&&"r"in t&&"g"in t&&"b"in t&&(i=t.b,r=t.g,t=t.r),r==null&&e.is(t,"string")){var n=e.getRGB(t);t=n.r,r=n.g,i=n.b}return(t>1||r>1||i>1)&&(t/=255,r/=255,i/=255),[t,r,i]},lt=function(t,r,i,n){var a={r:t*=255,g:r*=255,b:i*=255,hex:e.rgb(t,r,i),toString:st};return e.is(n,"finite")&&(a.opacity=n),a};function ht(t,e,r){return function i(){var n=Array.prototype.slice.call(arguments,0),a=n.join("␀"),s=i.cache=i.cache||{},l=i.count=i.count||[];return s[o](a)?((function(t,e){for(var r=0,i=t.length;r=1e3&&delete s[l.shift()],l.push(a),s[a]=t[c](e,n),r?r(s[a]):s[a])}}e.color=function(t){var r;return e.is(t,"object")&&"h"in t&&"s"in t&&"b"in t?(r=e.hsb2rgb(t),t.r=r.r,t.g=r.g,t.b=r.b,t.hex=r.hex):e.is(t,"object")&&"h"in t&&"s"in t&&"l"in t?(r=e.hsl2rgb(t),t.r=r.r,t.g=r.g,t.b=r.b,t.hex=r.hex):(e.is(t,"string")&&(t=e.getRGB(t)),e.is(t,"object")&&"r"in t&&"g"in t&&"b"in t?(r=e.rgb2hsl(t),t.h=r.h,t.s=r.s,t.l=r.l,r=e.rgb2hsb(t),t.v=r.b):(t={hex:"none"}).r=t.g=t.b=t.h=t.s=t.v=t.l=-1),t.toString=st,t},e.hsb2rgb=function(t,e,r,i){var n,a,s,o,l;return this.is(t,"object")&&"h"in t&&"s"in t&&"b"in t&&(r=t.b,e=t.s,i=t.o,t=t.h),o=(l=r*e)*(1-B((t=(t*=360)%360/60)%2-1)),n=a=s=r-l,lt(n+=[l,o,0,0,o,l][t=~~t],a+=[o,l,l,o,0,0][t],s+=[0,0,o,l,l,o][t],i)},e.hsl2rgb=function(t,e,r,i){var n,a,s,o,l;return this.is(t,"object")&&"h"in t&&"s"in t&&"l"in t&&(r=t.l,e=t.s,t=t.h),(t>1||e>1||r>1)&&(t/=360,e/=100,r/=100),t=(t*=360)%360/60,o=(l=2*e*(r<.5?r:1-r))*(1-B(t%2-1)),n=a=s=r-l/2,lt(n+=[l,o,0,0,o,l][t=~~t],a+=[o,l,l,o,0,0][t],s+=[0,0,o,l,l,o][t],i)},e.rgb2hsb=function(t,e,r){var i,n;return t=(r=ot(t,e,r))[0],e=r[1],r=r[2],{h:(((n=(i=w(t,e,r))-k(t,e,r))==0?null:i==t?(e-r)/n:i==e?(r-t)/n+2:(t-e)/n+4)+360)%6*60/360,s:n==0?0:n/i,b:i,toString:nt}},e.rgb2hsl=function(t,e,r){var i,n,a,s;return t=(r=ot(t,e,r))[0],e=r[1],r=r[2],i=((n=w(t,e,r))+(a=k(t,e,r)))/2,{h:(((s=n-a)==0?null:n==t?(e-r)/s:n==e?(r-t)/s+2:(t-e)/s+4)+360)%6*60/360,s:s==0?0:i<.5?s/(2*i):s/(2-2*i),l:i,toString:at}},e._path2string=function(){return this.join(",").replace(O,"$1")};e._preload=function(t,e){var r=l.doc.createElement("img");r.style.cssText="position:absolute;left:-9999em;top:-9999em",r.onload=function(){e.call(this),this.onload=null,l.doc.body.removeChild(this)},r.onerror=function(){l.doc.body.removeChild(this)},l.doc.body.appendChild(r),r.src=t};function ut(){return this.hex}function ct(t,e){for(var r=[],i=0,n=t.length;n-2*!e>i;i+=2){var a=[{x:+t[i-2],y:+t[i-1]},{x:+t[i],y:+t[i+1]},{x:+t[i+2],y:+t[i+3]},{x:+t[i+4],y:+t[i+5]}];e?i?n-4==i?a[3]={x:+t[0],y:+t[1]}:n-2==i&&(a[2]={x:+t[0],y:+t[1]},a[3]={x:+t[2],y:+t[3]}):a[0]={x:+t[n-2],y:+t[n-1]}:n-4==i?a[3]=a[2]:i||(a[0]={x:+t[i],y:+t[i+1]}),r.push(["C",(-a[0].x+6*a[1].x+a[2].x)/6,(-a[0].y+6*a[1].y+a[2].y)/6,(a[1].x+6*a[2].x-a[3].x)/6,(a[1].y+6*a[2].y-a[3].y)/6,a[2].x,a[2].y])}return r}e.getRGB=ht(function(t){if(!t||(t=x(t)).indexOf("-")+1)return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:ut};if(t=="none")return{r:-1,g:-1,b:-1,hex:"none",toString:ut};!q[o](t.toLowerCase().substring(0,2))&&t.charAt()!="#"&&(t=it(t));var r,i,n,a,s,l,h=t.match(E);return h?(h[2]&&(n=F(h[2].substring(5),16),i=F(h[2].substring(3,5),16),r=F(h[2].substring(1,3),16)),h[3]&&(n=F((s=h[3].charAt(3))+s,16),i=F((s=h[3].charAt(2))+s,16),r=F((s=h[3].charAt(1))+s,16)),h[4]&&(l=h[4][v](D),r=z(l[0]),l[0].slice(-1)=="%"&&(r*=2.55),i=z(l[1]),l[1].slice(-1)=="%"&&(i*=2.55),n=z(l[2]),l[2].slice(-1)=="%"&&(n*=2.55),h[1].toLowerCase().slice(0,4)=="rgba"&&(a=z(l[3])),l[3]&&l[3].slice(-1)=="%"&&(a/=100)),h[5]?(l=h[5][v](D),r=z(l[0]),l[0].slice(-1)=="%"&&(r*=2.55),i=z(l[1]),l[1].slice(-1)=="%"&&(i*=2.55),n=z(l[2]),l[2].slice(-1)=="%"&&(n*=2.55),(l[0].slice(-3)=="deg"||l[0].slice(-1)=="°")&&(r/=360),h[1].toLowerCase().slice(0,4)=="hsba"&&(a=z(l[3])),l[3]&&l[3].slice(-1)=="%"&&(a/=100),e.hsb2rgb(r,i,n,a)):h[6]?(l=h[6][v](D),r=z(l[0]),l[0].slice(-1)=="%"&&(r*=2.55),i=z(l[1]),l[1].slice(-1)=="%"&&(i*=2.55),n=z(l[2]),l[2].slice(-1)=="%"&&(n*=2.55),(l[0].slice(-3)=="deg"||l[0].slice(-1)=="°")&&(r/=360),h[1].toLowerCase().slice(0,4)=="hsla"&&(a=z(l[3])),l[3]&&l[3].slice(-1)=="%"&&(a/=100),e.hsl2rgb(r,i,n,a)):((h={r:r,g:i,b:n,toString:ut}).hex="#"+(16777216|n|i<<8|r<<16).toString(16).slice(1),e.is(a,"finite")&&(h.opacity=a),h)):{r:-1,g:-1,b:-1,hex:"none",error:1,toString:ut}},e),e.hsb=ht(function(t,r,i){return e.hsb2rgb(t,r,i).hex}),e.hsl=ht(function(t,r,i){return e.hsl2rgb(t,r,i).hex}),e.rgb=ht(function(t,e,r){function i(t){return t+.5|0}return"#"+(16777216|i(r)|i(e)<<8|i(t)<<16).toString(16).slice(1)}),e.getColor=function(t){var e=this.getColor.start=this.getColor.start||{h:0,s:1,b:t||.75},r=this.hsb2rgb(e.h,e.s,e.b);return e.h+=.075,e.h>1&&(e.h=0,e.s-=.2,e.s<=0&&(this.getColor.start={h:0,s:1,b:e.b})),r.hex},e.getColor.reset=function(){delete this.start},e.parsePathString=function(t){if(!t)return null;var r=ft(t);if(r.arr)return mt(r.arr);var i={a:7,c:6,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,z:0},n=[];return e.is(t,T)&&e.is(t[0],T)&&(n=mt(t)),n.length||x(t).replace(V,function(t,e,r){var a=[],s=e.toLowerCase();if(r.replace(W,function(t,e){e&&a.push(+e)}),s=="m"&&a.length>2&&(n.push([e][f](a.splice(0,2))),s="l",e=e=="m"?"l":"L"),s=="r")n.push([e][f](a));else for(;a.length>=i[s]&&(n.push([e][f](a.splice(0,i[s]))),i[s]););}),n.toString=e._path2string,r.arr=mt(n),n},e.parseTransformString=ht(function(t){if(!t)return null;var r=[];return e.is(t,T)&&e.is(t[0],T)&&(r=mt(t)),r.length||x(t).replace(Y,function(t,e,i){var n=[];b.call(e);i.replace(W,function(t,e){e&&n.push(+e)}),r.push([e][f](n))}),r.toString=e._path2string,r});var ft=function(t){var e=ft.ps=ft.ps||{};return e[t]?e[t].sleep=100:e[t]={sleep:100},setTimeout(function(){for(var r in e)e[o](r)&&r!=t&&(e[r].sleep--,!e[r].sleep&&delete e[r])}),e[t]};function pt(t,e,r,i,n){return t*(t*(-3*e+9*r-9*i+3*n)+6*e-12*r+6*i)-3*e+3*r}function dt(t,e,r,i,n,a,s,o,l){l==null&&(l=1);for(var h=(l=l>1?1:l<0?0:l)/2,u=[-.1252,.1252,-.3678,.3678,-.5873,.5873,-.7699,.7699,-.9041,.9041,-.9816,.9816],c=[.2491,.2491,.2335,.2335,.2032,.2032,.1601,.1601,.1069,.1069,.0472,.0472],f=0,p=0;p<12;p++){var d=h*u[p]+h,g=pt(d,t,r,n,s),x=pt(d,e,i,a,o),v=g*g+x*x;f+=c[p]*_.sqrt(v)}return h*f}function gt(t,e,r,i,n,a,s,o){if(!(w(t,r)w(n,s)||w(e,i)w(a,o))){var l=(t-r)*(a-o)-(e-i)*(n-s);if(l){var h=((t*i-e*r)*(n-s)-(t-r)*(n*o-a*s))/l,u=((t*i-e*r)*(a-o)-(e-i)*(n*o-a*s))/l,c=+h.toFixed(2),f=+u.toFixed(2);if(!(c<+k(t,r).toFixed(2)||c>+w(t,r).toFixed(2)||c<+k(n,s).toFixed(2)||c>+w(n,s).toFixed(2)||f<+k(e,i).toFixed(2)||f>+w(e,i).toFixed(2)||f<+k(a,o).toFixed(2)||f>+w(a,o).toFixed(2)))return{x:h,y:u}}}}function xt(t,r,i){var n=e.bezierBBox(t),a=e.bezierBBox(r);if(!e.isBBoxIntersect(n,a))return i?0:[];for(var s=dt.apply(0,t),o=dt.apply(0,r),l=w(~~(s/5),1),h=w(~~(o/5),1),u=[],c=[],f={},p=i?0:[],d=0;d=0&&A<=1.001&&T>=0&&T<=1.001&&(i?p++:p.push({x:S.x,y:S.y,t1:k(A,1),t2:k(T,1)}))}}return p}function vt(t,r,i){t=e._path2curve(t),r=e._path2curve(r);for(var n,a,s,o,l,h,u,c,f,p,d=i?0:[],g=0,x=t.length;gy||v=t.x&&e<=t.x2&&r>=t.y&&r<=t.y2},e.isBBoxIntersect=function(t,r){var i=e.isPointInsideBBox;return i(r,t.x,t.y)||i(r,t.x2,t.y)||i(r,t.x,t.y2)||i(r,t.x2,t.y2)||i(t,r.x,r.y)||i(t,r.x2,r.y)||i(t,r.x,r.y2)||i(t,r.x2,r.y2)||(t.xr.x||r.xt.x)&&(t.yr.y||r.yt.y)},e.pathIntersection=function(t,e){return vt(t,e)},e.pathIntersectionNumber=function(t,e){return vt(t,e,1)},e.isPointInsidePath=function(t,r,i){var n=e.pathBBox(t);return e.isPointInsideBBox(n,r,i)&&vt(t,[["M",r,i],["H",n.x2+10]],1)%2==1},e._removedFactory=function(e){return function(){t("raphael.log",null,"Raphaël: you are calling to method “"+e+"” of removed object",e)}};var yt=e.pathBBox=function(t){var e=ft(t);if(e.bbox)return tt(e.bbox);if(!t)return{x:0,y:0,width:0,height:0,x2:0,y2:0};for(var r,i=0,n=0,a=[],s=[],o=0,l=(t=At(t)).length;o1&&(r*=m=_.sqrt(m),i*=m);var b=r*r,w=i*i,k=(a==s?-1:1)*_.sqrt(B((b*w-b*y*y-w*x*x)/(b*y*y+w*x*x))),C=k*r*y/i+(t+o)/2,A=k*-i*x/r+(e+l)/2,T=_.asin(((e-A)/i).toFixed(9)),M=_.asin(((l-A)/i).toFixed(9));T=tM&&(T-=2*S),!s&&M>T&&(M-=2*S)}var E=M-T;if(B(E)>c){var N=M,L=o,P=l;M=T+c*(s&&M>T?1:-1),o=C+r*_.cos(M),l=A+i*_.sin(M),d=Bt(o,l,r,i,n,0,s,L,P,[M,N,C,A])}E=M-T;var z=_.cos(T),F=_.sin(T),R=_.cos(M),j=_.sin(M),I=_.tan(E/4),D=4/3*r*I,q=4/3*i*I,O=[t,e],V=[t+D*F,e-q*z],Y=[o+D*j,l-q*R],W=[o,l];if(V[0]=2*O[0]-V[0],V[1]=2*O[1]-V[1],h)return[V,Y,W][f](d);for(var G=[],H=0,X=(d=[V,Y,W][f](d).join()[v](",")).length;H"1e12"&&(p=.5),B(d)>"1e12"&&(d=.5),p>0&&p<1&&(l=Ct(t,e,r,i,n,a,s,o,p),x.push(l.x),g.push(l.y)),d>0&&d<1&&(l=Ct(t,e,r,i,n,a,s,o,d),x.push(l.x),g.push(l.y)),h=a-2*i+e-(o-2*a+i),f=e-i,p=(-(u=2*(i-e)-2*(a-i))+_.sqrt(u*u-4*h*f))/2/h,d=(-u-_.sqrt(u*u-4*h*f))/2/h,B(p)>"1e12"&&(p=.5),B(d)>"1e12"&&(d=.5),p>0&&p<1&&(l=Ct(t,e,r,i,n,a,s,o,p),x.push(l.x),g.push(l.y)),d>0&&d<1&&(l=Ct(t,e,r,i,n,a,s,o,d),x.push(l.x),g.push(l.y)),{min:{x:k[c](0,x),y:k[c](0,g)},max:{x:w[c](0,x),y:w[c](0,g)}}}),At=e._path2curve=ht(function(t,e){var r=!e&&ft(t);if(!e&&r.curve)return mt(r.curve);for(var i=_t(t),n=e&&_t(e),a={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},s={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},o=function(t,e,r){var i,n;if(!t)return["C",e.x,e.y,e.x,e.y,e.x,e.y];switch(!(t[0]in{T:1,Q:1})&&(e.qx=e.qy=null),t[0]){case"M": e.X=t[1],e.Y=t[2];break;case"A": t=["C"][f](Bt[c](0,[e.x,e.y][f](t.slice(1))));break;case"S": r=="C"||r=="S"?(i=2*e.x-e.bx,n=2*e.y-e.by):(i=e.x,n=e.y),t=["C",i,n][f](t.slice(1));break;case"T": r=="Q"||r=="T"?(e.qx=2*e.x-e.qx,e.qy=2*e.y-e.qy):(e.qx=e.x,e.qy=e.y),t=["C"][f](kt(e.x,e.y,e.qx,e.qy,t[1],t[2]));break;case"Q": e.qx=t[1],e.qy=t[2],t=["C"][f](kt(e.x,e.y,t[1],t[2],t[3],t[4]));break;case"L": t=["C"][f](wt(e.x,e.y,t[1],t[2]));break;case"H": t=["C"][f](wt(e.x,e.y,t[1],e.y));break;case"V": t=["C"][f](wt(e.x,e.y,e.x,t[1]));break;case"Z": t=["C"][f](wt(e.x,e.y,e.X,e.Y))}return t},l=function(t,e){if(t[e].length>7){t[e].shift();for(var r=t[e];r.length;)u[e]="A",n&&(p[e]="A"),t.splice(e++,0,["C"][f](r.splice(0,6)));t.splice(e,1),v=w(i.length,n&&n.length||0)}},h=function(t,e,r,a,s){t&&e&&t[s][0]=="M"&&e[s][0]!="M"&&(e.splice(s,0,["M",a.x,a.y]),r.bx=0,r.by=0,r.x=t[s][1],r.y=t[s][2],v=w(i.length,n&&n.length||0))},u=[],p=[],d="",g="",x=0,v=w(i.length,n&&n.length||0);x.01;)u/=2,h=dt(t,e,r,i,n,a,s,o,c+=(hn){if(r&&!f.start){if(c+=["C"+(u=Xt(s,o,l[1],l[2],l[3],l[4],l[5],l[6],n-p)).start.x,u.start.y,u.m.x,u.m.y,u.x,u.y],a)return c;f.start=c,c=["M"+u.x,u.y+"C"+u.n.x,u.n.y,u.end.x,u.end.y,l[5],l[6]].join(),p+=h,s=+l[5],o=+l[6];continue}if(!t&&!r)return{x:(u=Xt(s,o,l[1],l[2],l[3],l[4],l[5],l[6],n-p)).x,y:u.y,alpha:u.alpha}}p+=h,s=+l[5],o=+l[6]}c+=l.shift()+l}return f.end=c,(u=t?p:r?f:e.findDotsAtSegment(s,o,l[0],l[1],l[2],l[3],l[4],l[5],1)).alpha&&(u={x:u.x,y:u.y,alpha:u.alpha}),u}},$t=Ut(1),Zt=Ut(),Qt=Ut(0,1);e.getTotalLength=$t,e.getPointAtLength=Zt,e.getSubpath=function(t,e,r){if(this.getTotalLength(t)-r<1e-6)return Qt(t,e).end;var i=Qt(t,r,1);return e?Qt(i,e).end:i},Yt.getTotalLength=function(){var t=this.getPath();if(t)return this.node.getTotalLength?this.node.getTotalLength():$t(t)},Yt.getPointAtLength=function(t){var e=this.getPath();if(e)return Zt(e,t)},Yt.getPath=function(){var t,r=e._getPath[this.type];if(this.type!="text"&&this.type!="set")return r&&(t=r(this)),t},Yt.getSubpath=function(t,r){var i=this.getPath();if(i)return e.getSubpath(i,t,r)};var Jt=e.easing_formulas={linear:function(t){return t},"<":function(t){return C(t,1.7)},">":function(t){return C(t,.48)},"<>":function(t){var e=.48-t/1.04,r=_.sqrt(.1734+e*e),i=r-e,n=-r-e,a=C(B(i),1/3)*(i<0?-1:1)+C(B(n),1/3)*(n<0?-1:1)+.5;return 3*(1-a)*a*a+a*a*a},backIn:function(t){var e=1.70158;return t*t*((e+1)*t-e)},backOut:function(t){var e=1.70158;return(t-=1)*t*((e+1)*t+e)+1},elastic:function(t){return t==!!t?t:C(2,-10*t)*_.sin(2*S*(t-.075)/.3)+1},bounce:function(t){var e=7.5625,r=2.75;return t<1/r?e*t*t:t<2/r?e*(t-=1.5/r)*t+.75:t<2.5/r?e*(t-=2.25/r)*t+.9375:e*(t-=2.625/r)*t+.984375}};Jt.easeIn=Jt["ease-in"]=Jt["<"],Jt.easeOut=Jt["ease-out"]=Jt[">"],Jt.easeInOut=Jt["ease-in-out"]=Jt["<>"],Jt["back-in"]=Jt.backIn,Jt["back-out"]=Jt.backOut;var Kt=[],te=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){setTimeout(t,16)},ee=function(){for(var r=+new Date,i=0;i1&&!n.next){for(s in d)d[o](s)&&(y[s]=n.totalOrigin[s]);n.el.attr(y),ae(n.anim,n.el,n.anim.percents[0],null,n.totalOrigin,n.repeat-1)}n.next&&!n.stop&&ae(n.anim,n.el,n.next,null,n.totalOrigin,n.repeat)}}}Kt.length&&te(ee)},re=function(t){return t>255?255:t<0?0:t};function ie(t,e,r,i,n,a){var s=3*e,o=3*(i-e)-s,l=1-s-o,h=3*r,u=3*(n-r)-h,c=1-h-u;function f(t){return((l*t+o)*t+s)*t}return (function(t,e){var r=(function(t,e){var r,i,n,a,h,u;for(n=t,u=0;u<8;u++){if(a=f(n)-t,B(a)i)return i;for(;ra?r=n:i=n,n=(i-r)/2+r}return n}(t,e));return((c*r+u)*r+h)*r}(t,1/(200*a)))}function ne(t,e){var r=[],i={};if(this.ms=e,this.times=1,t){for(var n in t)t[o](n)&&(i[z(n)]=t[n],r.push(z(n)));r.sort(H)}this.anim=i,this.top=r[r.length-1],this.percents=r}function ae(r,i,a,s,l,h){a=z(a);var u,c,p,d,g,y,m=r.ms,b={},_={},w={};if(s)for(B=0,C=Kt.length;Bs*r.top){a=r.percents[B],g=r.percents[B-1]||0,m=m/r.top*(a-g),d=r.percents[B+1],u=r.anim[a];break}s&&i.attr(r.anim[r.percents[B]])}if(u){if(c)c.initstatus=s,c.start=new Date-c.ms*s;else{for(var S in u)if(u[o](S)&&(I[o](S)||i.paper.customAttributes[o](S)))switch(b[S]=i.attr(S),b[S]==null&&(b[S]=j[S]),_[S]=u[S],I[S]){case A: w[S]=(_[S]-b[S])/m;break;case"colour": b[S]=e.getRGB(b[S]);var T=e.getRGB(_[S]);w[S]={r:(T.r-b[S].r)/m,g:(T.g-b[S].g)/m,b:(T.b-b[S].b)/m};break;case"path": var M=At(b[S],_[S]),E=M[1];for(b[S]=M[0],w[S]=[],B=0,C=b[S].length;Bh&&(h=c)}!t[h+="%"].callback&&(t[h].callback=n)}return new ne(t,r)},Yt.animate=function(t,r,i,n){if(this.removed)return n&&n.call(this),this;var a=t instanceof ne?t:e.animation(t,r,i,n);return ae(a,this,a.percents[0],null,this.attr()),this},Yt.setTime=function(t,e){return t&&e!=null&&this.status(t,k(e,t.ms)/t.ms),this},Yt.status=function(t,e){var r,i,n=[],a=0;if(e!=null)return ae(t,this,-1,k(e,1)),this;for(r=Kt.length;a"));var U=H.getBoundingClientRect();A.W=g.w=(U.right-U.left)/100,A.H=g.h=(U.bottom-U.top)/100,A.X=g.x,A.Y=g.y+A.H/2,("x"in l||"y"in l)&&(A.path.v=t.format("m{0},{1}l{2},{1}",a(g.x*y),a(g.y*y),a(g.x*y)+1));for(var $=["x","y","text","font","font-family","font-weight","font-style","font-size"],Z=0,Q=$.length;Z.25&&(r=n.sqrt(.25-o(e-.5,2))*(2*(r>.5)-1)+.5),h=e+c+r),f})).split(/\s*\-\s*/),l=="linear"){var u=a.shift();if(u=-i(u),isNaN(u))return null}var p=t._parseDots(a);if(!p)return null;if(e=e.shape||e.node,p.length){e.removeChild(s),s.on=!0,s.method="none",s.color=p[0].color,s.color2=p[p.length-1].color;for(var d=[],g=0,x=p.length;g')}}catch(t){k=function(t){return e.createElement("<"+t+' xmlns="urn:schemas-microsoft.com:vml" class="rvml">')}}},t._engine.initWin(t._g.win),t._engine.create=function(){var e=t._getContainer.apply(0,arguments),r=e.container,i=e.height,n=e.width,a=e.x,s=e.y;if(!r)throw new Error("VML container not found.");var o=new t._Paper,l=o.canvas=t._g.doc.createElement("div"),h=l.style;return a=a||0,s=s||0,n=n||512,i=i||342,o.width=n,o.height=i,n==+n&&(n+="px"),i==+i&&(i+="px"),o.coordsize=216e5+c+216e5,o.coordorigin="0 0",o.span=t._g.doc.createElement("span"),o.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;",l.appendChild(o.span),h.cssText=t.format("top:0;left:0;width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden",n,i),r==1?(t._g.doc.body.appendChild(l),h.left=a+"px",h.top=s+"px",h.position="absolute"):r.firstChild?r.insertBefore(l,r.firstChild):r.appendChild(l),o.renderfix=function(){},o},t.prototype.clear=function(){t.eve("raphael.clear",this),this.canvas.innerHTML=f,this.span=t._g.doc.createElement("span"),this.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;",this.canvas.appendChild(this.span),this.bottom=this.top=null},t.prototype.remove=function(){for(var e in t.eve("raphael.remove",this),this.canvas.parentNode.removeChild(this.canvas),this)this[e]=typeof this[e]=="function"?t._removedFactory(e):null;return!0};var M=t.st;for(var E in T)T[e](E)&&!M[e](E)&&(M[E]=(function(t){return function(){var e=arguments;return this.forEach(function(r){r[t].apply(r,e)})}}(E)))}}.apply(e,i))||(t.exports=n)},function(t,e,r){var i,n;i=[r(0)],void 0===(n=function(t){if(!t||t.svg){var e="hasOwnProperty",r=String,i=parseFloat,n=parseInt,a=Math,s=a.max,o=a.abs,l=a.pow,h=/[, ]+/,u=t.eve,c="",f=" ",p="http://www.w3.org/1999/xlink",d={block:"M5,0 0,2.5 5,5z",classic:"M5,0 0,2.5 5,5 3.5,3 3.5,2z",diamond:"M2.5,0 5,2.5 2.5,5 0,2.5z",open:"M6,1 1,3.5 6,6",oval:"M2.5,0A2.5,2.5,0,0,1,2.5,5 2.5,2.5,0,0,1,2.5,0z"},g={};t.toString=function(){return"Your browser supports SVG.\nYou are running Raphaël "+this.version};var x=function(i,n){if(n)for(var a in typeof i=="string"&&(i=x(i)),n)n[e](a)&&(a.substring(0,6)=="xlink:"?i.setAttributeNS(p,a.substring(6),r(n[a])):i.setAttribute(a,r(n[a])));else(i=t._g.doc.createElementNS("http://www.w3.org/2000/svg",i)).style&&(i.style.webkitTapHighlightColor="rgba(0,0,0,0)");return i},v=function(e,n){var h="linear",u=e.id+n,f=.5,p=.5,d=e.node,g=e.paper,v=d.style,m=t._g.doc.getElementById(u);if(!m){if(n=(n=r(n).replace(t._radial_gradient,function(t,e,r){if(h="radial",e&&r){f=i(e);var n=2*((p=i(r))>.5)-1;l(f-.5,2)+l(p-.5,2)>.25&&(p=a.sqrt(.25-l(f-.5,2))*n+.5)&&p!=.5&&(p=p.toFixed(5)-1e-5*n)}return c})).split(/\s*\-\s*/),h=="linear"){var b=n.shift();if(b=-i(b),isNaN(b))return null;var _=[0,0,a.cos(t.rad(b)),a.sin(t.rad(b))],w=1/(s(o(_[2]),o(_[3]))||1);_[2]*=w,_[3]*=w,_[2]<0&&(_[0]=-_[2],_[2]=0),_[3]<0&&(_[1]=-_[3],_[3]=0)}var k=t._parseDots(n);if(!k)return null;if(u=u.replace(/[\(\)\s,\xb0#]/g,"_"),e.gradient&&u!=e.gradient.id&&(g.defs.removeChild(e.gradient),delete e.gradient),!e.gradient){m=x(h+"Gradient",{id:u}),e.gradient=m,x(m,h=="radial"?{fx:f,fy:p}:{x1:_[0],y1:_[1],x2:_[2],y2:_[3],gradientTransform:e.matrix.invert()}),g.defs.appendChild(m);for(var B=0,C=k.length;B1?P.opacity/100:P.opacity});case"stroke": P=t.getRGB(g),l.setAttribute(d,P.hex),d=="stroke"&&P[e]("opacity")&&x(l,{"stroke-opacity":P.opacity>1?P.opacity/100:P.opacity}),d=="stroke"&&i._.arrows&&("startString"in i._.arrows&&b(i,i._.arrows.startString),"endString"in i._.arrows&&b(i,i._.arrows.endString,1));break;case"gradient": (i.type=="circle"||i.type=="ellipse"||r(g).charAt()!="r")&&v(i,g);break;case"opacity": u.gradient&&!u[e]("stroke-opacity")&&x(l,{"stroke-opacity":g>1?g/100:g});case"fill-opacity": if(u.gradient){(z=t._g.doc.getElementById(l.getAttribute("fill").replace(/^url\(#|\)$/g,c)))&&(F=z.getElementsByTagName("stop"),x(F[F.length-1],{"stop-opacity":g}));break}default: d=="font-size"&&(g=n(g,10)+"px");var R=d.replace(/(\-.)/g,function(t){return t.substring(1).toUpperCase()});l.style[R]=g,i._.dirty=1,l.setAttribute(d,g)}}B(i,a),l.style.visibility=f},B=function(i,a){if(i.type=="text"&&(a[e]("text")||a[e]("font")||a[e]("font-size")||a[e]("x")||a[e]("y"))){var s=i.attrs,o=i.node,l=o.firstChild?n(t._g.doc.defaultView.getComputedStyle(o.firstChild,c).getPropertyValue("font-size"),10):10;if(a[e]("text")){for(s.text=a.text;o.firstChild;)o.removeChild(o.firstChild);for(var h,u=r(a.text).split("\n"),f=[],p=0,d=u.length;p1)for(var i=0,n=r.length;i { let s: string = e.toString(); @@ -52,18 +52,18 @@ function convert2DArrayToString(arr: any[][]) { export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ { - desc: (n: number) => { + desc: (n: number): string => { return ["A prime factor is a factor that is a prime number.", `What is the largest prime factor of ${n}?`].join(" "); }, difficulty: 1, - gen: () => { + gen: (): number => { return getRandomInt(500, 1e9); }, name: "Find Largest Prime Factor", numTries: 10, - solver: (data: number, ans: string) => { - let fac: number = 2; + solver: (data: number, ans: string): boolean => { + let fac = 2; let n: number = data; while (n > ((fac-1) * (fac-1))) { while (n % fac === 0) { @@ -76,18 +76,18 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ }, }, { - desc: (n: number[]) => { + desc: (n: number[]): string => { return ["Given the following integer array, find the contiguous subarray", "(containing at least one number) which has the largest sum and return that sum.", "'Sum' refers to the sum of all the numbers in the subarray.\n", `${n.toString()}`].join(" "); }, difficulty: 1, - gen: () => { + gen: (): number[] => { const len: number = getRandomInt(5, 40); const arr: number[] = []; arr.length = len; - for (let i: number = 0; i < len; ++i) { + for (let i = 0; i < len; ++i) { arr[i] = getRandomInt(-10, 10); } @@ -95,9 +95,9 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ }, name: "Subarray with Maximum Sum", numTries: 10, - solver: (data: number[], ans: string) => { + solver: (data: number[], ans: string): boolean => { const nums: number[] = data.slice(); - for (let i: number = 1; i < nums.length; i++) { + for (let i = 1; i < nums.length; i++) { nums[i] = Math.max(nums[i], nums[i] + nums[i - 1]); } @@ -105,7 +105,7 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ }, }, { - desc: (n: number) => { + desc: (n: number): string => { return ["It is possible write four as a sum in exactly four different ways:\n\n", " 3 + 1\n", " 2 + 2\n", @@ -115,16 +115,16 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ "two positive integers?"].join(" "); }, difficulty: 1.5, - gen: () => { + gen: (): number => { return getRandomInt(8, 100); }, name: "Total Ways to Sum", numTries: 10, - solver: (data: number, ans: string) => { + solver: (data: number, ans: string): boolean => { const ways: number[] = [1]; ways.length = data + 1; ways.fill(0, 1); - for (let i: number = 1; i < data; ++i) { + for (let i = 1; i < data; ++i) { for (let j: number = i; j <= data; ++j) { ways[j] += ways[j - i]; } @@ -134,7 +134,7 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ }, }, { - desc: (n: number[][]) => { + desc: (n: number[][]): string => { let d: string = ["Given the following array of array of numbers representing a 2D matrix,", "return the elements of the matrix as an array in spiral order:\n\n"].join(" "); for (const line of n) { @@ -157,18 +157,18 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ return d; }, difficulty: 2, - gen: () => { + gen: (): number[][] => { const m: number = getRandomInt(1, 15); const n: number = getRandomInt(1, 15); const matrix: number[][] = []; matrix.length = m; - for (let i: number = 0; i < m; ++i) { + for (let i = 0; i < m; ++i) { matrix[i] = []; matrix[i].length = n; } - for (let i: number = 0; i < m; ++i) { - for (let j: number = 0; j < n; ++j) { + for (let i = 0; i < m; ++i) { + for (let j = 0; j < n; ++j) { matrix[i][j] = getRandomInt(1, 50); } } @@ -177,15 +177,15 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ }, name: "Spiralize Matrix", numTries: 10, - solver: (data: number[][], ans: string) => { + solver: (data: number[][], ans: string): boolean => { const spiral: number[] = []; const m: number = data.length; const n: number = data[0].length; - let u: number = 0; + let u = 0; let d: number = m - 1; - let l: number = 0; + let l = 0; let r: number = n - 1; - let k: number = 0; + let k = 0; while (true) { // Up for (let col: number = l; col <= r; col++) { @@ -219,11 +219,11 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ const sanitizedPlayerAns: string = removeBracketsFromArrayString(ans) .replace(/\s/g, ""); const playerAns: any[] = sanitizedPlayerAns.split(","); - for (let i: number = 0; i < playerAns.length; ++i) { + for (let i = 0; i < playerAns.length; ++i) { playerAns[i] = parseInt(playerAns[i], 10); } if (spiral.length !== playerAns.length) { return false; } - for (let i: number = 0; i < spiral.length; ++i) { + for (let i = 0; i < spiral.length; ++i) { if (spiral[i] !== playerAns[i]) { return false; } @@ -233,7 +233,7 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ }, }, { - desc: (arr: number[]) => { + desc: (arr: number[]): string => { return ["You are given the following array of integers:\n\n", `${arr}\n\n`, "Each element in the array represents your MAXIMUM jump length", @@ -246,11 +246,11 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ "Your answer should be submitted as 1 or 0, representing true and false respectively"].join(" "); }, difficulty: 2.5, - gen: () => { + gen: (): number[] => { const len: number = getRandomInt(3, 25); const arr: number[] = []; arr.length = len; - for (let i: number = 0; i < arr.length; ++i) { + for (let i = 0; i < arr.length; ++i) { if (Math.random() < 0.2) { arr[i] = 0; // 20% chance of being 0 } else { @@ -262,10 +262,10 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ }, name: "Array Jumping Game", numTries: 1, - solver: (data: number[], ans: string) => { + solver: (data: number[], ans: string): boolean => { const n: number = data.length; - let i: number = 0; - for (let reach: number = 0; i < n && i <= reach; ++i) { + let i = 0; + for (let reach = 0; i < n && i <= reach; ++i) { reach = Math.max(i + data[i], reach); } const solution: boolean = (i === n); @@ -277,7 +277,7 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ }, }, { - desc: (arr: number[][]) => { + desc: (arr: number[][]): string => { return ["Given the following array of array of numbers representing a list of", "intervals, merge all overlapping intervals.\n\n", `[${convert2DArrayToString(arr)}]\n\n`, @@ -289,10 +289,10 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ "smaller than the second."].join(" "); }, difficulty: 3, - gen: () => { + gen: (): number[][] => { const intervals: number[][] = []; const numIntervals: number = getRandomInt(3, 20); - for (let i: number = 0; i < numIntervals; ++i) { + for (let i = 0; i < numIntervals; ++i) { const start: number = getRandomInt(1, 25); const end: number = start + getRandomInt(1, 10); intervals.push([start, end]); @@ -302,7 +302,7 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ }, name: "Merge Overlapping Intervals", numTries: 15, - solver: (data: number[][], ans: string) => { + solver: (data: number[][], ans: string): boolean => { const intervals: number[][] = data.slice(); intervals.sort((a: number[], b: number[]) => { return a[0] - b[0]; @@ -330,7 +330,7 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ }, }, { - desc: (data: string) => { + desc: (data: string): string => { return ["Given the following string containing only digits, return", "an array with all possible valid IP address combinations", "that can be created from the string:\n\n", @@ -342,9 +342,9 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ "1938718066 -> [193.87.180.66]"].join(" "); }, difficulty: 3, - gen: () => { - let str: string = ""; - for (let i: number = 0; i < 4; ++i) { + gen: (): string => { + let str = ""; + for (let i = 0; i < 4; ++i) { const num: number = getRandomInt(0, 255); const convNum: string = num.toString(); str += convNum; @@ -354,12 +354,12 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ }, name: "Generate IP Addresses", numTries: 10, - solver: (data: string, ans: string) => { + solver: (data: string, ans: string): boolean => { const ret: string[] = []; - for (let a: number = 1; a <= 3; ++a) { - for (let b: number = 1; b <= 3; ++b) { - for (let c: number = 1; c <= 3; ++c) { - for (let d: number = 1; d <= 3; ++d) { + for (let a = 1; a <= 3; ++a) { + for (let b = 1; b <= 3; ++b) { + for (let c = 1; c <= 3; ++c) { + for (let d = 1; d <= 3; ++d) { if (a + b + c + d === data.length) { const A: number = parseInt(data.substring(0, a), 10); const B: number = parseInt(data.substring(a, a + b), 10); @@ -392,7 +392,7 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ }, }, { - desc: (data: number[]) => { + desc: (data: number[]): string => { return ["You are given the following array of stock prices (which are numbers)", "where the i-th element represents the stock price on day i:\n\n", `${data}\n\n`, @@ -402,11 +402,11 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ "that you have to buy the stock before you can sell it"].join(" "); }, difficulty: 1, - gen: () => { + gen: (): number[] => { const len: number = getRandomInt(3, 50); const arr: number[] = []; arr.length = len; - for (let i: number = 0; i < len; ++i) { + for (let i = 0; i < len; ++i) { arr[i] = getRandomInt(1, 200); } @@ -414,10 +414,10 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ }, name: "Algorithmic Stock Trader I", numTries: 5, - solver: (data: number[], ans: string) => { - let maxCur: number = 0; - let maxSoFar: number = 0; - for (let i: number = 1; i < data.length; ++i) { + solver: (data: number[], ans: string): boolean => { + let maxCur = 0; + let maxSoFar = 0; + for (let i = 1; i < data.length; ++i) { maxCur = Math.max(0, maxCur += data[i] - data[i - 1]); maxSoFar = Math.max(maxCur, maxSoFar); } @@ -426,7 +426,7 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ }, }, { - desc: (data: number[]) => { + desc: (data: number[]): string => { return ["You are given the following array of stock prices (which are numbers)", "where the i-th element represents the stock price on day i:\n\n", `${data}\n\n`, @@ -438,11 +438,11 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ "If no profit can be made, then the answer should be 0"].join(" "); }, difficulty: 2, - gen: () => { + gen: (): number[] => { const len: number = getRandomInt(3, 50); const arr: number[] = []; arr.length = len; - for (let i: number = 0; i < len; ++i) { + for (let i = 0; i < len; ++i) { arr[i] = getRandomInt(1, 200); } @@ -450,9 +450,9 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ }, name: "Algorithmic Stock Trader II", numTries: 10, - solver: (data: number[], ans: string) => { - let profit: number = 0; - for (let p: number = 1; p < data.length; ++p) { + solver: (data: number[], ans: string): boolean => { + let profit = 0; + for (let p = 1; p < data.length; ++p) { profit += Math.max(data[p] - data[p - 1], 0); } @@ -460,7 +460,7 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ }, }, { - desc: (data: number[]) => { + desc: (data: number[]): string => { return ["You are given the following array of stock prices (which are numbers)", "where the i-th element represents the stock price on day i:\n\n", `${data}\n\n`, @@ -472,11 +472,11 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ "If no profit can be made, then the answer should be 0"].join(" "); }, difficulty: 5, - gen: () => { + gen: (): number[] => { const len: number = getRandomInt(3, 50); const arr: number[] = []; arr.length = len; - for (let i: number = 0; i < len; ++i) { + for (let i = 0; i < len; ++i) { arr[i] = getRandomInt(1, 200); } @@ -484,11 +484,11 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ }, name: "Algorithmic Stock Trader III", numTries: 10, - solver: (data: number[], ans: string) => { + solver: (data: number[], ans: string): boolean => { let hold1: number = Number.MIN_SAFE_INTEGER; let hold2: number = Number.MIN_SAFE_INTEGER; - let release1: number = 0; - let release2: number = 0; + let release1 = 0; + let release2 = 0; for (const price of data) { release2 = Math.max(release2, hold2 + price); hold2 = Math.max(hold2, release1 - price); @@ -500,7 +500,7 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ }, }, { - desc: (data: any[]) => { + desc: (data: any[]): string => { const k: number = (data[0]); const prices: number[] = (data[1]); return ["You are given the following array with two elements:\n\n", @@ -516,7 +516,7 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ "If no profit can be made, then the answer should be 0."].join(" "); }, difficulty: 8, - gen: () => { + gen: (): any[] => { const k: number = getRandomInt(2, 10); const len: number = getRandomInt(3, 50); const prices: number[] = []; @@ -529,14 +529,14 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ }, name: "Algorithmic Stock Trader IV", numTries: 10, - solver: (data: any[], ans: string) => { + solver: (data: any[], ans: string): boolean => { const k: number = (data[0]); const prices: number[] = (data[1]); const len = prices.length; if (len < 2) { return (parseInt(ans) === 0); } if (k > len / 2) { - let res: number = 0; + let res = 0; for (let i = 1; i < len; ++i) { res += Math.max(prices[i] - prices[i-1], 0); } @@ -566,8 +566,8 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ }, }, { - desc: (data: number[][]) => { - function createTriangleRecurse(data: number[][], level: number = 0): string { + desc: (data: number[][]): string => { + function createTriangleRecurse(data: number[][], level = 0): string { const numLevels: number = data.length; if (level >= numLevels) { return ""; } const numSpaces = numLevels - level + 1; @@ -580,7 +580,7 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ return str + "\n" + createTriangleRecurse(data, level+1); } - function createTriangle(data: number[][]) { + function createTriangle(data: number[][]): string { return ["[\n", createTriangleRecurse(data), "]"].join(""); } @@ -600,7 +600,7 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ "The minimum path sum is 11 (2 -> 3 -> 5 -> 1)."].join(" "); }, difficulty: 5, - gen: () => { + gen: (): number[][] => { const triangle: number[][] = []; const levels: number = getRandomInt(3, 12); triangle.length = levels; @@ -617,9 +617,9 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ }, name: "Minimum Path Sum in a Triangle", numTries: 10, - solver: (data: number[][], ans: string) => { - let n: number = data.length; - let dp: number[] = data[n-1].slice(); + solver: (data: number[][], ans: string): boolean => { + const n: number = data.length; + const dp: number[] = data[n-1].slice(); for (let i = n-2; i > -1; --i) { for (let j = 0; j < data[i].length; ++j) { dp[j] = Math.min(dp[j], dp[j + 1]) + data[i][j]; @@ -630,7 +630,7 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ }, }, { - desc: (data: number[]) => { + desc: (data: number[]): string => { const numRows = data[0]; const numColumns = data[1]; return ["You are in a grid with", @@ -644,7 +644,7 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ `[${numRows}, ${numColumns}]`].join(" "); }, difficulty: 3, - gen: () => { + gen: (): number[] => { const numRows: number = getRandomInt(2, 14); const numColumns: number = getRandomInt(2, 14); @@ -652,10 +652,10 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ }, name: "Unique Paths in a Grid I", numTries: 10, - solver: (data: number[], ans: string) => { - let n: number = data[0]; // Number of rows - let m: number = data[1]; // Number of columns - let currentRow: number[] = []; + solver: (data: number[], ans: string): boolean => { + const n: number = data[0]; // Number of rows + const m: number = data[1]; // Number of columns + const currentRow: number[] = []; currentRow.length = n; for (let i = 0; i < n; i++) { @@ -671,8 +671,8 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ }, }, { - desc: (data: number[][]) => { - let gridString: string = ""; + desc: (data: number[][]): string => { + let gridString = ""; for (const line of data) { gridString += `${line.toString()},\n`; } @@ -686,7 +686,7 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ "NOTE: The data returned for this contract is an 2D array of numbers representing the grid."].join(" "); }, difficulty: 5, - gen: () => { + gen: (): number[][] => { const numRows: number = getRandomInt(2, 12); const numColumns: number = getRandomInt(2, 12); @@ -714,8 +714,8 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ }, name: "Unique Paths in a Grid II", numTries: 10, - solver: (data: number[][], ans: string) => { - let obstacleGrid: number[][] = []; + solver: (data: number[][], ans: string): boolean => { + const obstacleGrid: number[][] = []; obstacleGrid.length = data.length; for (let i = 0; i < obstacleGrid.length; ++i) { obstacleGrid[i] = data[i].slice(); @@ -738,7 +738,7 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ }, }, { - desc: (data: string) => { + desc: (data: string): string => { return ["Given the following string:\n\n", `${data}\n\n`, "remove the minimum number of invalid parentheses in order to validate", @@ -753,9 +753,9 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ `")( -> [""]`].join(" "); }, difficulty: 10, - gen: () => { + gen: (): string => { const len: number = getRandomInt(6, 20); - let chars: string[] = []; + const chars: string[] = []; chars.length = len; // 80% chance of the first parenthesis being ( @@ -776,10 +776,10 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ }, name: "Sanitize Parentheses in Expression", numTries: 10, - solver: (data: string, ans: string) => { + solver: (data: string, ans: string): boolean => { let left = 0; let right = 0; - let res: string[] = []; + const res: string[] = []; for (let i = 0; i < data.length; ++i) { if (data[i] === '(') { @@ -789,10 +789,10 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ } } - function dfs(pair: number, index: number, left: number, right: number, s: string, solution: string, res: string[]) { + function dfs(pair: number, index: number, left: number, right: number, s: string, solution: string, res: string[]): void { if (s.length === index) { if (left === 0 && right === 0 && pair === 0) { - for(var i = 0; i < res.length; i++) { + for(let i = 0; i < res.length; i++) { if(res[i] === solution) { return; } } res.push(solution); @@ -828,7 +828,7 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ }, }, { - desc: (data: any[]) => { + desc: (data: any[]): string => { const digits: string = data[0]; const target: number = data[1]; @@ -850,7 +850,7 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ `Output: [1*0+5, 10-5]`].join(" "); }, difficulty: 10, - gen: () => { + gen: (): any[] => { const numDigits = getRandomInt(4, 12); const digitsArray: string[] = []; digitsArray.length = numDigits; @@ -869,11 +869,11 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ }, name: "Find All Valid Math Expressions", numTries: 10, - solver: (data: any[], ans: string) => { + solver: (data: any[], ans: string): boolean => { const num: string = data[0]; const target: number = data[1]; - function helper(res: string[], path: string, num: string, target: number, pos: number, evaluated: number, multed: number) { + function helper(res: string[], path: string, num: string, target: number, pos: number, evaluated: number, multed: number): void { if (pos === num.length) { if (target === evaluated) { res.push(path); @@ -883,7 +883,7 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ for (let i = pos; i < num.length; ++i) { if (i != pos && num[pos] == '0') { break; } - let cur = parseInt(num.substring(pos, i+1)); + const cur = parseInt(num.substring(pos, i+1)); if (pos === 0) { helper(res, path + cur, num, target, i + 1, cur, cur); @@ -899,7 +899,7 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ const sanitizedPlayerAnsArr: string[] = sanitizedPlayerAns.split(","); for (let i = 0; i < sanitizedPlayerAnsArr.length; ++i) { sanitizedPlayerAnsArr[i] = removeQuotesFromString(sanitizedPlayerAnsArr[i]) - .replace(/\s/g, "");; + .replace(/\s/g, ""); } if (num == null || num.length === 0) { @@ -908,7 +908,7 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ return false; } - let result: string[] = []; + const result: string[] = []; helper(result, "", num, target, 0, 0, 0); for (const expr of result) { diff --git a/src/data/gangmembertasks.ts b/src/data/gangmembertasks.ts index 16732c5ab..9aefa0059 100644 --- a/src/data/gangmembertasks.ts +++ b/src/data/gangmembertasks.ts @@ -146,9 +146,9 @@ export const gangMemberTasksMetadata: IGangMemberTaskMetadata[] = [ territory: { money: 1.6, respect: 1.1, - wanted: 1.5 - } - } + wanted: 1.5, + }, + }, }, { desc: "Assign this gang member to run cons

    Earns money - Increases respect - Increases wanted level", @@ -212,8 +212,8 @@ export const gangMemberTasksMetadata: IGangMemberTaskMetadata[] = [ money: 1.5, respect: 1.5, wanted: 1.6, - } - } + }, + }, }, { desc: "Assign this gang member to commit acts of terrorism

    Greatly increases respect - Greatly increases wanted level - Scales heavily with territory", @@ -254,7 +254,7 @@ export const gangMemberTasksMetadata: IGangMemberTaskMetadata[] = [ name: "Train Combat", params: { strWeight: 25, defWeight: 25, dexWeight: 25, agiWeight: 25, - difficulty: 5 + difficulty: 5, }, }, { @@ -278,7 +278,7 @@ export const gangMemberTasksMetadata: IGangMemberTaskMetadata[] = [ name: "Territory Warfare", params: { hackWeight: 15, strWeight: 20, defWeight: 20, dexWeight: 20, agiWeight: 20, chaWeight: 5, - difficulty: 5 + difficulty: 5, }, }, ]; diff --git a/src/engine.jsx b/src/engine.jsx index 06dc0b1e9..5e7dae147 100644 --- a/src/engine.jsx +++ b/src/engine.jsx @@ -5,7 +5,7 @@ */ import { convertTimeMsToTimeElapsedString, - replaceAt + replaceAt, } from "../utils/StringHelperFunctions"; import { logBoxUpdateText, logBoxOpened } from "../utils/LogBox"; import { Augmentations } from "./Augmentation/Augmentations"; @@ -15,7 +15,7 @@ import { } from "./Augmentation/AugmentationHelpers"; import { AugmentationNames } from "./Augmentation/data/AugmentationNames"; import { - initBitNodeMultipliers + initBitNodeMultipliers, } from "./BitNode/BitNode"; import { Bladeburner } from "./Bladeburner"; import { CharacterOverviewComponent } from "./ui/React/CharacterOverview"; @@ -30,14 +30,14 @@ import { displayFactionContent, joinFaction, processPassiveFactionRepGain, - inviteToFaction + inviteToFaction, } from "./Faction/FactionHelpers"; import { FconfSettings } from "./Fconf/FconfSettings"; import { hasHacknetServers, renderHacknetNodesUI, clearHacknetNodesUI, - processHacknetEarnings + processHacknetEarnings, } from "./Hacknet/HacknetHelpers"; import { iTutorialStart } from "./InteractiveTutorial"; import { LocationName } from "./Locations/data/LocationNames"; @@ -54,14 +54,14 @@ import { prestigeAugmentation } from "./Prestige"; import { displayCreateProgramContent, getNumAvailableCreateProgram, - initCreateProgramButtons + initCreateProgramButtons, } from "./Programs/ProgramHelpers"; import { redPillFlag } from "./RedPill"; import { saveObject, loadGame } from "./SaveObject"; import { getCurrentEditor, scriptEditorInit, - updateScriptEditorContent + updateScriptEditorContent, } from "./Script/ScriptHelpers"; import { initForeignServers } from "./Server/AllServers"; import { Settings } from "./Settings/Settings"; @@ -70,7 +70,7 @@ import { initSpecialServerIps } from "./Server/SpecialServerIps"; import { initSymbolToStockMap, processStockPrices, - displayStockMarketContent + displayStockMarketContent, } from "./StockMarket/StockMarket"; import { displayMilestonesContent } from "./Milestones/MilestoneHelpers"; import { Terminal, postNetburnerText } from "./Terminal"; @@ -78,17 +78,16 @@ import { Sleeve } from "./PersonObjects/Sleeve/Sleeve"; import { clearSleevesPage, createSleevesPage, - updateSleevesPage + updateSleevesPage, } from "./PersonObjects/Sleeve/SleeveUI"; import { clearResleevesPage, - createResleevesPage + createResleevesPage, } from "./PersonObjects/Resleeving/ResleevingUI"; import { createStatusText } from "./ui/createStatusText"; import { CharacterInfo } from "./ui/CharacterInfo"; import { Page, routing } from "./ui/navigationTracking"; -import { numeralWrapper } from "./ui/numeralFormat"; import { setSettingsLabels } from "./ui/setSettingsLabels"; import { Money } from "./ui/React/Money"; import { Hashes } from "./ui/React/Hashes"; @@ -134,7 +133,7 @@ $(document).keydown(function(e) { if (getCurrentEditor().isFocused()) { return; } - } catch(e) {} + } catch(error) {} if (!Player.isWorking && !redPillFlag && !inMission && !cinematicTextFlag) { if (e.keyCode == KEY.T && e.altKey) { @@ -270,7 +269,7 @@ const Engine = { routing.navigateTo(Page.ActiveScripts); ReactDOM.render( , - Engine.Display.activeScriptsContent + Engine.Display.activeScriptsContent, ) MainMenuLinks.ActiveScripts.classList.add("active"); }, @@ -590,10 +589,10 @@ const Engine = { // Factions Engine.Display.factionsContent.appendChild(createElement("h1", { - innerText:"Factions" + innerText:"Factions", })); Engine.Display.factionsContent.appendChild(createElement("p", { - innerText:"Lists all factions you have joined" + innerText:"Lists all factions you have joined", })); var factionsList = createElement("ul"); Engine.Display.factionsContent.appendChild(createElement("br")); @@ -610,7 +609,7 @@ const Engine = { Engine.loadFactionContent(); displayFactionContent(factionName); return false; - } + }, })); factionsList.appendChild(createElement("br")); }()); // Immediate invocation @@ -620,12 +619,12 @@ const Engine = { // Invited Factions Engine.Display.factionsContent.appendChild(createElement("h1", { - innerText:"Outstanding Faction Invitations" + innerText:"Outstanding Faction Invitations", })); Engine.Display.factionsContent.appendChild(createElement("p", { width:"70%", innerText:"Lists factions you have been invited to. You can accept " + - "these faction invitations at any time." + "these faction invitations at any time.", })); var invitationsList = createElement("ul"); @@ -636,7 +635,7 @@ const Engine = { var item = createElement("li", {padding:"6px", margin:"6px"}); item.appendChild(createElement("p", { - innerText:factionName, display:"inline", margin:"4px", padding:"4px" + innerText:factionName, display:"inline", margin:"4px", padding:"4px", })); item.appendChild(createElement("a", { innerText:"Accept Faction Invitation", @@ -652,7 +651,7 @@ const Engine = { } Engine.displayFactionsInfo(); return false; - } + }, })); invitationsList.appendChild(item); @@ -829,7 +828,7 @@ const Engine = { if (routing.isOn(Page.ActiveScripts)) { ReactDOM.render( , - Engine.Display.activeScriptsContent + Engine.Display.activeScriptsContent, ) } @@ -1229,7 +1228,7 @@ const Engine = { Engine.openMainMenuHeader( [terminal, createScript, activeScripts, stats, hacknetnodes, city, milestones, - tutorial, options] + tutorial, options], ); // Start interactive tutorial @@ -1474,7 +1473,6 @@ const Engine = { var cancelButton = document.getElementById("work-in-progress-cancel-button"); cancelButton.addEventListener("click", function() { if (Player.workType == CONSTANTS.WorkTypeFaction) { - var fac = Factions[Player.currentWorkFactionName]; Player.finishFactionWork(true); } else if (Player.workType == CONSTANTS.WorkTypeCreateProgram) { Player.finishCreateProgramWork(true); @@ -1534,7 +1532,8 @@ const Engine = { // Use the Async Clipboard API navigator.clipboard.writeText(saveString).then(function() { createStatusText("Copied save to clipboard"); - }, function(e) { + }, function(err) { + console.error(err); console.error("Unable to copy save data to clipboard using Async API"); createStatusText("Failed to copy save"); }) @@ -1561,7 +1560,7 @@ const Engine = { start: function() { // Run main loop Engine.idleTimer(); - } + }, }; var indexedDb, indexedDbRequest; @@ -1593,14 +1592,14 @@ window.onload = function() { return Engine.load(null); // Try to load from localstorage } - request.onsuccess = function(e) { + request.onsuccess = function() { Engine.load(request.result); } }; indexedDbRequest.onupgradeneeded = function(e) { - var db = e.target.result; - var objectStore = db.createObjectStore("savestring"); + const db = e.target.result; + db.createObjectStore("savestring"); } }; diff --git a/src/ui/ActiveScripts/Root.tsx b/src/ui/ActiveScripts/Root.tsx index 00ac8bbbb..d18dec637 100644 --- a/src/ui/ActiveScripts/Root.tsx +++ b/src/ui/ActiveScripts/Root.tsx @@ -20,7 +20,7 @@ export class ActiveScriptsRoot extends React.Component { super(props); } - render() { + render(): React.ReactNode { return ( <>

    diff --git a/src/ui/ActiveScripts/ScriptProduction.tsx b/src/ui/ActiveScripts/ScriptProduction.tsx index 3f9d51f60..d82d430dc 100644 --- a/src/ui/ActiveScripts/ScriptProduction.tsx +++ b/src/ui/ActiveScripts/ScriptProduction.tsx @@ -4,8 +4,6 @@ */ import * as React from "react"; -import { numeralWrapper } from "../numeralFormat"; - import { WorkerScript } from "../../Netscript/WorkerScript"; import { IPlayer } from "../../PersonObjects/IPlayer"; import { Money } from "../React/Money"; diff --git a/src/ui/ActiveScripts/ServerAccordion.tsx b/src/ui/ActiveScripts/ServerAccordion.tsx index 9a0d1c57f..35a78e6a2 100644 --- a/src/ui/ActiveScripts/ServerAccordion.tsx +++ b/src/ui/ActiveScripts/ServerAccordion.tsx @@ -26,7 +26,7 @@ export function ServerAccordion(props: IProps): React.ReactElement { const paddedName = `${server.hostname}${" ".repeat(longestHostnameLength)}`.slice(0, Math.max(server.hostname.length, longestHostnameLength)); const barOptions = { progress: server.ramUsed / server.maxRam, - totalTicks: 30 + totalTicks: 30, }; const headerTxt = `${paddedName} ${createProgressBarText(barOptions)}`; diff --git a/src/ui/ActiveScripts/ServerAccordions.tsx b/src/ui/ActiveScripts/ServerAccordions.tsx index acd279870..6368eef89 100644 --- a/src/ui/ActiveScripts/ServerAccordions.tsx +++ b/src/ui/ActiveScripts/ServerAccordions.tsx @@ -47,14 +47,14 @@ export class ServerAccordions extends React.Component { this.rerender = this.rerender.bind(this); } - componentDidMount() { + componentDidMount(): void { WorkerScriptStartStopEventEmitter.addSubscriber({ cb: this.rerender, id: subscriberId, }) } - componentWillUnmount() { + componentWillUnmount(): void { WorkerScriptStartStopEventEmitter.removeSubscriber(subscriberId); } @@ -81,14 +81,14 @@ export class ServerAccordions extends React.Component { this.serverToScriptMap = map; } - rerender() { + rerender(): void { this.updateServerToScriptsMap(); this.setState((prevState) => { return { rerenderFlag: !prevState.rerenderFlag } }); } - render() { + render(): React.ReactNode { const elems = Object.keys(this.serverToScriptMap).map((serverName) => { const data = this.serverToScriptMap[serverName]; return ( diff --git a/src/ui/ActiveScripts/WorkerScriptAccordion.tsx b/src/ui/ActiveScripts/WorkerScriptAccordion.tsx index c62546bb8..f084f659f 100644 --- a/src/ui/ActiveScripts/WorkerScriptAccordion.tsx +++ b/src/ui/ActiveScripts/WorkerScriptAccordion.tsx @@ -29,7 +29,7 @@ export function WorkerScriptAccordion(props: IProps): React.ReactElement { const logClickHandler = logBoxCreate.bind(null, scriptRef); const killScript = killWorkerScript.bind(null, scriptRef as any, scriptRef.server); - function killScriptClickHandler() { + function killScriptClickHandler(): void { killScript(); dialogBoxCreate("Killing script"); } diff --git a/src/ui/CharacterInfo.tsx b/src/ui/CharacterInfo.tsx index 03b84f3fc..fbd98f6cf 100644 --- a/src/ui/CharacterInfo.tsx +++ b/src/ui/CharacterInfo.tsx @@ -47,25 +47,25 @@ export function CharacterInfo(p: IPlayer): React.ReactElement { } function convertMoneySourceTrackerToString(src: MoneySourceTracker): React.ReactElement { - let parts: any[][] = [[`Total:`, Money(src.total)]]; - if (src.bladeburner) { parts.push([`Bladeburner:`, Money(src.bladeburner)]) }; - if (src.codingcontract) { parts.push([`Coding Contracts:`, Money(src.codingcontract)]) }; - if (src.work) { parts.push([`Company Work:`, Money(src.work)]) }; - if (src.class) { parts.push([`Class:`, Money(src.class)]) }; - if (src.corporation) { parts.push([`Corporation:`, Money(src.corporation)]) }; - if (src.crime) { parts.push([`Crimes:`, Money(src.crime)]) }; - if (src.gang) { parts.push([`Gang:`, Money(src.gang)]) }; - if (src.hacking) { parts.push([`Hacking:`, Money(src.hacking)]) }; - if (src.hacknetnode) { parts.push([`Hacknet Nodes:`, Money(src.hacknetnode)]) }; - if (src.hospitalization) { parts.push([`Hospitalization:`, Money(src.hospitalization)]) }; - if (src.infiltration) { parts.push([`Infiltration:`, Money(src.infiltration)]) }; - if (src.stock) { parts.push([`Stock Market:`, Money(src.stock)]) }; - if (src.casino) { parts.push([`Casino:`, Money(src.casino)]) }; + const parts: any[][] = [[`Total:`, Money(src.total)]]; + if (src.bladeburner) { parts.push([`Bladeburner:`, Money(src.bladeburner)]) } + if (src.codingcontract) { parts.push([`Coding Contracts:`, Money(src.codingcontract)]) } + if (src.work) { parts.push([`Company Work:`, Money(src.work)]) } + if (src.class) { parts.push([`Class:`, Money(src.class)]) } + if (src.corporation) { parts.push([`Corporation:`, Money(src.corporation)]) } + if (src.crime) { parts.push([`Crimes:`, Money(src.crime)]) } + if (src.gang) { parts.push([`Gang:`, Money(src.gang)]) } + if (src.hacking) { parts.push([`Hacking:`, Money(src.hacking)]) } + if (src.hacknetnode) { parts.push([`Hacknet Nodes:`, Money(src.hacknetnode)]) } + if (src.hospitalization) { parts.push([`Hospitalization:`, Money(src.hospitalization)]) } + if (src.infiltration) { parts.push([`Infiltration:`, Money(src.infiltration)]) } + if (src.stock) { parts.push([`Stock Market:`, Money(src.stock)]) } + if (src.casino) { parts.push([`Casino:`, Money(src.casino)]) } return StatsTable(parts, ""); } - function openMoneyModal() { + function openMoneyModal(): void { let content = (<> Money earned since you last installed Augmentations:
    {convertMoneySourceTrackerToString(p.moneySourceA)} @@ -80,7 +80,7 @@ export function CharacterInfo(p: IPlayer): React.ReactElement { function Intelligence(): React.ReactElement { if (p.intelligence > 0) { - return + return Intelligence: {numeralWrapper.formatSkill(p.intelligence)} ; @@ -89,9 +89,9 @@ export function CharacterInfo(p: IPlayer): React.ReactElement { } function MultiplierTable(props: any): React.ReactElement { - function bn5Stat(r: any) { + function bn5Stat(r: any): JSX.Element { if(SourceFileFlags[5] > 0 && r.length > 2 && r[1] != r[2]) { - return ({numeralWrapper.formatPercentage(r[2])}) + return ({numeralWrapper.formatPercentage(r[2])}) } return <>; } @@ -99,8 +99,8 @@ export function CharacterInfo(p: IPlayer): React.ReactElement { {props.rows.map((r: any) => - - + + {bn5Stat(r)} )} @@ -146,35 +146,35 @@ export function CharacterInfo(p: IPlayer): React.ReactElement { Stats
    {`${r[0]} multiplier:`}{numeralWrapper.formatPercentage(r[1])}{`${r[0]} multiplier:`}{numeralWrapper.formatPercentage(r[1])}
    - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + @@ -184,7 +184,7 @@ export function CharacterInfo(p: IPlayer): React.ReactElement { ['Hacking Chance', p.hacking_chance_mult], ['Hacking Speed', p.hacking_speed_mult], ['Hacking Money', p.hacking_money_mult, p.hacking_money_mult*BitNodeMultipliers.ScriptHackMoney], - ['Hacking Growth', p.hacking_grow_mult, p.hacking_grow_mult*BitNodeMultipliers.ServerGrowthRate] + ['Hacking Growth', p.hacking_grow_mult, p.hacking_grow_mult*BitNodeMultipliers.ServerGrowthRate], ]} />









    Misc.

    diff --git a/src/ui/MainMenu/Headers.ts b/src/ui/MainMenu/Headers.ts index 09931f15b..6e076285f 100644 --- a/src/ui/MainMenu/Headers.ts +++ b/src/ui/MainMenu/Headers.ts @@ -17,8 +17,8 @@ export const MainMenuHeaders: IMainMenuHeaders = { } // Implements collapsible toggle feature when a header is clicked -function toggleHeader(open: boolean, elems: HTMLElement[], links: HTMLElement[]) { - for (var i = 0; i < elems.length; ++i) { +function toggleHeader(open: boolean, elems: HTMLElement[], links: HTMLElement[]): void { + for (let i = 0; i < elems.length; ++i) { if (open) { elems[i].style.opacity = "1"; elems[i].style.maxHeight = elems[i].scrollHeight + "px"; @@ -28,7 +28,7 @@ function toggleHeader(open: boolean, elems: HTMLElement[], links: HTMLElement[]) } } - for (var i = 0; i < links.length; ++i) { + for (let i = 0; i < links.length; ++i) { if (open) { links[i].style.opacity = "1"; links[i].style.maxHeight = links[i].scrollHeight + "px"; @@ -48,7 +48,7 @@ export function initializeMainMenuHeaders(p: IPlayer, dev = false): boolean { throw new Error(`Failed to find element with id ${id} in initializeMainMenuHeaders()`); } - return elem!; + return elem; } try { @@ -71,7 +71,7 @@ export function initializeMainMenuHeaders(p: IPlayer, dev = false): boolean { (this as any).classList.toggle("opened"); const elems: HTMLElement[] = [terminal, createScript, activeScripts, createProgram]; - const links: HTMLElement[] = [MainMenuLinks.Terminal!, MainMenuLinks.ScriptEditor!, MainMenuLinks.ActiveScripts!, MainMenuLinks.CreateProgram!]; + const links: HTMLElement[] = [MainMenuLinks.Terminal, MainMenuLinks.ScriptEditor, MainMenuLinks.ActiveScripts, MainMenuLinks.CreateProgram]; if (terminal.style.maxHeight) { toggleHeader(false, elems, links); createProgramNot.style.display = "none"; @@ -93,7 +93,7 @@ export function initializeMainMenuHeaders(p: IPlayer, dev = false): boolean { (this as any).classList.toggle("opened"); const elems: HTMLElement[] = [stats, factions, augmentations, hacknetnodes, sleeves]; - const links: HTMLElement[] = [MainMenuLinks.Stats!, MainMenuLinks.Factions!, MainMenuLinks.Augmentations!, MainMenuLinks.HacknetNodes!, MainMenuLinks.Sleeves!]; + const links: HTMLElement[] = [MainMenuLinks.Stats, MainMenuLinks.Factions, MainMenuLinks.Augmentations, MainMenuLinks.HacknetNodes, MainMenuLinks.Sleeves]; if (stats.style.maxHeight) { toggleHeader(false, elems, links); } else { @@ -120,7 +120,7 @@ export function initializeMainMenuHeaders(p: IPlayer, dev = false): boolean { (this as any).classList.toggle("opened"); const elems: HTMLElement[] = [city, travel, job, stockmarket, bladeburner, corporation, gang]; - const links: HTMLElement[] = [MainMenuLinks.City!, MainMenuLinks.Travel!, MainMenuLinks.Job!, MainMenuLinks.StockMarket!, MainMenuLinks.Bladeburner!, MainMenuLinks.Corporation!, MainMenuLinks.Gang!]; + const links: HTMLElement[] = [MainMenuLinks.City, MainMenuLinks.Travel, MainMenuLinks.Job, MainMenuLinks.StockMarket, MainMenuLinks.Bladeburner, MainMenuLinks.Corporation, MainMenuLinks.Gang]; if (city.style.maxHeight) { toggleHeader(false, elems, links); } else { @@ -136,7 +136,7 @@ export function initializeMainMenuHeaders(p: IPlayer, dev = false): boolean { (this as any).classList.toggle("opened"); const elems: HTMLElement[] = [milestones, tutorial, options]; - const links: HTMLElement[] = [MainMenuLinks.Milestones!, MainMenuLinks.Tutorial!, MainMenuLinks.Options!]; + const links: HTMLElement[] = [MainMenuLinks.Milestones, MainMenuLinks.Tutorial, MainMenuLinks.Options]; if (dev) { elems.push(safeGetElement("dev-tab")); diff --git a/src/ui/MainMenu/Links.ts b/src/ui/MainMenu/Links.ts index b86bd8cba..890efa405 100644 --- a/src/ui/MainMenu/Links.ts +++ b/src/ui/MainMenu/Links.ts @@ -3,49 +3,55 @@ import { clearEventListeners } from "../../../utils/uiHelpers/clearEventListeners"; interface IMainMenuLinks { - Terminal: HTMLElement | null; - ScriptEditor: HTMLElement | null; - ActiveScripts: HTMLElement | null; - CreateProgram: HTMLElement | null; - Stats: HTMLElement | null; - Factions: HTMLElement | null; - Augmentations: HTMLElement | null; - HacknetNodes: HTMLElement | null; - Sleeves: HTMLElement | null; - City: HTMLElement | null; - Travel: HTMLElement | null; - Job: HTMLElement | null; - StockMarket: HTMLElement | null; - Bladeburner: HTMLElement | null; - Corporation: HTMLElement | null; - Gang: HTMLElement | null; - Milestones: HTMLElement | null; - Tutorial: HTMLElement | null; - Options: HTMLElement | null; - DevMenu: HTMLElement | null; + Terminal: HTMLElement; + ScriptEditor: HTMLElement; + ActiveScripts: HTMLElement; + CreateProgram: HTMLElement; + Stats: HTMLElement; + Factions: HTMLElement; + Augmentations: HTMLElement; + HacknetNodes: HTMLElement; + Sleeves: HTMLElement; + City: HTMLElement; + Travel: HTMLElement; + Job: HTMLElement; + StockMarket: HTMLElement; + Bladeburner: HTMLElement; + Corporation: HTMLElement; + Gang: HTMLElement; + Milestones: HTMLElement; + Tutorial: HTMLElement; + Options: HTMLElement; + DevMenu: HTMLElement; } +const emptyElement: HTMLElement = ((): HTMLElement => { + const elem = document.createElement('div'); + if(elem === null) throw new Error("unable to create empty div element"); + return elem; +})(); + export const MainMenuLinks: IMainMenuLinks = { - Terminal: null, - ScriptEditor: null, - ActiveScripts: null, - CreateProgram: null, - Stats: null, - Factions: null, - Augmentations: null, - HacknetNodes: null, - Sleeves: null, - City: null, - Travel: null, - Job: null, - StockMarket: null, - Bladeburner: null, - Corporation: null, - Gang: null, - Milestones: null, - Tutorial: null, - Options: null, - DevMenu: null, + Terminal: emptyElement, + ScriptEditor: emptyElement, + ActiveScripts: emptyElement, + CreateProgram: emptyElement, + Stats: emptyElement, + Factions: emptyElement, + Augmentations: emptyElement, + HacknetNodes: emptyElement, + Sleeves: emptyElement, + City: emptyElement, + Travel: emptyElement, + Job: emptyElement, + StockMarket: emptyElement, + Bladeburner: emptyElement, + Corporation: emptyElement, + Gang: emptyElement, + Milestones: emptyElement, + Tutorial: emptyElement, + Options: emptyElement, + DevMenu: emptyElement, } export function initializeMainMenuLinks(): boolean { @@ -77,7 +83,9 @@ export function initializeMainMenuLinks(): boolean { MainMenuLinks.Gang = safeGetLink("gang-menu-link"); MainMenuLinks.Milestones = safeGetLink("milestones-menu-link"); MainMenuLinks.Tutorial = safeGetLink("tutorial-menu-link"); - MainMenuLinks.Options = document.getElementById("options-menu-link"); // This click listener is already set, so don't clear it + const op: HTMLElement | null = document.getElementById("options-menu-link"); + if(op === null) throw new Error(`Could not find element with id: "options-menu-link"`); + MainMenuLinks.Options = op; // This click listener is already set, so don't clear it MainMenuLinks.DevMenu = safeGetLink("dev-menu-link"); return true; diff --git a/src/ui/React/Accordion.tsx b/src/ui/React/Accordion.tsx index a90be06f0..d45055cfb 100644 --- a/src/ui/React/Accordion.tsx +++ b/src/ui/React/Accordion.tsx @@ -27,26 +27,26 @@ export class Accordion extends React.Component { } } - handleHeaderClick(e: React.MouseEvent) { + handleHeaderClick(e: React.MouseEvent): void { const elem = e.currentTarget; elem.classList.toggle("active"); const panel: HTMLElement = elem.nextElementSibling as HTMLElement; const active = elem.classList.contains("active"); if (active) { - panel!.style.display = "block"; + panel.style.display = "block"; this.setState({ panelOpened: true, }); } else { - panel!.style.display = "none"; + panel.style.display = "none"; this.setState({ panelOpened: false, }); } } - render() { + render(): React.ReactNode { let className = "accordion-header"; if (typeof this.props.headerClass === "string") { className = this.props.headerClass; @@ -74,11 +74,11 @@ type IPanelProps = { } class AccordionPanel extends React.Component { - shouldComponentUpdate(nextProps: IPanelProps) { + shouldComponentUpdate(nextProps: IPanelProps): boolean { return this.props.opened || nextProps.opened; } - render() { + render(): React.ReactNode { let className = "accordion-panel" if (typeof this.props.panelClass === "string") { className = this.props.panelClass; diff --git a/src/ui/React/AccordionButton.tsx b/src/ui/React/AccordionButton.tsx index f60c6b821..722a1c188 100644 --- a/src/ui/React/AccordionButton.tsx +++ b/src/ui/React/AccordionButton.tsx @@ -10,7 +10,7 @@ interface IProps { disabled?: boolean; id?: string; onClick?: (e: React.MouseEvent) => any; - style?: object; + style?: any; text: string; tooltip?: string; } @@ -33,11 +33,8 @@ export function AccordionButton(props: IProps): React.ReactElement { } // Tooltip will be set using inner HTML - let tooltipMarkup: IInnerHTMLMarkup | null; - if (hasTooltip) { - tooltipMarkup = { - __html: props.tooltip! - } + const tooltipMarkup: IInnerHTMLMarkup = { + __html: props.tooltip ? props.tooltip : "", } return ( @@ -45,7 +42,7 @@ export function AccordionButton(props: IProps): React.ReactElement { {props.text} { hasTooltip && - + } ) diff --git a/src/ui/React/Augmentation.tsx b/src/ui/React/Augmentation.tsx index 0bfeb93b3..fddbf7e41 100644 --- a/src/ui/React/Augmentation.tsx +++ b/src/ui/React/Augmentation.tsx @@ -1,5 +1,4 @@ import * as React from "react"; -import { numeralWrapper } from "../../ui/numeralFormat"; export function Augmentation(name: string): JSX.Element { return {name} diff --git a/src/ui/React/AugmentationAccordion.tsx b/src/ui/React/AugmentationAccordion.tsx index 98b95f8f1..87ab4ae8f 100644 --- a/src/ui/React/AugmentationAccordion.tsx +++ b/src/ui/React/AugmentationAccordion.tsx @@ -12,8 +12,8 @@ import { Augmentation } from "../../Augmentation/Augmentation"; import { AugmentationNames } from "../../Augmentation/data/AugmentationNames"; type IProps = { - aug: Augmentation, - level?: number | string | null, + aug: Augmentation; + level?: number | string | null; } export function AugmentationAccordion(props: IProps): React.ReactElement { diff --git a/src/ui/React/AutoupdatingParagraph.tsx b/src/ui/React/AutoupdatingParagraph.tsx index 28e9d47c9..10572b346 100644 --- a/src/ui/React/AutoupdatingParagraph.tsx +++ b/src/ui/React/AutoupdatingParagraph.tsx @@ -7,7 +7,7 @@ import * as React from "react"; interface IProps { intervalTime?: number; - style?: object; + style?: any; getContent: () => JSX.Element; getTooltip?: () => JSX.Element; } @@ -16,15 +16,11 @@ interface IState { i: number; } -type IInnerHTMLMarkup = { - __html: string; -} - export class AutoupdatingParagraph extends React.Component { /** * Timer ID for auto-updating implementation (returned value from setInterval()) */ - interval: number = 0; + interval = 0; constructor(props: IProps) { super(props); @@ -33,37 +29,40 @@ export class AutoupdatingParagraph extends React.Component { } } - componentDidMount() { + componentDidMount(): void { const time = this.props.intervalTime ? this.props.intervalTime : 1000; this.interval = setInterval(() => this.tick(), time); } - componentWillUnmount() { + componentWillUnmount(): void { clearInterval(this.interval); } - tick() { + tick(): void { this.setState(prevState => ({ - i: prevState.i + 1 + i: prevState.i + 1, })); } - render() { - let hasTooltip = this.props.getTooltip != null; - let tooltip: JSX.Element | null; - if (hasTooltip) { - tooltip = this.props.getTooltip!(); - if (!tooltip) { - hasTooltip = false; - } + hasTooltip(): boolean { + if (this.props.getTooltip != null) { + return !!this.props.getTooltip() } + return true; + } + tooltip(): JSX.Element { + if(!this.props.getTooltip) return <>; + return this.props.getTooltip(); + } + + render(): React.ReactNode { return (

    {this.props.getContent()} { - hasTooltip && - {tooltip!} + this.hasTooltip() && + {this.tooltip()} }

    ) diff --git a/src/ui/React/AutoupdatingStdButton.tsx b/src/ui/React/AutoupdatingStdButton.tsx index ff3c5a608..bcf5b6f2f 100644 --- a/src/ui/React/AutoupdatingStdButton.tsx +++ b/src/ui/React/AutoupdatingStdButton.tsx @@ -10,7 +10,7 @@ interface IProps { disabled?: boolean; intervalTime?: number; onClick?: (e: React.MouseEvent) => any; - style?: object; + style?: any; text: string | JSX.Element; tooltip?: string; } @@ -27,7 +27,7 @@ export class AutoupdatingStdButton extends React.Component { /** * Timer ID for auto-updating implementation (returned value from setInterval()) */ - interval: number = 0; + interval = 0; constructor(props: IProps) { super(props); @@ -36,22 +36,22 @@ export class AutoupdatingStdButton extends React.Component { } } - componentDidMount() { + componentDidMount(): void { const time = this.props.intervalTime ? this.props.intervalTime : 1000; this.interval = setInterval(() => this.tick(), time); } - componentWillUnmount() { + componentWillUnmount(): void { clearInterval(this.interval); } - tick() { + tick(): void { this.setState(prevState => ({ - i: prevState.i + 1 + i: prevState.i + 1, })); } - render() { + render(): React.ReactNode { const hasTooltip = this.props.tooltip != null && this.props.tooltip !== ""; let className = this.props.disabled ? "std-button-disabled" : "std-button"; @@ -60,11 +60,8 @@ export class AutoupdatingStdButton extends React.Component { } // Tooltip will eb set using inner HTML - let tooltipMarkup: IInnerHTMLMarkup | null; - if (hasTooltip) { - tooltipMarkup = { - __html: this.props.tooltip! - } + const tooltipMarkup: IInnerHTMLMarkup = { + __html: this.props.tooltip ? this.props.tooltip : "", } return ( @@ -72,7 +69,7 @@ export class AutoupdatingStdButton extends React.Component { {this.props.text} { hasTooltip && - + } ) diff --git a/src/ui/React/CopyableText.tsx b/src/ui/React/CopyableText.tsx index da103505b..26ea3dc1a 100644 --- a/src/ui/React/CopyableText.tsx +++ b/src/ui/React/CopyableText.tsx @@ -21,7 +21,7 @@ export class CopyableText extends React.Component { } } - copy(e: React.MouseEvent) { + copy(): void { const copyText = document.createElement("textarea"); copyText.value = this.props.value; document.body.appendChild(copyText); @@ -52,7 +52,7 @@ export class CopyableText extends React.Component { } - render() { + render(): React.ReactNode { return ( {this.props.value} Copied! diff --git a/src/ui/React/CorruptableText.tsx b/src/ui/React/CorruptableText.tsx index 4a54e0175..926e1ece6 100644 --- a/src/ui/React/CorruptableText.tsx +++ b/src/ui/React/CorruptableText.tsx @@ -26,7 +26,7 @@ function randomize(char: string): string { return randFrom(other); } -export function CorruptableText(props: IProps) { +export function CorruptableText(props: IProps): JSX.Element { const [content, setContent] = useState(props.content); useEffect(() => { diff --git a/src/ui/React/ErrorBoundary.tsx b/src/ui/React/ErrorBoundary.tsx index 203f0c5fe..ee65679b8 100644 --- a/src/ui/React/ErrorBoundary.tsx +++ b/src/ui/React/ErrorBoundary.tsx @@ -37,45 +37,40 @@ export class ErrorBoundary extends React.Component { } } - static getDerivedStateFromError(error: Error) { - return { - errorInfo: error.message, - hasError: true, - }; - } - - componentDidCatch(error: Error, info: IErrorInfo) { + componentDidCatch(error: Error, info: IErrorInfo): void { console.error(`Caught error in React ErrorBoundary. Component stack:`); console.error(info.componentStack); } - componentDidMount() { - const cb = () => { + componentDidMount(): void { + const cb = (): void => { this.setState({ hasError: false, }); } if (this.hasEventEmitter()) { - this.props.eventEmitterForReset!.addSubscriber({ + (this.props.eventEmitterForReset as EventEmitter).addSubscriber({ cb: cb, - id: this.props.id!, + id: (this.props.id as string), }); } } - componentWillUnmount() { + componentWillUnmount(): void { if (this.hasEventEmitter()) { - this.props.eventEmitterForReset!.removeSubscriber(this.props.id!); + (this.props.eventEmitterForReset as EventEmitter).removeSubscriber((this.props.id as string)); } } hasEventEmitter(): boolean { - return this.props.eventEmitterForReset instanceof EventEmitter - && typeof this.props.id === "string"; + return this.props.eventEmitterForReset != null && + this.props.eventEmitterForReset instanceof EventEmitter && + this.props.id != null && + typeof this.props.id === "string"; } - render() { + render(): React.ReactNode { if (this.state.hasError) { return (
    @@ -100,4 +95,11 @@ export class ErrorBoundary extends React.Component { return this.props.children; } + + static getDerivedStateFromError(error: Error): IState { + return { + errorInfo: error.message, + hasError: true, + }; + } } diff --git a/src/ui/React/HashRate.tsx b/src/ui/React/HashRate.tsx index c19759c0d..88785f3dc 100644 --- a/src/ui/React/HashRate.tsx +++ b/src/ui/React/HashRate.tsx @@ -1,4 +1,3 @@ -import * as React from "react"; import { numeralWrapper } from "../../ui/numeralFormat"; import { Hashes } from "../../ui/React/Hashes"; diff --git a/src/ui/React/MoneyRate.tsx b/src/ui/React/MoneyRate.tsx index e0b832675..6e03a06f5 100644 --- a/src/ui/React/MoneyRate.tsx +++ b/src/ui/React/MoneyRate.tsx @@ -1,4 +1,3 @@ -import * as React from "react"; import { numeralWrapper } from "../../ui/numeralFormat"; import { Money } from "../../ui/React/Money"; diff --git a/src/ui/React/ParagraphWithTooltip.tsx b/src/ui/React/ParagraphWithTooltip.tsx index fb2af3933..288b53fee 100644 --- a/src/ui/React/ParagraphWithTooltip.tsx +++ b/src/ui/React/ParagraphWithTooltip.tsx @@ -4,13 +4,13 @@ import * as React from "react"; export interface IParagraphWithTooltipProps { - style?: object; + style?: any; content: JSX.Element; tooltip: string; } export class ParagraphWithTooltip extends React.Component { - render() { + render(): React.ReactNode { return (

    {this.props.content} diff --git a/src/ui/React/Popup.tsx b/src/ui/React/Popup.tsx index c296809bb..89f2a3c12 100644 --- a/src/ui/React/Popup.tsx +++ b/src/ui/React/Popup.tsx @@ -10,7 +10,7 @@ type ReactComponent = new(...args: any[]) => React.Component interface IProps { content: ReactComponent; id: string; - props: object; + props: any; } export function Popup(props: IProps): React.ReactElement { diff --git a/src/ui/React/PopupCloseButton.tsx b/src/ui/React/PopupCloseButton.tsx index dfd581926..8375fabec 100644 --- a/src/ui/React/PopupCloseButton.tsx +++ b/src/ui/React/PopupCloseButton.tsx @@ -14,7 +14,7 @@ import { removeElement } from "../../../utils/uiHelpers/removeElement"; export interface IPopupCloseButtonProps { class?: string; popup: HTMLElement | string; - style?: object; + style?: any; text: string; } @@ -26,15 +26,15 @@ export class PopupCloseButton extends React.Component) => any; - style?: object; + style?: any; text: string | JSX.Element; tooltip?: string | JSX.Element; } @@ -33,13 +33,12 @@ export function StdButton(props: IStdButtonProps): React.ReactElement { let tooltip; if (hasTooltip) { if(typeof props.tooltip === 'string') { - let tooltipMarkup: IInnerHTMLMarkup | null; - tooltipMarkup = { - __html: props.tooltip! + const tooltipMarkup: IInnerHTMLMarkup = { + __html: props.tooltip, } - tooltip = + tooltip = } else { - tooltip = {props.tooltip!} + tooltip = {props.tooltip} } } diff --git a/src/ui/React/StdButtonPurchased.tsx b/src/ui/React/StdButtonPurchased.tsx index db041af0a..afdab4cba 100644 --- a/src/ui/React/StdButtonPurchased.tsx +++ b/src/ui/React/StdButtonPurchased.tsx @@ -5,7 +5,7 @@ import * as React from "react"; interface IStdButtonPurchasedProps { onClick?: (e: React.MouseEvent) => any; - style?: object; + style?: any; text: string; tooltip?: string; } @@ -15,18 +15,35 @@ type IInnerHTMLMarkup = { } export class StdButtonPurchased extends React.Component { - render() { - const hasTooltip = this.props.tooltip != null && this.props.tooltip !== ""; + + constructor(props: IStdButtonPurchasedProps) { + super(props); + this.hasTooltip = this.hasTooltip.bind(this); + this.tooltip = this.tooltip.bind(this); + } + + hasTooltip(): boolean { + return this.props.tooltip != null && this.props.tooltip !== ""; + } + + tooltip(): string { + if(!this.props.tooltip) return ""; + return this.props.tooltip; + } + + render(): React.ReactNode { let className = "std-button-bought"; - if (hasTooltip) { + if (this.hasTooltip()) { className += " tooltip"; } // Tooltip will be set using inner HTML - let tooltipMarkup: IInnerHTMLMarkup | null; - if (hasTooltip) { + let tooltipMarkup: IInnerHTMLMarkup = { + __html: "", + } + if (this.hasTooltip()) { tooltipMarkup = { - __html: this.props.tooltip! + __html: this.tooltip(), } } @@ -34,8 +51,8 @@ export class StdButtonPurchased extends React.Component {this.props.text} { - hasTooltip && - + this.hasTooltip() && + } ) diff --git a/src/ui/React/createPopup.tsx b/src/ui/React/createPopup.tsx index 3f9bb5e25..0f1a7d4a3 100644 --- a/src/ui/React/createPopup.tsx +++ b/src/ui/React/createPopup.tsx @@ -18,8 +18,8 @@ type ReactComponent = new(...args: any[]) => React.Component; let gameContainer: HTMLElement; -function getGameContainer() { - let container = document.getElementById("entire-game-container"); +function getGameContainer(): void { + const container = document.getElementById("entire-game-container"); if (container == null) { throw new Error(`Failed to find game container DOM element`) } @@ -30,7 +30,8 @@ function getGameContainer() { document.addEventListener("DOMContentLoaded", getGameContainer); -export function createPopup(id: string, rootComponent: ReactComponent, props: object): HTMLElement | null { +// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types +export function createPopup(id: string, rootComponent: ReactComponent, props: any): HTMLElement | null { let container = document.getElementById(id); if (container == null) { container = createElement("div", { @@ -51,7 +52,7 @@ export function createPopup(id: string, rootComponent: ReactComponent, props: ob * Closes a popup created with the createPopup() function above */ export function removePopup(id: string): void { - let content = document.getElementById(`${id}`); + const content = document.getElementById(`${id}`); if (content == null) { return; } ReactDOM.unmountComponentAtNode(content); diff --git a/src/ui/createStatusText.ts b/src/ui/createStatusText.ts index 161eb047e..58ee30947 100644 --- a/src/ui/createStatusText.ts +++ b/src/ui/createStatusText.ts @@ -2,14 +2,14 @@ import { setTimeoutRef } from "../utils/SetTimeoutRef"; import { getElementById } from "../../utils/uiHelpers/getElementById"; import { Action } from "../types"; -const threeSeconds: number = 3000; +const threeSeconds = 3000; let x: number | undefined; /** * Displays a status message to the player for approximately 3 seconds. * @param text The status text to display */ -export function createStatusText(text: string) { +export function createStatusText(text: string): void { if (x !== undefined) { clearTimeout(x); // Likely not needed due to clearTimeout, but just in case... diff --git a/src/ui/navigationTracking.ts b/src/ui/navigationTracking.ts index 7f448aed4..6005c7b56 100644 --- a/src/ui/navigationTracking.ts +++ b/src/ui/navigationTracking.ts @@ -137,7 +137,7 @@ class Routing { * Determines if the player is currently on the specified page. * @param page The page to compare against the current state. */ - isOn(page: Page) { + isOn(page: Page): boolean { return this.currentPage === page; } @@ -145,7 +145,7 @@ class Routing { * Routes the player to the appropriate page. * @param page The page to navigate to. */ - navigateTo(page: Page) { + navigateTo(page: Page): void { this.currentPage = page; } } diff --git a/src/ui/numeralFormat.ts b/src/ui/numeralFormat.ts index 3c4e7c5f9..df84e3ed7 100644 --- a/src/ui/numeralFormat.ts +++ b/src/ui/numeralFormat.ts @@ -85,7 +85,7 @@ class NumeralFormatter { return this.format(n, formatter); } - formatServerSecurity(n: number, decimalPlaces = 2): string { + formatServerSecurity(n: number): string { return this.format(n, "0,0.000"); } @@ -101,15 +101,15 @@ class NumeralFormatter { return this.format(n, "0,0.00"); } - formatShock(n: number): string { + formatSleeveShock(n: number): string { return this.format(n, "0,0.000"); } - formatSync(n: number): string { + formatSleeveSynchro(n: number): string { return this.format(n, "0,0.000"); } - formatMemory(n: number): string { + formatSleeveMemory(n: number): string { return this.format(n, "0"); } diff --git a/src/ui/postToTerminal.tsx b/src/ui/postToTerminal.tsx index 5716e8569..7f06e03ff 100644 --- a/src/ui/postToTerminal.tsx +++ b/src/ui/postToTerminal.tsx @@ -1,4 +1,3 @@ -import * as React from "react"; import { renderToStaticMarkup } from "react-dom/server" import { getElementById } from "../../utils/uiHelpers/getElementById"; @@ -6,11 +5,11 @@ import { getElementById } from "../../utils/uiHelpers/getElementById"; * Adds some output to the terminal. * @param input Text or HTML to output to the terminal */ -export function post(input: string) { +export function post(input: string): void { postContent(input); } -export function postError(input: string) { +export function postError(input: string): void { postContent(`ERROR: ${input}`, { color: "#ff2929" }); } @@ -18,7 +17,7 @@ export function postError(input: string) { * Adds some output to the terminal with an identifier of "hack-progress-bar" * @param input Text or HTML to output to the terminal */ -export function hackProgressBarPost(input: string) { +export function hackProgressBarPost(input: string): void { postContent(input, { id: "hack-progress-bar" }); } @@ -26,7 +25,7 @@ export function hackProgressBarPost(input: string) { * Adds some output to the terminal with an identifier of "hack-progress" * @param input Text or HTML to output to the terminal */ -export function hackProgressPost(input: string) { +export function hackProgressPost(input: string): void { postContent(input, { id: "hack-progress" }); } @@ -35,21 +34,21 @@ interface IPostContentConfig { color?: string; // Additional class for terminal-line. Does NOT replace } -export function postElement(element: JSX.Element) { +export function postElement(element: JSX.Element): void { postContent(renderToStaticMarkup(element)); } -export function postContent(input: string, config: IPostContentConfig = {}) { +export function postContent(input: string, config: IPostContentConfig = {}): void { // tslint:disable-next-line:max-line-length - const style: string = `color: ${config.color != null ? config.color : "var(--my-font-color)"}; background-color:var(--my-background-color);${config.id === undefined ? " white-space:pre-wrap;" : ""}`; + const style = `color: ${config.color != null ? config.color : "var(--my-font-color)"}; background-color:var(--my-background-color);${config.id === undefined ? " white-space:pre-wrap;" : ""}`; // tslint:disable-next-line:max-line-length - const content: string = `

    `; + const content = ``; const inputElement: HTMLElement = getElementById("terminal-input"); inputElement.insertAdjacentHTML("beforebegin", content); scrollTerminalToBottom(); } -function scrollTerminalToBottom() { +function scrollTerminalToBottom(): void { const container: HTMLElement = getElementById("terminal-container"); container.scrollTop = container.scrollHeight; } diff --git a/src/utils/EventEmitter.ts b/src/utils/EventEmitter.ts index b513d76d5..5064ac05f 100644 --- a/src/utils/EventEmitter.ts +++ b/src/utils/EventEmitter.ts @@ -31,19 +31,19 @@ export class EventEmitter { } } - addSubscriber(s: ISubscriber) { + addSubscriber(s: ISubscriber): void { this.subscribers[s.id] = s.cb; } emitEvent(...args: any[]): void { for (const s in this.subscribers) { - const cb = this.subscribers[s]; + const sub = this.subscribers[s]; - cb(args); + sub(args); } } - removeSubscriber(id: string) { + removeSubscriber(id: string): void { delete this.subscribers[id]; } diff --git a/src/utils/MoneySourceTracker.ts b/src/utils/MoneySourceTracker.ts index 66fdb18a4..891e3389f 100644 --- a/src/utils/MoneySourceTracker.ts +++ b/src/utils/MoneySourceTracker.ts @@ -5,6 +5,7 @@ import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver"; export class MoneySourceTracker { + // eslint-disable-next-line @typescript-eslint/ban-types [key: string]: number | Function; bladeburner = 0; @@ -49,6 +50,7 @@ export class MoneySourceTracker { } // Initiatizes a MoneySourceTracker object from a JSON save state. + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types static fromJSON(value: any): MoneySourceTracker { return Generic_fromJSON(MoneySourceTracker, value.data); } diff --git a/src/utils/helpers/createRandomString.ts b/src/utils/helpers/createRandomString.ts index d963e8a41..97261a919 100644 --- a/src/utils/helpers/createRandomString.ts +++ b/src/utils/helpers/createRandomString.ts @@ -2,7 +2,7 @@ const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; export function createRandomString(n: number): string { - let str: string = ""; + let str = ""; for (let i = 0; i < n; ++i) { str += chars.charAt(Math.floor(Math.random() * chars.length)); diff --git a/stylelint.config.js b/stylelint.config.js index 34255608b..6a3a7e05e 100644 --- a/stylelint.config.js +++ b/stylelint.config.js @@ -2,7 +2,7 @@ module.exports = { plugins: [ "stylelint-declaration-use-variable", - "stylelint-order" /*, + "stylelint-order", /*, "stylelint-scss" */ ], rules: { @@ -139,20 +139,20 @@ module.exports = { "custom-properties", { type: "at-rule", - name: "extend" + name: "extend", }, { type: "at-rule", - name: "include" + name: "include", }, "declarations", "rules", "at-rules", - "less-mixins" + "less-mixins", ], { - unspecified: "bottom" - } + unspecified: "bottom", + }, ], // "order/properties-order": [ // [] @@ -162,7 +162,7 @@ module.exports = { "grid-area", "grid-template", "grid-column", - "grid-row" + "grid-row", ], "property-case": "lower", "property-no-unknown": true, @@ -236,7 +236,7 @@ module.exports = { "selector-attribute-operator-space-after": "never", "selector-attribute-operator-space-before": "never", "selector-attribute-operator-whitelist": [ - "=" + "=", ], "selector-attribute-quotes": "always", "selector-class-pattern": ".+", @@ -264,9 +264,9 @@ module.exports = { true, { ignore: [ - "attribute", "class" - ] - } + "attribute", "class", + ], + }, ], "selector-no-vendor-prefix": true, "selector-pseudo-class-blacklist": [], @@ -284,7 +284,7 @@ module.exports = { "not", "last-child", "root", - "visited" + "visited", ], //"selector-pseudo-element-blacklist": [], "selector-pseudo-element-case": "lower", @@ -315,7 +315,7 @@ module.exports = { "ms", "s", "vw", - "%" + "%", ], // "value-keyword-case": "lower", "value-list-comma-newline-after": "always-multi-line", @@ -323,6 +323,6 @@ module.exports = { "value-list-comma-space-after": "always-single-line", "value-list-comma-space-before": "never", "value-list-max-empty-lines": 0, - "value-no-vendor-prefix": true - } + "value-no-vendor-prefix": true, + }, }; diff --git a/test/Netscript/DynamicRamCalculationTests.js b/test/Netscript/DynamicRamCalculationTests.js index e23bc41a3..95d5040bb 100644 --- a/test/Netscript/DynamicRamCalculationTests.js +++ b/test/Netscript/DynamicRamCalculationTests.js @@ -34,7 +34,7 @@ describe("Netscript Dynamic RAM Calculation/Generation Tests", function() { function runPotentiallyAsyncFunction(fn) { let res = fn(); if (res instanceof Promise) { - res.catch(() => {}); + res.catch(() => undefined); } } diff --git a/test/Netscript/StaticRamCalculationTests.js b/test/Netscript/StaticRamCalculationTests.js index 6c59d8b7e..a883e3b71 100644 --- a/test/Netscript/StaticRamCalculationTests.js +++ b/test/Netscript/StaticRamCalculationTests.js @@ -54,7 +54,6 @@ describe("Netscript Static RAM Calculation/Generation Tests", function() { const calculated = await calculateRamUsage(code, []); testEquality(calculated, ScriptBaseCost); - const multipleCallsCode = code.repeat(3); const multipleCallsCalculated = await calculateRamUsage(code, []); expect(multipleCallsCalculated).to.equal(ScriptBaseCost); } diff --git a/test/StockMarketTests.ts b/test/StockMarketTests.ts index bd933478d..10a89f63a 100644 --- a/test/StockMarketTests.ts +++ b/test/StockMarketTests.ts @@ -63,7 +63,7 @@ describe("Stock Market Tests", function() { }; beforeEach(function() { - function construct() { + function construct(): void { stock = new Stock(ctorParams); } @@ -73,13 +73,14 @@ describe("Stock Market Tests", function() { describe("Stock Class", function() { describe("constructor", function() { it("should have default parameters", function() { - let defaultStock: Stock; - function construct() { - defaultStock = new Stock(); + function construct(): void { + new Stock(); // eslint-disable-line no-new } - expect(construct).to.not.throw(); - expect(defaultStock!.name).to.equal(""); + + const defaultStock = new Stock(); + expect(defaultStock).to.not.equal(null); + expect(defaultStock.name).to.equal(""); }); it("should properly initialize props from parameters", function() { @@ -99,7 +100,6 @@ describe("Stock Market Tests", function() { }); it ("should properly initialize props from range-values", function() { - let stock: Stock; const params = { b: true, initPrice: { @@ -126,15 +126,18 @@ describe("Stock Market Tests", function() { symbol: "mock", }; - function construct() { - stock = new Stock(params); + function construct(): void { + new Stock(params); // eslint-disable-line no-new } expect(construct).to.not.throw(); - expect(stock!.price).to.be.within(params.initPrice.min, params.initPrice.max); - expect(stock!.mv).to.be.within(params.mv.min / params.mv.divisor, params.mv.max / params.mv.divisor); - expect(stock!.spreadPerc).to.be.within(params.spreadPerc.min / params.spreadPerc.divisor, params.spreadPerc.max / params.spreadPerc.divisor); - expect(stock!.shareTxForMovement).to.be.within(params.shareTxForMovement.min, params.shareTxForMovement.max); + + const stock = new Stock(params); + expect(stock).not.equal(null); + expect(stock.price).to.be.within(params.initPrice.min, params.initPrice.max); + expect(stock.mv).to.be.within(params.mv.min / params.mv.divisor, params.mv.max / params.mv.divisor); + expect(stock.spreadPerc).to.be.within(params.spreadPerc.min / params.spreadPerc.divisor, params.spreadPerc.max / params.spreadPerc.divisor); + expect(stock.shareTxForMovement).to.be.within(params.shareTxForMovement.min, params.shareTxForMovement.max); }); it("should round the 'totalShare' prop to the nearest 100k", function() { @@ -569,17 +572,19 @@ describe("Stock Market Tests", function() { describe("Forecast Movement Processor Function", function() { // N = 1 is the original forecast - function getNthForecast(origForecast: number, n: number) { + function getNthForecast(origForecast: number, n: number): number { return origForecast - forecastChangePerPriceMovement * (n - 1); } - function getNthForecastForecast(origForecastForecast: number, n: number) { + function getNthForecastForecast(origForecastForecast: number, n: number): number { if (stock.otlkMagForecast > 50) { const expected = origForecastForecast - (forecastChangePerPriceMovement * (n - 1) * (stock.mv / 100)); return expected < 50 ? 50 : expected; } else if (stock.otlkMagForecast < 50) { const expected = origForecastForecast + (forecastChangePerPriceMovement * (n - 1) * (stock.mv / 100)); return expected > 50 ? 50 : expected; + } else { + return 50; } } @@ -838,9 +843,10 @@ describe("Stock Market Tests", function() { const cost = getBuyTransactionCost(stock, shares, PositionTypes.Long); if (cost == null) { expect.fail(); + return; } - Player.setMoney(cost!); + Player.setMoney(cost); expect(buyStock(stock, shares, null, suppressDialogOpt)).to.equal(true); expect(stock.playerShares).to.equal(shares); @@ -932,9 +938,10 @@ describe("Stock Market Tests", function() { const cost = getBuyTransactionCost(stock, shares, PositionTypes.Short); if (cost == null) { expect.fail(); + return } - Player.setMoney(cost!); + Player.setMoney(cost); expect(shortStock(stock, shares, null, suppressDialogOpt)).to.equal(true); expect(stock.playerShortShares).to.equal(shares); @@ -1006,19 +1013,19 @@ describe("Stock Market Tests", function() { describe("Order Class", function() { it("should throw on invalid arguments", function() { - function invalid1() { + function invalid1(): Order { return new Order({} as string, 1, 1, OrderTypes.LimitBuy, PositionTypes.Long); } - function invalid2() { + function invalid2(): Order { return new Order("FOO", "z" as any as number, 0, OrderTypes.LimitBuy, PositionTypes.Short); } - function invalid3() { + function invalid3(): Order { return new Order("FOO", 1, {} as number, OrderTypes.LimitBuy, PositionTypes.Short); } - function invalid4() { + function invalid4(): Order { return new Order("FOO", 1, NaN, OrderTypes.LimitBuy, PositionTypes.Short); } - function invalid5() { + function invalid5(): Order { return new Order("FOO", NaN, 0, OrderTypes.LimitBuy, PositionTypes.Short); } @@ -1089,7 +1096,7 @@ describe("Stock Market Tests", function() { shares: 1e3, price: 9e3, type: OrderTypes.LimitBuy, - pos: PositionTypes.Long + pos: PositionTypes.Long, }); expect(res).to.equal(true); expect(StockMarket["Orders"][stock.symbol]).to.have.lengthOf(0); @@ -1107,7 +1114,7 @@ describe("Stock Market Tests", function() { shares: 999, price: 9e3, type: OrderTypes.LimitBuy, - pos: PositionTypes.Long + pos: PositionTypes.Long, }); expect(res2).to.equal(false); expect(StockMarket["Orders"][stock.symbol]).to.have.lengthOf(1); @@ -1130,20 +1137,20 @@ describe("Stock Market Tests", function() { Player.setMoney(100e9); processOrdersRefs = { - rerenderFn: () => {}, + rerenderFn: () => undefined, stockMarket: StockMarket as IStockMarket, symbolToStockMap: SymbolToStockMap, }; }); - function checkThatOrderExists(placeOrderRes?: boolean) { + function checkThatOrderExists(placeOrderRes?: boolean): void { if (typeof placeOrderRes === "boolean") { expect(placeOrderRes).to.equal(true); } expect(StockMarket["Orders"][stock.symbol]).to.have.lengthOf(1); } - function checkThatOrderExecuted() { + function checkThatOrderExecuted(): void { expect(StockMarket["Orders"][stock.symbol]).to.have.lengthOf(0); } diff --git a/test/Terminal/DirectoryTests.js b/test/Terminal/DirectoryTests.js index e8516ca18..e63136626 100644 --- a/test/Terminal/DirectoryTests.js +++ b/test/Terminal/DirectoryTests.js @@ -286,13 +286,13 @@ describe("Terminal Directory Tests", function() { }); describe("evaluateDirectoryPath()", function() { - const evaluateDirectoryPath = dirHelpers.evaluateDirectoryPath; + //const evaluateDirectoryPath = dirHelpers.evaluateDirectoryPath; // TODO }); describe("evaluateFilePath()", function() { - const evaluateFilePath = dirHelpers.evaluateFilePath; + //const evaluateFilePath = dirHelpers.evaluateFilePath; // TODO }) diff --git a/utils/DialogBox.d.ts b/utils/DialogBox.d.ts index 7273671cb..87e1ea85a 100644 --- a/utils/DialogBox.d.ts +++ b/utils/DialogBox.d.ts @@ -1,2 +1,2 @@ export function dialogBoxCreate(txt: string | JSX.Element, preformatted?: boolean): void; -export var dialogBoxOpened: boolean; +export let dialogBoxOpened: boolean; diff --git a/utils/DialogBox.jsx b/utils/DialogBox.jsx index 5a93cb23f..56d5daa9c 100644 --- a/utils/DialogBox.jsx +++ b/utils/DialogBox.jsx @@ -31,7 +31,7 @@ function closeTopmostDialogBox() { } // Dialog box close buttons -$(document).on('click', '.dialog-box-close-button', function( event ) { +$(document).on('click', '.dialog-box-close-button', function() { closeTopmostDialogBox(); }); diff --git a/utils/FactionInvitationBox.js b/utils/FactionInvitationBox.js index f6ed35ab6..8150def89 100644 --- a/utils/FactionInvitationBox.js +++ b/utils/FactionInvitationBox.js @@ -20,11 +20,6 @@ function factionInvitationSetText(txt) { textBox.innerHTML = txt; } -function factionInvitationSetMessage(msg) { - var msgBox = document.getElementById("faction-invitation-box-message"); - msgBox.innerHTML = msg; -} - //ram argument is in GB function factionInvitationBoxCreate(faction) { factionInvitationSetText("You have received a faction invitation from " + faction.name); diff --git a/utils/GameOptions.js b/utils/GameOptions.js index ad929a6cc..654a17bdf 100644 --- a/utils/GameOptions.js +++ b/utils/GameOptions.js @@ -23,7 +23,7 @@ function gameOptionsBoxInit() { gameOptionsBoxClose(); return false; }); -}; +} document.addEventListener("DOMContentLoaded", gameOptionsBoxInit, false); diff --git a/utils/InfiltrationBox.js b/utils/InfiltrationBox.js index 59db25098..ab05179cc 100644 --- a/utils/InfiltrationBox.js +++ b/utils/InfiltrationBox.js @@ -4,7 +4,6 @@ import { formatNumber } from "./StringHelperFunctions"; import { BitNodeMultipliers } from "../src/BitNode/BitNodeMultipliers"; import { CONSTANTS } from "../src/Constants"; -import { Faction } from "../src/Faction/Faction"; import { Factions } from "../src/Faction/Factions"; import { Player } from "../src/Player"; diff --git a/utils/JSONReviver.d.ts b/utils/JSONReviver.d.ts index f4405df83..237eb0364 100644 --- a/utils/JSONReviver.d.ts +++ b/utils/JSONReviver.d.ts @@ -1,10 +1,10 @@ interface IReviverValue { ctor: string; - data: object + data: any; } export function Generic_fromJSON(ctor: new () => T, data: any): T; -export function Generic_toJSON(ctorName: string, obj: object, keys?: string[]): string; +export function Generic_toJSON(ctorName: string, obj: any, keys?: string[]): string; export function Reviver(key, value: IReviverValue); export namespace Reviver { - export var constructors: any; + export let constructors: any; } diff --git a/utils/JSONReviver.js b/utils/JSONReviver.js index 8d10ceee5..b23656b86 100644 --- a/utils/JSONReviver.js +++ b/utils/JSONReviver.js @@ -46,7 +46,7 @@ Reviver.constructors = {}; // A list of constructors the smart reviver should kn // Returns: The structure (which will then be turned into a string // as part of the JSON.stringify algorithm) function Generic_toJSON(ctorName, obj, keys) { - var data, index, key; + var data, key; if (!keys) { keys = Object.keys(obj); // Only "own" properties are included diff --git a/utils/LogBox.ts b/utils/LogBox.ts index 10633e035..23fce3c59 100644 --- a/utils/LogBox.ts +++ b/utils/LogBox.ts @@ -42,18 +42,18 @@ function logBoxInit(): void { logBoxClose(); document.removeEventListener("DOMContentLoaded", logBoxInit); -}; +} document.addEventListener("DOMContentLoaded", logBoxInit); -function logBoxClose() { +function logBoxClose(): void { logBoxOpened = false; if (logBoxContainer instanceof HTMLElement) { logBoxContainer.style.display = "none"; } } -function logBoxOpen() { +function logBoxOpen(): void { logBoxOpened = true; if (logBoxContainer instanceof HTMLElement) { @@ -64,7 +64,7 @@ function logBoxOpen() { export let logBoxOpened = false; let logBoxCurrentScript: RunningScript | null = null; -export function logBoxCreate(script: RunningScript) { +export function logBoxCreate(script: RunningScript): void { logBoxCurrentScript = script; const killScriptBtn = clearEventListeners("log-box-kill-script"); @@ -92,7 +92,7 @@ export function logBoxCreate(script: RunningScript) { logBoxUpdateText(); } -export function logBoxUpdateText() { +export function logBoxUpdateText(): void { if (!(logText instanceof HTMLElement)) { return; } if (logBoxCurrentScript && logBoxOpened && logBoxCurrentScript.logUpd) { diff --git a/utils/StringHelperFunctions.ts b/utils/StringHelperFunctions.ts index 01a69ce69..effe284d4 100644 --- a/utils/StringHelperFunctions.ts +++ b/utils/StringHelperFunctions.ts @@ -14,11 +14,11 @@ e.g. 10000 -> "10 seconds" 120000 -> "2 minutes and 0 seconds" */ function convertTimeMsToTimeElapsedString(time: number): string { - const millisecondsPerSecond: number = 1000; - const secondPerMinute: number = 60; - const minutesPerHours: number = 60; + const millisecondsPerSecond = 1000; + const secondPerMinute = 60; + const minutesPerHours = 60; const secondPerHours: number = secondPerMinute * minutesPerHours; - const hoursPerDays: number = 24; + const hoursPerDays = 24; const secondPerDay: number = secondPerHours * hoursPerDays; // Convert ms to seconds, since we only have second-level precision @@ -35,7 +35,7 @@ function convertTimeMsToTimeElapsedString(time: number): string { const seconds: number = secTruncMinutes; - let res: string = ""; + let res = ""; if (days > 0) {res += `${days} days `; } if (hours > 0) {res += `${hours} hours `; } if (minutes > 0) {res += `${minutes} minutes `; } @@ -54,7 +54,7 @@ function longestCommonStart(strings: string[]): string { const a1: string = A[0]; const a2: string = A[A.length - 1]; const L: number = a1.length; - let i: number = 0; + let i = 0; const areEqualCaseInsensitive: EqualityFunc = (a: string, b: string) => a.toUpperCase() === b.toUpperCase(); while (i < L && areEqualCaseInsensitive(a1.charAt(i), a2.charAt(i))) { i++; @@ -92,10 +92,10 @@ function isHTML(str: string): boolean { // Generates a random alphanumeric string with N characters function generateRandomString(n: number): string { - let str: string = ""; - const chars: string = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + let str = ""; + const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; - for (let i: number = 0; i < n; i++) { + for (let i = 0; i < n; i++) { str += chars.charAt(Math.floor(Math.random() * chars.length)); } diff --git a/utils/YesNoBox.ts b/utils/YesNoBox.ts index ca1da968f..bbac42b1e 100644 --- a/utils/YesNoBox.ts +++ b/utils/YesNoBox.ts @@ -8,15 +8,14 @@ */ import { clearEventListeners } from "./uiHelpers/clearEventListeners"; import { KEY } from "./helpers/keyCodes"; -import * as React from "react"; import * as ReactDOM from "react-dom"; -export let yesNoBoxOpen: boolean = false; +export let yesNoBoxOpen = false; const yesNoBoxContainer: HTMLElement | null = document.getElementById("yes-no-box-container"); const yesNoBoxTextElement: HTMLElement | null = document.getElementById("yes-no-box-text"); -function yesNoBoxHotkeyHandler(e: KeyboardEvent) { +function yesNoBoxHotkeyHandler(e: KeyboardEvent): void { if (e.keyCode === KEY.ESC) { yesNoBoxClose(); } else if (e.keyCode === KEY.ENTER) { @@ -43,15 +42,15 @@ export function yesNoBoxClose(): boolean { return false; //So that 'return yesNoBoxClose()' is return false in event listeners } -export function yesNoBoxGetYesButton() { +export function yesNoBoxGetYesButton(): HTMLElement | null { return clearEventListeners("yes-no-box-yes"); } -export function yesNoBoxGetNoButton() { +export function yesNoBoxGetNoButton(): HTMLElement | null { return clearEventListeners("yes-no-box-no"); } -export function yesNoBoxCreate(txt: string | JSX.Element) { +export function yesNoBoxCreate(txt: string | JSX.Element): boolean { if (yesNoBoxOpen) { return false; } //Already open yesNoBoxOpen = true; @@ -86,7 +85,7 @@ const yesNoTextInputBoxContainer: HTMLElement | null = document.getElementById(" const yesNoTextInputBoxInput: HTMLInputElement | null = document.getElementById("yes-no-text-input-box-input") as HTMLInputElement; const yesNoTextInputBoxTextElement: HTMLElement | null = document.getElementById("yes-no-text-input-box-text"); -export function yesNoTxtInpBoxHotkeyHandler(e: KeyboardEvent) { +export function yesNoTxtInpBoxHotkeyHandler(e: KeyboardEvent): void { if (e.keyCode === KEY.ESC) { yesNoTxtInpBoxClose(); } else if (e.keyCode === KEY.ENTER) { @@ -106,8 +105,9 @@ export function yesNoTxtInpBoxClose(): boolean { console.error("Container not found for YesNoTextInputBox"); return false; } + if(!yesNoTextInputBoxInput) throw new Error("yesNoTextInputBoxInput was not set"); yesNoBoxOpen = false; - yesNoTextInputBoxInput!.value = ""; + yesNoTextInputBoxInput.value = ""; // Remove hotkey handler document.removeEventListener("keydown", yesNoTxtInpBoxHotkeyHandler); @@ -115,25 +115,29 @@ export function yesNoTxtInpBoxClose(): boolean { return false; } -export function yesNoTxtInpBoxGetYesButton(): HTMLElement | null { - return clearEventListeners("yes-no-text-input-box-yes"); +export function yesNoTxtInpBoxGetYesButton(): HTMLElement { + const elem = clearEventListeners("yes-no-text-input-box-yes"); + if(elem === null) throw new Error("Could not find element with id: 'yes-no-text-input-box-yes'"); + return elem; } -export function yesNoTxtInpBoxGetNoButton(): HTMLElement | null { - return clearEventListeners("yes-no-text-input-box-no"); +export function yesNoTxtInpBoxGetNoButton(): HTMLElement { + const elem = clearEventListeners("yes-no-text-input-box-no"); + if(elem === null) throw new Error("Could not find element with id: 'yes-no-text-input-box-no'"); + return elem; } export function yesNoTxtInpBoxGetInput(): string { - if (yesNoTextInputBoxInput == null) { + if (!yesNoTextInputBoxInput) { console.error("Could not find YesNoTextInputBox input element"); return ""; } - let val: string = yesNoTextInputBoxInput!.value; + let val: string = yesNoTextInputBoxInput.value; val = val.replace(/\s+/g, ''); return val; } -export function yesNoTxtInpBoxCreate(txt: string | JSX.Element) { +export function yesNoTxtInpBoxCreate(txt: string | JSX.Element): void { yesNoBoxOpen = true; @@ -156,5 +160,6 @@ export function yesNoTxtInpBoxCreate(txt: string | JSX.Element) { // Add event listener for Esc and Enter hotkeys document.addEventListener("keydown", yesNoTxtInpBoxHotkeyHandler); - yesNoTextInputBoxInput!.focus(); + if(!yesNoTextInputBoxInput) throw new Error("yesNoTextInputBoxInput was not set"); + yesNoTextInputBoxInput.focus(); } diff --git a/utils/helpers/addOffset.ts b/utils/helpers/addOffset.ts index a45ababd4..2463a8aff 100644 --- a/utils/helpers/addOffset.ts +++ b/utils/helpers/addOffset.ts @@ -9,8 +9,8 @@ * @param midpoint The number to be the midpoint of the offset range * @param percentage The percentage (in a range of 0-100) to offset */ -export function addOffset(midpoint: number, percentage: number) { - const maxPercent: number = 100; +export function addOffset(midpoint: number, percentage: number): number { + const maxPercent = 100; if (percentage < 0 || percentage > maxPercent) { return midpoint; } diff --git a/utils/helpers/arrayToString.ts b/utils/helpers/arrayToString.ts index 815dd4495..f301c6563 100644 --- a/utils/helpers/arrayToString.ts +++ b/utils/helpers/arrayToString.ts @@ -5,7 +5,7 @@ * - Adds brackets around the array * - Adds quotation marks around strings */ -export function arrayToString(a: T[]) { +export function arrayToString(a: T[]): string { const vals: any[] = []; for (let i = 0; i < a.length; ++i) { let elem: any = a[i]; diff --git a/utils/helpers/clearObject.ts b/utils/helpers/clearObject.ts index fec858b20..57a92b6f4 100644 --- a/utils/helpers/clearObject.ts +++ b/utils/helpers/clearObject.ts @@ -4,7 +4,8 @@ * @deprecated Look into using `Map` or `Set` rather than manipulating properties on an Object. * @param obj the object to clear all properties */ -export function clearObject(obj: any) { + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types +export function clearObject(obj: any): void { for (const key in obj) { if (obj.hasOwnProperty(key)) { // tslint:disable-next-line:no-dynamic-delete diff --git a/utils/helpers/compareArrays.ts b/utils/helpers/compareArrays.ts index 257b2912a..8b88caf13 100644 --- a/utils/helpers/compareArrays.ts +++ b/utils/helpers/compareArrays.ts @@ -4,7 +4,7 @@ * @param a1 The first array * @param a2 The second array */ -export function compareArrays(a1: T[], a2: T[]) { +export function compareArrays(a1: T[], a2: T[]): boolean { if (a1.length !== a2.length) { return false; } diff --git a/utils/helpers/createProgressBarText.ts b/utils/helpers/createProgressBarText.ts index 37f433a00..2107de5eb 100644 --- a/utils/helpers/createProgressBarText.ts +++ b/utils/helpers/createProgressBarText.ts @@ -26,7 +26,7 @@ interface IProgressBarConfigurationMaterialized extends IProgressBarConfiguratio * e.g.: [||||---------------] * @param params The configuration parameters for the progress bar */ -export function createProgressBarText(params: IProgressBarConfiguration) { +export function createProgressBarText(params: IProgressBarConfiguration): string { // Default values const defaultParams: IProgressBarConfigurationMaterialized = { progress: 0, diff --git a/utils/helpers/exceptionAlert.ts b/utils/helpers/exceptionAlert.ts index 2a6998c89..5130b2fb5 100644 --- a/utils/helpers/exceptionAlert.ts +++ b/utils/helpers/exceptionAlert.ts @@ -1,8 +1,8 @@ import { dialogBoxCreate } from "../DialogBox"; interface IError { - fileName?: string, - lineNumber?: number, + fileName?: string; + lineNumber?: number; } export function exceptionAlert(e: IError): void { diff --git a/utils/helpers/getRandomByte.ts b/utils/helpers/getRandomByte.ts index 5b6ddf57d..954d45d83 100644 --- a/utils/helpers/getRandomByte.ts +++ b/utils/helpers/getRandomByte.ts @@ -4,9 +4,9 @@ import { getRandomInt } from "./getRandomInt"; * Gets a random value in the range of a byte (0 - 255), or up to the maximum. * @param max The maximum value (up to 255). */ -export function getRandomByte(max: number) { +export function getRandomByte(max: number): number { // Technically 2^8 is 256, but the values are 0-255, not 1-256. - const byteMaximum: number = 255; + const byteMaximum = 255; const upper: number = Math.max(Math.min(max, byteMaximum), 0); return getRandomInt(0, upper); diff --git a/utils/helpers/getRandomInt.ts b/utils/helpers/getRandomInt.ts index 4f5dc15b5..1dc4956f1 100644 --- a/utils/helpers/getRandomInt.ts +++ b/utils/helpers/getRandomInt.ts @@ -3,7 +3,7 @@ * @param min The minimum value in the range. * @param max The maximum value in the range. */ -export function getRandomInt(min: number, max: number) { +export function getRandomInt(min: number, max: number): number { const lower: number = Math.min(min, max); const upper: number = Math.max(min, max); diff --git a/utils/helpers/getTimestamp.ts b/utils/helpers/getTimestamp.ts index 6e7ee119f..bd523f727 100644 --- a/utils/helpers/getTimestamp.ts +++ b/utils/helpers/getTimestamp.ts @@ -1,10 +1,10 @@ /** * Returns a MM/DD HH:MM timestamp for the current time */ -export function getTimestamp() { +export function getTimestamp(): string { const d: Date = new Date(); // A negative slice value takes from the end of the string rather than the beginning. - const stringWidth: number = -2; + const stringWidth = -2; const formattedHours: string = `0${d.getHours()}`.slice(stringWidth); const formattedMinutes: string = `0${d.getMinutes()}`.slice(stringWidth); diff --git a/utils/helpers/isPowerOfTwo.ts b/utils/helpers/isPowerOfTwo.ts index 6f98ccf83..c0822c704 100644 --- a/utils/helpers/isPowerOfTwo.ts +++ b/utils/helpers/isPowerOfTwo.ts @@ -2,7 +2,7 @@ * Determines if the number is a power of 2 * @param n The number to check. */ -export function isPowerOfTwo(n: number) { +export function isPowerOfTwo(n: number): boolean { if (isNaN(n)) { return false; } diff --git a/utils/helpers/isString.ts b/utils/helpers/isString.ts index 5d24bc197..204d42427 100644 --- a/utils/helpers/isString.ts +++ b/utils/helpers/isString.ts @@ -2,6 +2,7 @@ * Checks whether the value passed in can be considered a string. * @param value The value to check if it is a string. */ +// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export function isString(value: any): boolean { return (typeof value === "string" || value instanceof String); } diff --git a/utils/helpers/isValidIPAddress.ts b/utils/helpers/isValidIPAddress.ts index 67b40257f..47afdbb43 100644 --- a/utils/helpers/isValidIPAddress.ts +++ b/utils/helpers/isValidIPAddress.ts @@ -3,10 +3,10 @@ * Checks whether a IP Address string is valid. * @param ipaddress A string representing a potential IP Address */ -export function isValidIPAddress(ipaddress: string) { - const byteRange: string = "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"; - const regexStr: string = `^${byteRange}\.${byteRange}\.${byteRange}\.${byteRange}$`; - const ipAddressRegex: RegExp = new RegExp(regexStr); +export function isValidIPAddress(ipaddress: string): boolean { + const byteRange = "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"; + const regexStr = `^${byteRange}\.${byteRange}\.${byteRange}\.${byteRange}$`; + const ipAddressRegex = new RegExp(regexStr); return ipAddressRegex.test(ipaddress); } diff --git a/utils/helpers/roundToTwo.ts b/utils/helpers/roundToTwo.ts index 33053ec61..a7fa1c2fb 100644 --- a/utils/helpers/roundToTwo.ts +++ b/utils/helpers/roundToTwo.ts @@ -2,7 +2,7 @@ * Rounds a number to two decimal places. * @param decimal A decimal value to trim to two places. */ -export function roundToTwo(decimal: number) { +export function roundToTwo(decimal: number): number { const leftShift: number = Math.round(parseFloat(`${decimal}e+2`)); return +(`${leftShift}e-2`); diff --git a/utils/uiHelpers/appendLineBreaks.ts b/utils/uiHelpers/appendLineBreaks.ts index f2895c536..02ac2ca1e 100644 --- a/utils/uiHelpers/appendLineBreaks.ts +++ b/utils/uiHelpers/appendLineBreaks.ts @@ -5,8 +5,8 @@ import { createElement } from "./createElement"; * @param el The element to add child break elements to. * @param n The number of breaks to add. */ -export function appendLineBreaks(el: HTMLElement, n: number) { - for (let i: number = 0; i < n; ++i) { +export function appendLineBreaks(el: HTMLElement, n: number): void { + for (let i = 0; i < n; ++i) { el.appendChild(createElement("br")); } } diff --git a/utils/uiHelpers/clearSelector.ts b/utils/uiHelpers/clearSelector.ts index 39e087bc0..887f72a53 100644 --- a/utils/uiHelpers/clearSelector.ts +++ b/utils/uiHelpers/clearSelector.ts @@ -2,7 +2,7 @@ * Clears all
    Hacking:{numeralWrapper.formatSkill(p.hacking_skill)}({numeralWrapper.formatExp(p.hacking_exp)} exp)
    Hacking:{numeralWrapper.formatSkill(p.hacking_skill)}({numeralWrapper.formatExp(p.hacking_exp)} exp)
    Strength:{numeralWrapper.formatSkill(p.strength)}({numeralWrapper.formatExp(p.strength_exp)} exp)
    Strength:{numeralWrapper.formatSkill(p.strength)}({numeralWrapper.formatExp(p.strength_exp)} exp)
    Defense:{numeralWrapper.formatSkill(p.defense)}({numeralWrapper.formatExp(p.defense_exp)} exp)
    Defense:{numeralWrapper.formatSkill(p.defense)}({numeralWrapper.formatExp(p.defense_exp)} exp)
    Dexterity:{numeralWrapper.formatSkill(p.dexterity)}({numeralWrapper.formatExp(p.dexterity_exp)} exp)
    Dexterity:{numeralWrapper.formatSkill(p.dexterity)}({numeralWrapper.formatExp(p.dexterity_exp)} exp)
    Agility:{numeralWrapper.formatSkill(p.agility)}({numeralWrapper.formatExp(p.agility_exp)} exp)
    Agility:{numeralWrapper.formatSkill(p.agility)}({numeralWrapper.formatExp(p.agility_exp)} exp)
    Charisma:{numeralWrapper.formatSkill(p.charisma)}({numeralWrapper.formatExp(p.charisma_exp)} exp)
    Charisma:{numeralWrapper.formatSkill(p.charisma)}({numeralWrapper.formatExp(p.charisma_exp)} exp)
    ${input}
    ${input}