From 96db360a3670c0735a998b18e5ddcb668cb1ff7f Mon Sep 17 00:00:00 2001 From: Olivier Gagnon Date: Sat, 23 Mar 2019 00:22:40 -0400 Subject: [PATCH 01/17] added sleeve aug api --- .../sleeveapi/getSleeveAugmentations.rst | 8 +++ .../sleeveapi/getSleevePurchasableAugs.rst | 17 +++++ .../netscript/sleeveapi/purchaseSleeveAug.rst | 9 +++ src/NetscriptFunctions.js | 67 ++++++++++++++++++- src/PersonObjects/Sleeve/Sleeve.ts | 39 +++++++++++ .../Sleeve/SleeveAugmentationsUI.ts | 26 ++----- src/ScriptEditor/AceNetscriptMode.js | 7 +- src/ScriptEditor/CodeMirrorNetscriptMode.js | 3 + 8 files changed, 150 insertions(+), 26 deletions(-) create mode 100644 doc/source/netscript/sleeveapi/getSleeveAugmentations.rst create mode 100644 doc/source/netscript/sleeveapi/getSleevePurchasableAugs.rst create mode 100644 doc/source/netscript/sleeveapi/purchaseSleeveAug.rst diff --git a/doc/source/netscript/sleeveapi/getSleeveAugmentations.rst b/doc/source/netscript/sleeveapi/getSleeveAugmentations.rst new file mode 100644 index 000000000..93f584725 --- /dev/null +++ b/doc/source/netscript/sleeveapi/getSleeveAugmentations.rst @@ -0,0 +1,8 @@ +getSleeveAugmentations() Netscript Function +======================================= + +.. js:function:: getSleeveAugmentations(sleeveNumber) + + :param int sleeveNumber: Index of the sleeve to retrieve augmentations from. See :ref:`here ` + + Return a list of augmentation names that this sleeve has installed. diff --git a/doc/source/netscript/sleeveapi/getSleevePurchasableAugs.rst b/doc/source/netscript/sleeveapi/getSleevePurchasableAugs.rst new file mode 100644 index 000000000..e9ee46a54 --- /dev/null +++ b/doc/source/netscript/sleeveapi/getSleevePurchasableAugs.rst @@ -0,0 +1,17 @@ +getSleevePurchasableAugs() Netscript Function +======================================= + +.. js:function:: getSleevePurchasableAugs(sleeveNumber) + + :param int sleeveNumber: Index of the sleeve to retrieve purchasable augmentations from. See :ref:`here ` + + Return a list of augmentations that the player can buy for this sleeve. + +.. code-block:: javascript + + [ + { + name: string, // augmentation name + cost: number, // augmentation cost + } + ] diff --git a/doc/source/netscript/sleeveapi/purchaseSleeveAug.rst b/doc/source/netscript/sleeveapi/purchaseSleeveAug.rst new file mode 100644 index 000000000..31fff9f49 --- /dev/null +++ b/doc/source/netscript/sleeveapi/purchaseSleeveAug.rst @@ -0,0 +1,9 @@ +purchaseSleeveAug() Netscript Function +======================================= + +.. js:function:: purchaseSleeveAug(sleeveNumber, augName) + + :param int sleeveNumber: Index of the sleeve to buy an aug for. See :ref:`here ` + :param string augName: Name of the aug to buy. See :ref:`here ` + + Return true if the aug was purchased and installed on the sleeve. \ No newline at end of file diff --git a/src/NetscriptFunctions.js b/src/NetscriptFunctions.js index 6d246a1d2..1e5fb2166 100644 --- a/src/NetscriptFunctions.js +++ b/src/NetscriptFunctions.js @@ -73,7 +73,8 @@ import {WorkerScript, workerScripts, import {makeRuntimeRejectMsg, netscriptDelay, runScriptFromScript} from "./NetscriptEvaluator"; import {NetscriptPort} from "./NetscriptPort"; -import { SleeveTaskType } from "./PersonObjects/Sleeve/SleeveTaskTypesEnum" +import { SleeveTaskType } from "./PersonObjects/Sleeve/SleeveTaskTypesEnum"; +import { findSleevePurchasableAugs } from "./PersonObjects/Sleeve/Sleeve"; import {Page, routing} from "./ui/navigationTracking"; import {numeralWrapper} from "./ui/numeralFormat"; @@ -5080,6 +5081,70 @@ function NetscriptFunctions(workerScript) { workRepGain: sl.getRepGain(), } }, + getSleeveAugmentations : function(sleeveNumber=0) { + if (workerScript.checkingRam) { + return updateStaticRam("getSleeveAugmentations", CONSTANTS.ScriptSleeveBaseRamCost); + } + if (Player.bitNodeN !== 10 && !SourceFileFlags[10]) { + throw makeRuntimeRejectMsg(workerScript, "getSleeveAugmentations() failed because you do not currently have access to the Sleeve API. This is either because you are not in BitNode-10 or because you do not have Source-File 10"); + } + updateDynamicRam("getSleeveAugmentations", CONSTANTS.ScriptSleeveBaseRamCost); + if (sleeveNumber >= Player.sleeves.length || sleeveNumber < 0) { + workerScript.log(`ERROR: sleeve.getSleeveAugmentations(${sleeveNumber}) failed because it is an invalid sleeve number.`); + return []; + } + + const augs = []; + for (let i = 0; i < Player.sleeves[sleeveNumber].augmentations.length; i++) { + augs.push(Player.sleeves[sleeveNumber].augmentations[i].name); + } + return augs; + }, + getSleevePurchasableAugs : function(sleeveNumber=0) { + if (workerScript.checkingRam) { + return updateStaticRam("getSleevePurchasableAugs", CONSTANTS.ScriptSleeveBaseRamCost); + } + if (Player.bitNodeN !== 10 && !SourceFileFlags[10]) { + throw makeRuntimeRejectMsg(workerScript, "getSleevePurchasableAugs() failed because you do not currently have access to the Sleeve API. This is either because you are not in BitNode-10 or because you do not have Source-File 10"); + } + updateDynamicRam("getSleevePurchasableAugs", CONSTANTS.ScriptSleeveBaseRamCost); + if (sleeveNumber >= Player.sleeves.length || sleeveNumber < 0) { + workerScript.log(`ERROR: sleeve.getSleevePurchasableAugs(${sleeveNumber}) failed because it is an invalid sleeve number.`); + return []; + } + + const purchasableAugs = findSleevePurchasableAugs(Player.sleeves[sleeveNumber], Player); + const augs = []; + for (let i = 0; i < purchasableAugs.length; i++) { + const aug = purchasableAugs[i]; + augs.push({ + name: aug.name, + cost: aug.startingCost, + }); + } + + return augs; + }, + purchaseSleeveAug : function(sleeveNumber=0, augName="") { + if (workerScript.checkingRam) { + return updateStaticRam("purchaseSleeveAug", CONSTANTS.ScriptSleeveBaseRamCost); + } + if (Player.bitNodeN !== 10 && !SourceFileFlags[10]) { + throw makeRuntimeRejectMsg(workerScript, "purchaseSleeveAug() failed because you do not currently have access to the Sleeve API. This is either because you are not in BitNode-10 or because you do not have Source-File 10"); + } + updateDynamicRam("purchaseSleeveAug", CONSTANTS.ScriptSleeveBaseRamCost); + if (sleeveNumber >= Player.sleeves.length || sleeveNumber < 0) { + workerScript.log(`ERROR: sleeve.purchaseSleeveAug(${sleeveNumber}) failed because it is an invalid sleeve number.`); + return false; + } + + const aug = Augmentations[augName]; + if (!aug) { + workerScript.log(`ERROR: sleeve.purchaseSleeveAug(${sleeveNumber}) failed because ${augName} is not a valid aug.`); + } + + return Player.sleeves[sleeveNumber].tryBuyAugmentation(Player, aug); + } } // End sleeve } //End return } //End NetscriptFunction() diff --git a/src/PersonObjects/Sleeve/Sleeve.ts b/src/PersonObjects/Sleeve/Sleeve.ts index 6f5a27c98..6fe7f980a 100644 --- a/src/PersonObjects/Sleeve/Sleeve.ts +++ b/src/PersonObjects/Sleeve/Sleeve.ts @@ -14,6 +14,8 @@ import { Person, createTaskTracker } from "../Person"; import { Augmentation } from "../../Augmentation/Augmentation"; +import { Augmentations } from "../../Augmentation/Augmentations"; +import { AugmentationNames } from "../../Augmentation/data/AugmentationNames"; import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers"; @@ -806,6 +808,16 @@ export class Sleeve extends Person { return true; } + tryBuyAugmentation(p: IPlayer, aug: Augmentation): boolean { + if (!p.canAfford(aug.startingCost)) { + return false; + } + + p.loseMoney(aug.startingCost); + this.installAugmentation(aug); + return true; + } + /** * Serialize the current object to a JSON save state. */ @@ -814,4 +826,31 @@ export class Sleeve extends Person { } } +export function findSleevePurchasableAugs(sleeve: Sleeve, p: IPlayer): Augmentation[] { + // You can only purchase Augmentations that are actually available from + // your factions. I.e. you must be in a faction that has the Augmentation + // and you must also have enough rep in that faction in order to purchase it. + + const ownedAugNames: string[] = sleeve.augmentations.map((e) => {return e.name}); + const availableAugs: Augmentation[] = []; + + for (const facName of p.factions) { + if (facName === "Bladeburners") { continue; } + const fac: Faction | null = Factions[facName]; + if (fac == null) { continue; } + + for (const augName of fac.augmentations) { + if (augName === AugmentationNames.NeuroFluxGovernor) { continue; } + if (ownedAugNames.includes(augName)) { continue; } + const aug: Augmentation | null = Augmentations[augName]; + + if (fac.playerReputation > aug.baseRepRequirement && !availableAugs.includes(aug)) { + availableAugs.push(aug); + } + } + } + + return availableAugs; +} + Reviver.constructors.Sleeve = Sleeve; diff --git a/src/PersonObjects/Sleeve/SleeveAugmentationsUI.ts b/src/PersonObjects/Sleeve/SleeveAugmentationsUI.ts index 471d95695..1c7e42ad4 100644 --- a/src/PersonObjects/Sleeve/SleeveAugmentationsUI.ts +++ b/src/PersonObjects/Sleeve/SleeveAugmentationsUI.ts @@ -2,7 +2,7 @@ * Module for handling the UI for purchasing Sleeve Augmentations * This UI is a popup, not a full page */ -import { Sleeve } from "./Sleeve"; +import { Sleeve, findSleevePurchasableAugs } from "./Sleeve"; import { IPlayer } from "../IPlayer"; @@ -29,23 +29,7 @@ export function createSleevePurchaseAugsPopup(sleeve: Sleeve, p: IPlayer) { // You can only purchase Augmentations that are actually available from // your factions. I.e. you must be in a faction that has the Augmentation // and you must also have enough rep in that faction in order to purchase it. - const availableAugs: Augmentation[] = []; - - for (const facName of p.factions) { - if (facName === "Bladeburners") { continue; } - const fac: Faction | null = Factions[facName]; - if (fac == null) { continue; } - - for (const augName of fac.augmentations) { - if (augName === AugmentationNames.NeuroFluxGovernor) { continue; } - if (ownedAugNames.includes(augName)) { continue; } - const aug: Augmentation | null = Augmentations[augName]; - - if (fac.playerReputation > aug.baseRepRequirement && !availableAugs.includes(aug)) { - availableAugs.push(aug); - } - } - } + const availableAugs = findSleevePurchasableAugs(sleeve, p); // Create popup const popupId = "purchase-sleeve-augs-popup"; @@ -110,10 +94,8 @@ export function createSleevePurchaseAugsPopup(sleeve: Sleeve, p: IPlayer) { ].join(" "), padding: "2px", clickListener: () => { - if (p.canAfford(aug.startingCost)) { - p.loseMoney(aug.startingCost); - sleeve.installAugmentation(aug); - dialogBoxCreate(`Installed ${aug.name} on Duplicate Sleeve!`, false) + if (sleeve.tryBuyAugmentation(p, aug)) { + dialogBoxCreate(`Installed ${aug.name} on Duplicate Sleeve!`, false); removeElementById(popupId); createSleevePurchaseAugsPopup(sleeve, p); } else { diff --git a/src/ScriptEditor/AceNetscriptMode.js b/src/ScriptEditor/AceNetscriptMode.js index 18ca0030a..15873e07c 100644 --- a/src/ScriptEditor/AceNetscriptMode.js +++ b/src/ScriptEditor/AceNetscriptMode.js @@ -128,9 +128,10 @@ let NetscriptFunctions = "getNumTriesRemaining|" + // Sleeve API - "sleeve|getNumSleeves|setToShockRecovery|setToSynchronize|setToCommitCrime|" + - "setToUniversityCourse|travel|setToCompanyWork|setToFactionWork|setToGymWorkout|" + - "getSleeveStats|getTask|getInformation"; + "sleeve|getNumSleeves|setToShockRecovery|setToSynchronize|" + + "setToCommitCrime|setToUniversityCourse|travel|setToCompanyWork|" + + "setToFactionWork|setToGymWorkout|getSleeveStats|getTask|getInformation|" + + "getSleeveAugmentations|getSleevePurchasableAugs|purchaseSleeveAug"; var NetscriptHighlightRules = function(options) { var keywordMapper = this.createKeywordMapper({ diff --git a/src/ScriptEditor/CodeMirrorNetscriptMode.js b/src/ScriptEditor/CodeMirrorNetscriptMode.js index bf6f2790b..fed212ac8 100644 --- a/src/ScriptEditor/CodeMirrorNetscriptMode.js +++ b/src/ScriptEditor/CodeMirrorNetscriptMode.js @@ -257,6 +257,9 @@ CodeMirror.defineMode("netscript", function(config, parserConfig) { "getSleeveStats": atom, "getTask": atom, "getInformation": atom, + "getSleeveAugmentations": atom, + "getSleevePurchasableAugs": atom, + "purchaseSleeveAug": atom, }; }(); From 139a5add20d3614c0e2541c7683647cfca256b20 Mon Sep 17 00:00:00 2001 From: danielyxie Date: Sun, 24 Mar 2019 19:56:47 -0700 Subject: [PATCH 02/17] Cleaned up whitespace from a PR --- src/PersonObjects/Resleeving/ResleevingUI.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PersonObjects/Resleeving/ResleevingUI.ts b/src/PersonObjects/Resleeving/ResleevingUI.ts index 28c8ee5b5..dc5114d34 100644 --- a/src/PersonObjects/Resleeving/ResleevingUI.ts +++ b/src/PersonObjects/Resleeving/ResleevingUI.ts @@ -96,7 +96,7 @@ export function createResleevesPage(p: IPlayer) { display: "inline-block", innerText: "Sort By: " }); - UIElems.sortSelector = createElement("select",{class:"dropdown"}) as HTMLSelectElement; + UIElems.sortSelector = createElement("select", { class: "dropdown" }) as HTMLSelectElement; enum SortOption { Cost = "Cost", From 227bcf146e536bd3bd424f377b8d508c4ea72b30 Mon Sep 17 00:00:00 2001 From: koriar Date: Sun, 24 Mar 2019 16:32:48 -0400 Subject: [PATCH 03/17] Fixing Corp Happiness typo --- src/Corporation/ui/IndustryOffice.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Corporation/ui/IndustryOffice.jsx b/src/Corporation/ui/IndustryOffice.jsx index 65626d327..7a0a3a743 100644 --- a/src/Corporation/ui/IndustryOffice.jsx +++ b/src/Corporation/ui/IndustryOffice.jsx @@ -300,7 +300,7 @@ export class IndustryOffice extends BaseReactComponent {

Avg Employee Morale: {numeralWrapper.format(avgMorale, "0.000")}

-

Avg Happiness Morale: {numeralWrapper.format(avgHappiness, "0.000")}

+

Avg Employee Happiness: {numeralWrapper.format(avgHappiness, "0.000")}

Avg Energy Morale: {numeralWrapper.format(avgEnergy, "0.000")}

Total Employee Salary: {numeralWrapper.formatMoney(totalSalary)}

{ From 2ce4af24982ca8e5d9061d4805b24c4f918ac7fb Mon Sep 17 00:00:00 2001 From: Olivier Gagnon Date: Sat, 23 Mar 2019 14:27:11 -0400 Subject: [PATCH 04/17] infiltration now scale exp gained by some factor to prevent some abuse --- src/Constants.ts | 1 + src/Infiltration.js | 52 +++++++++++++++++++++++++++++++++++----- utils/InfiltrationBox.js | 27 ++++++++++----------- 3 files changed, 60 insertions(+), 20 deletions(-) diff --git a/src/Constants.ts b/src/Constants.ts index 6f376fa50..a34343427 100644 --- a/src/Constants.ts +++ b/src/Constants.ts @@ -126,6 +126,7 @@ export let CONSTANTS: IMap = { InfiltrationBribeBaseAmount: 100e3, //Amount per clearance level InfiltrationMoneyValue: 5e3, //Convert "secret" value to money InfiltrationRepValue: 1.4, //Convert "secret" value to faction reputation + InfiltrationExpPow: 0.7, //Stock market constants WSEAccountCost: 200e6, diff --git a/src/Infiltration.js b/src/Infiltration.js index 697481b74..d856d8252 100644 --- a/src/Infiltration.js +++ b/src/Infiltration.js @@ -52,41 +52,81 @@ function InfiltrationInstance(companyName, startLevel, val, maxClearance, diff) this.intExpGained = 0; } +InfiltrationInstance.prototype.expMultiplier = function() { + if (!this.clearanceLevel || isNaN(this.clearanceLevel) || !this.maxClearanceLevel ||isNaN(this.maxClearanceLevel)) return 1; + return 2 * this.clearanceLevel / this.maxClearanceLevel; +} + InfiltrationInstance.prototype.gainHackingExp = function(amt) { if (isNaN(amt)) {return;} this.hackingExpGained += amt; } +InfiltrationInstance.prototype.calcGainedHackingExp = function() { + if(!this.hackingExpGained || isNaN(this.hackingExpGained)) return 0; + return Math.pow(this.hackingExpGained*this.expMultiplier(), CONSTANTS.InfiltrationExpPow); +} + InfiltrationInstance.prototype.gainStrengthExp = function(amt) { if (isNaN(amt)) {return;} this.strExpGained += amt; } +InfiltrationInstance.prototype.calcGainedStrengthExp = function() { + if(!this.strExpGained || isNaN(this.strExpGained)) return 0; + return Math.pow(this.strExpGained*this.expMultiplier(), CONSTANTS.InfiltrationExpPow); +} + InfiltrationInstance.prototype.gainDefenseExp = function(amt) { if (isNaN(amt)) {return;} this.defExpGained += amt; } +InfiltrationInstance.prototype.calcGainedDefenseExp = function() { + if(!this.defExpGained || isNaN(this.defExpGained)) return 0; + return Math.pow(this.defExpGained*this.expMultiplier(), CONSTANTS.InfiltrationExpPow); +} + InfiltrationInstance.prototype.gainDexterityExp = function(amt) { if (isNaN(amt)) {return;} this.dexExpGained += amt; } +InfiltrationInstance.prototype.calcGainedDexterityExp = function() { + if(!this.dexExpGained || isNaN(this.dexExpGained)) return 0; + return Math.pow(this.dexExpGained*this.expMultiplier(), CONSTANTS.InfiltrationExpPow); +} + InfiltrationInstance.prototype.gainAgilityExp = function(amt) { if (isNaN(amt)) {return;} this.agiExpGained += amt; } +InfiltrationInstance.prototype.calcGainedAgilityExp = function() { + if(!this.agiExpGained || isNaN(this.agiExpGained)) return 0; + return Math.pow(this.agiExpGained*this.expMultiplier(), CONSTANTS.InfiltrationExpPow); +} + InfiltrationInstance.prototype.gainCharismaExp = function(amt) { if (isNaN(amt)) {return;} this.chaExpGained += amt; } +InfiltrationInstance.prototype.calcGainedCharismaExp = function() { + if(!this.chaExpGained || isNaN(this.chaExpGained)) return 0; + return Math.pow(this.chaExpGained*this.expMultiplier(), CONSTANTS.InfiltrationExpPow); +} + InfiltrationInstance.prototype.gainIntelligenceExp = function(amt) { if (isNaN(amt)) {return;} this.intExpGained += amt; } +InfiltrationInstance.prototype.calcGainedIntelligenceExp = function() { + if(!this.intExpGained || isNaN(this.intExpGained)) return 0; + return Math.pow(this.intExpGained*this.expMultiplier(), CONSTANTS.InfiltrationExpPow); +} + function beginInfiltration(companyName, startLevel, val, maxClearance, diff) { var inst = new InfiltrationInstance(companyName, startLevel, val, maxClearance, diff); clearInfiltrationStatusText(); @@ -477,12 +517,12 @@ function updateInfiltrationLevelText(inst) { "Total value of stolen secrets
" + "Reputation:       " + formatNumber(totalValue, 3) + "
" + "Money:           $" + formatNumber(totalMoneyValue, 2) + "

" + - "Hack exp gained:  " + formatNumber(inst.hackingExpGained * expMultiplier, 3) + "
" + - "Str exp gained:   " + formatNumber(inst.strExpGained * expMultiplier, 3) + "
" + - "Def exp gained:   " + formatNumber(inst.defExpGained * expMultiplier, 3) + "
" + - "Dex exp gained:   " + formatNumber(inst.dexExpGained * expMultiplier, 3) + "
" + - "Agi exp gained:   " + formatNumber(inst.agiExpGained * expMultiplier, 3) + "
" + - "Cha exp gained:   " + formatNumber(inst.chaExpGained * expMultiplier, 3); + "Hack exp gained:  " + formatNumber(inst.calcGainedHackingExp(), 3) + "
" + + "Str exp gained:   " + formatNumber(inst.calcGainedStrengthExp(), 3) + "
" + + "Def exp gained:   " + formatNumber(inst.calcGainedDefenseExp(), 3) + "
" + + "Dex exp gained:   " + formatNumber(inst.calcGainedDexterityExp(), 3) + "
" + + "Agi exp gained:   " + formatNumber(inst.calcGainedAgilityExp(), 3) + "
" + + "Cha exp gained:   " + formatNumber(inst.calcGainedCharismaExp(), 3); /* eslint-enable no-irregular-whitespace */ } diff --git a/utils/InfiltrationBox.js b/utils/InfiltrationBox.js index fb922fc63..59db25098 100644 --- a/utils/InfiltrationBox.js +++ b/utils/InfiltrationBox.js @@ -30,22 +30,21 @@ function infiltrationSetText(txt) { //ram argument is in GB function infiltrationBoxCreate(inst) { //Gain exp - var expMultiplier = 2 * inst.clearanceLevel / inst.maxClearanceLevel; - Player.gainHackingExp(inst.hackingExpGained * expMultiplier); - Player.gainStrengthExp(inst.strExpGained * expMultiplier); - Player.gainDefenseExp(inst.defExpGained * expMultiplier); - Player.gainDexterityExp(inst.dexExpGained * expMultiplier); - Player.gainAgilityExp(inst.agiExpGained * expMultiplier); - Player.gainCharismaExp(inst.chaExpGained * expMultiplier); - Player.gainIntelligenceExp(inst.intExpGained * expMultiplier); + Player.gainHackingExp(inst.calcGainedHackingExp()); + Player.gainStrengthExp(inst.calcGainedStrengthExp()); + Player.gainDefenseExp(inst.calcGainedDefenseExp()); + Player.gainDexterityExp(inst.calcGainedDexterityExp()); + Player.gainAgilityExp(inst.calcGainedAgilityExp()); + Player.gainCharismaExp(inst.calcGainedCharismaExp()); + Player.gainIntelligenceExp(inst.calcGainedIntelligenceExp()); const expGainText = ["You gained:", - `${formatNumber(inst.hackingExpGained * expMultiplier, 3)} hacking exp`, - `${formatNumber(inst.strExpGained * expMultiplier, 3)} str exp`, - `${formatNumber(inst.defExpGained * expMultiplier, 3)} def exp`, - `${formatNumber(inst.dexExpGained * expMultiplier, 3)} dex exp`, - `${formatNumber(inst.agiExpGained * expMultiplier, 3)} agi exp`, - `${formatNumber(inst.chaExpGained * expMultiplier, 3)} cha exp`].join("\n"); + `${formatNumber(inst.calcGainedHackingExp(), 3)} hacking exp`, + `${formatNumber(inst.calcGainedStrengthExp(), 3)} str exp`, + `${formatNumber(inst.calcGainedDefenseExp(), 3)} def exp`, + `${formatNumber(inst.calcGainedDexterityExp(), 3)} dex exp`, + `${formatNumber(inst.calcGainedAgilityExp(), 3)} agi exp`, + `${formatNumber(inst.calcGainedCharismaExp(), 3)} cha exp`].join("\n"); var totalValue = 0; for (var i = 0; i < inst.secretsStolen.length; ++i) { From 34d749809a3ca810d6fb22c39225e76a67897ba9 Mon Sep 17 00:00:00 2001 From: danielyxie Date: Sun, 24 Mar 2019 20:03:24 -0700 Subject: [PATCH 05/17] BitNode-9 initial implementation --- css/buttons.scss | 1 + css/characteroverview.scss | 2 +- css/hacknetnodes.scss | 75 +++ css/menupages.scss | 75 --- src/Augmentation/AugmentationHelpers.js | 2 +- src/BitNode/BitNode.ts | 34 +- src/BitNode/BitNodeMultipliers.ts | 3 +- src/Constants.ts | 20 +- src/Hacknet/HacknetHelpers.jsx | 431 ++++++++++++++ src/Hacknet/HacknetNode.ts | 285 ++++++++++ src/Hacknet/HacknetServer.ts | 348 ++++++++++++ src/Hacknet/HashManager.ts | 151 +++++ src/Hacknet/HashUpgrade.ts | 48 ++ src/Hacknet/HashUpgrades.ts | 18 + src/Hacknet/IHacknetNode.ts | 16 + src/Hacknet/data/HashUpgradesMetadata.ts | 64 +++ src/Hacknet/ui/GeneralInfo.jsx | 56 ++ src/Hacknet/ui/HacknetNode.jsx | 153 +++++ src/Hacknet/ui/HacknetServer.jsx | 200 +++++++ src/Hacknet/ui/HashUpgradePopup.jsx | 137 +++++ src/Hacknet/ui/MultiplierButtons.jsx | 41 ++ src/Hacknet/ui/PlayerInfo.jsx | 51 ++ src/Hacknet/ui/PurchaseButton.jsx | 40 ++ src/Hacknet/ui/Root.jsx | 144 +++++ src/HacknetNode.js | 694 ----------------------- src/NetscriptEnvironment.js | 32 -- src/NetscriptEvaluator.js | 2 +- src/NetscriptFunctions.js | 14 +- src/PersonObjects/IPlayer.ts | 4 +- src/Player.js | 27 +- src/RedPill.js | 4 +- src/SaveObject.js | 12 +- src/Server/BaseServer.ts | 206 +++++++ src/Server/Server.ts | 247 ++------ src/Terminal.js | 8 +- src/engine.jsx | 24 +- src/index.html | 30 +- src/ui/React/ServerDropdown.jsx | 65 +++ src/ui/React/createPopup.ts | 56 ++ src/utils/createRandomString.ts | 12 + 40 files changed, 2749 insertions(+), 1083 deletions(-) create mode 100644 css/hacknetnodes.scss create mode 100644 src/Hacknet/HacknetHelpers.jsx create mode 100644 src/Hacknet/HacknetNode.ts create mode 100644 src/Hacknet/HacknetServer.ts create mode 100644 src/Hacknet/HashManager.ts create mode 100644 src/Hacknet/HashUpgrade.ts create mode 100644 src/Hacknet/HashUpgrades.ts create mode 100644 src/Hacknet/IHacknetNode.ts create mode 100644 src/Hacknet/data/HashUpgradesMetadata.ts create mode 100644 src/Hacknet/ui/GeneralInfo.jsx create mode 100644 src/Hacknet/ui/HacknetNode.jsx create mode 100644 src/Hacknet/ui/HacknetServer.jsx create mode 100644 src/Hacknet/ui/HashUpgradePopup.jsx create mode 100644 src/Hacknet/ui/MultiplierButtons.jsx create mode 100644 src/Hacknet/ui/PlayerInfo.jsx create mode 100644 src/Hacknet/ui/PurchaseButton.jsx create mode 100644 src/Hacknet/ui/Root.jsx delete mode 100644 src/HacknetNode.js create mode 100644 src/Server/BaseServer.ts create mode 100644 src/ui/React/ServerDropdown.jsx create mode 100644 src/ui/React/createPopup.ts create mode 100644 src/utils/createRandomString.ts diff --git a/css/buttons.scss b/css/buttons.scss index b854356d6..a22844a87 100644 --- a/css/buttons.scss +++ b/css/buttons.scss @@ -38,6 +38,7 @@ button { } .a-link-button-inactive, +.std-button-disabled, .std-button:disabled { text-decoration: none; background-color: #333; diff --git a/css/characteroverview.scss b/css/characteroverview.scss index 0fabea40f..2e0279be2 100644 --- a/css/characteroverview.scss +++ b/css/characteroverview.scss @@ -2,7 +2,7 @@ @import "theme"; /** - * Styling for the Character Overview Panel (top-right) + * Styling for the Character Overview Panel (top-right panel) */ #character-overview-wrapper { diff --git a/css/hacknetnodes.scss b/css/hacknetnodes.scss new file mode 100644 index 000000000..cf21c6a72 --- /dev/null +++ b/css/hacknetnodes.scss @@ -0,0 +1,75 @@ +@import "mixins"; +@import "theme"; + +/** + * Styling for the Hacknet Nodes UI Page + */ + +#hacknet-nodes-container { + position: fixed; + padding: 10px; +} + +.hacknet-general-info { + margin: 10px; + width: 70vw; +} + +#hacknet-nodes-container li { + float: left; + overflow: hidden; + white-space: nowrap; + + &.hacknet-node { + $boxShadowArgs: inset 0 0 8px rgba(0, 0, 0, 0.1), 0 0 16px rgba(0, 0, 0, 0.1); + @include boxShadow($boxShadowArgs); + + margin: 6px; + padding: 7px; + width: 35vw; + border: 2px solid var(--my-highlight-color); + } +} + +#hacknet-nodes-list { + list-style: none; + width: 82vw; +} + +#hacknet-nodes-money { + margin: 10px; + float: left; +} + +#hacknet-nodes-money-multipliers-div { + display: inline-block; + width: 70vw; +} + +#hacknet-nodes-multipliers { + float: right; +} + +#hacknet-nodes-purchase-button { + display: inline-block; +} + +.hacknet-node-container { + display: inline-table; + + .row { + display: table-row; + height: 30px; + + p { + display: table-cell; + } + } + + .upgradable-info { + display: inline-block; + margin: 0 4px; /* Don't want the vertical margin/padding, just left & right */ + padding: 0 4px; + width: $defaultFontSize * 4; + } +} diff --git a/css/menupages.scss b/css/menupages.scss index e67847fa8..0c8e55033 100644 --- a/css/menupages.scss +++ b/css/menupages.scss @@ -138,81 +138,6 @@ } } -/* Hacknet Nodes */ -#hacknet-nodes-container { - position: fixed; - padding: 10px; -} - -#hacknet-nodes-text, -#hacknet-nodes-container li { - margin: 10px; - padding: 10px; -} - -#hacknet-nodes-container li { - float: left; - overflow: hidden; - white-space: nowrap; - - &.hacknet-node { - $boxShadowArgs: inset 0 0 8px rgba(0, 0, 0, 0.1), 0 0 16px rgba(0, 0, 0, 0.1); - @include boxShadow($boxShadowArgs); - - margin: 6px; - padding: 7px; - width: 35vw; - border: 2px solid var(--my-highlight-color); - } -} - -#hacknet-nodes-list { - list-style: none; - width: 82vw; -} - -#hacknet-nodes-money { - margin: 10px; - float: left; -} - -#hacknet-nodes-money-multipliers-div { - display: inline-block; - width: 70vw; -} - -#hacknet-nodes-multipliers { - float: right; -} - -#hacknet-nodes-purchase-button { - display: inline-block; -} - -.hacknet-node-container { - display: inline-table; - - .row { - display: table-row; - height: 30px; - - p { - display: table-cell; - } - } - - .upgradable-info { - display: inline-block; - margin: 0 4px; /* Don't want the vertical margin/padding, just left & right */ - padding: 0 4px; - width: $defaultFontSize * 4; - } -} - -.menu-page-text { - width: 70vw; -} - /* World */ #world-container { position: fixed; diff --git a/src/Augmentation/AugmentationHelpers.js b/src/Augmentation/AugmentationHelpers.js index c6c99debc..9be26fea2 100644 --- a/src/Augmentation/AugmentationHelpers.js +++ b/src/Augmentation/AugmentationHelpers.js @@ -2069,7 +2069,7 @@ function installAugmentations(cbScript=null) { } var runningScriptObj = new RunningScript(script, []); //No args runningScriptObj.threads = 1; //Only 1 thread - home.runningScripts.push(runningScriptObj); + home.runScript(runningScriptObj, Player); addWorkerScript(runningScriptObj, home); } } diff --git a/src/BitNode/BitNode.ts b/src/BitNode/BitNode.ts index 8888e8e7c..2d3568d70 100644 --- a/src/BitNode/BitNode.ts +++ b/src/BitNode/BitNode.ts @@ -173,7 +173,10 @@ export function initBitNodes() { "Level 3: Ability to use limit/stop orders in other BitNodes

" + "This Source-File also increases your hacking growth multipliers by: " + "
Level 1: 12%
Level 2: 18%
Level 3: 21%"); - BitNodes["BitNode9"] = new BitNode(9, "Do Androids Dream?", "COMING SOON"); + BitNodes["BitNode9"] = new BitNode(9, "Hacktocracy", "Hacknet Unleashed", + "When Fulcrum Technologies released their open-source Linux distro Chapeau, it quickly " + + "became the OS of choice for the underground hacking community. Chapeau became especially notorious for " + + "powering the Hacknet, "); BitNodes["BitNode10"] = new BitNode(10, "Digital Carbon", "Your body is not who you are", "In 2084, VitaLife unveiled to the world the Persona Core, a technology that allowed people " + "to digitize their consciousness. Their consciousness could then be transferred into Synthoids " + @@ -245,9 +248,9 @@ export function initBitNodeMultipliers(p: IPlayer) { } switch (p.bitNodeN) { - case 1: //Source Genesis (every multiplier is 1) + case 1: // Source Genesis (every multiplier is 1) break; - case 2: //Rise of the Underworld + case 2: // Rise of the Underworld BitNodeMultipliers.HackingLevelMultiplier = 0.8; BitNodeMultipliers.ServerGrowthRate = 0.8; BitNodeMultipliers.ServerMaxMoney = 0.2; @@ -257,7 +260,7 @@ export function initBitNodeMultipliers(p: IPlayer) { BitNodeMultipliers.FactionWorkRepGain = 0.5; BitNodeMultipliers.FactionPassiveRepGain = 0; break; - case 3: //Corporatocracy + case 3: // Corporatocracy BitNodeMultipliers.HackingLevelMultiplier = 0.8; BitNodeMultipliers.RepToDonateToFaction = 0.5; BitNodeMultipliers.AugmentationRepCost = 3; @@ -272,7 +275,7 @@ export function initBitNodeMultipliers(p: IPlayer) { BitNodeMultipliers.HomeComputerRamCost = 1.5; BitNodeMultipliers.PurchasedServerCost = 2; break; - case 4: //The Singularity + case 4: // The Singularity BitNodeMultipliers.ServerMaxMoney = 0.15; BitNodeMultipliers.ServerStartingMoney = 0.75; BitNodeMultipliers.ScriptHackMoney = 0.2; @@ -286,7 +289,7 @@ export function initBitNodeMultipliers(p: IPlayer) { BitNodeMultipliers.CrimeExpGain = 0.5; BitNodeMultipliers.FactionWorkRepGain = 0.75; break; - case 5: //Artificial intelligence + case 5: // Artificial intelligence BitNodeMultipliers.ServerMaxMoney = 2; BitNodeMultipliers.ServerStartingSecurity = 2; BitNodeMultipliers.ServerStartingMoney = 0.5; @@ -299,7 +302,7 @@ export function initBitNodeMultipliers(p: IPlayer) { BitNodeMultipliers.HackExpGain = 0.5; BitNodeMultipliers.CorporationValuation = 0.5; break; - case 6: //Bladeburner + case 6: // Bladeburner BitNodeMultipliers.HackingLevelMultiplier = 0.35; BitNodeMultipliers.ServerMaxMoney = 0.4; BitNodeMultipliers.ServerStartingMoney = 0.5; @@ -314,7 +317,7 @@ export function initBitNodeMultipliers(p: IPlayer) { BitNodeMultipliers.HackExpGain = 0.25; BitNodeMultipliers.DaedalusAugsRequirement = 1.166; // Results in 35 Augs needed break; - case 7: //Bladeburner 2079 + case 7: // Bladeburner 2079 BitNodeMultipliers.BladeburnerRank = 0.6; BitNodeMultipliers.BladeburnerSkillCost = 2; BitNodeMultipliers.AugmentationMoneyCost = 3; @@ -334,7 +337,7 @@ export function initBitNodeMultipliers(p: IPlayer) { BitNodeMultipliers.FourSigmaMarketDataApiCost = 2; BitNodeMultipliers.DaedalusAugsRequirement = 1.166; // Results in 35 Augs needed break; - case 8: //Ghost of Wall Street + case 8: // Ghost of Wall Street BitNodeMultipliers.ScriptHackMoney = 0; BitNodeMultipliers.ManualHackMoney = 0; BitNodeMultipliers.CompanyWorkMoney = 0; @@ -345,6 +348,19 @@ export function initBitNodeMultipliers(p: IPlayer) { BitNodeMultipliers.CorporationValuation = 0; BitNodeMultipliers.CodingContractMoney = 0; break; + case 9: // Hacktocracy + BitNodeMultipliers.HackingLevelMultiplier = 0.3; + BitNodeMultipliers.StrengthLevelMultiplier = 0.45; + BitNodeMultipliers.DefenseLevelMultiplier = 0.45; + BitNodeMultipliers.DexterityLevelMultiplier = 0.45; + BitNodeMultipliers.AgilityLevelMultiplier = 0.45; + BitNodeMultipliers.CharismaLevelMultiplier = 0.45; + BitNodeMultipliers.PurchasedServerLimit = 0; + BitNodeMultipliers.HomeComputerRamCost = 3; + BitNodeMultipliers.CrimeMoney = 0.5; + BitNodeMultipliers.ScriptHackMoney = 0.1; + BitNodeMultipliers.HackExpGain = 0.1; + break; case 10: // Digital Carbon BitNodeMultipliers.HackingLevelMultiplier = 0.2; BitNodeMultipliers.StrengthLevelMultiplier = 0.4; diff --git a/src/BitNode/BitNodeMultipliers.ts b/src/BitNode/BitNodeMultipliers.ts index e6d66062c..0a9334d59 100644 --- a/src/BitNode/BitNodeMultipliers.ts +++ b/src/BitNode/BitNodeMultipliers.ts @@ -120,7 +120,8 @@ interface IBitNodeMultipliers { HackingLevelMultiplier: number; /** - * Influences how much money each Hacknet node can generate. + * Influences how much money is produced by Hacknet Nodes. + * Influeces the hash rate of Hacknet Servers (unlocked in BitNode-9) */ HacknetNodeMoney: number; diff --git a/src/Constants.ts b/src/Constants.ts index a34343427..cb56cb3d2 100644 --- a/src/Constants.ts +++ b/src/Constants.ts @@ -1,3 +1,8 @@ +/** + * Generic Game Constants + * + * Constants for specific mechanics or features will NOT be here. + */ import {IMap} from "./types"; export let CONSTANTS: IMap = { @@ -17,24 +22,9 @@ export let CONSTANTS: IMap = { /* Base costs */ BaseCostFor1GBOfRamHome: 32000, BaseCostFor1GBOfRamServer: 55000, //1 GB of RAM - BaseCostFor1GBOfRamHacknetNode: 30000, TravelCost: 200e3, - BaseCostForHacknetNode: 1000, - BaseCostForHacknetNodeCore: 500000, - - /* Hacknet Node constants */ - HacknetNodeMoneyGainPerLevel: 1.6, - HacknetNodePurchaseNextMult: 1.85, //Multiplier when purchasing an additional hacknet node - HacknetNodeUpgradeLevelMult: 1.04, //Multiplier for cost when upgrading level - HacknetNodeUpgradeRamMult: 1.28, //Multiplier for cost when upgrading RAM - HacknetNodeUpgradeCoreMult: 1.48, //Multiplier for cost when buying another core - - HacknetNodeMaxLevel: 200, - HacknetNodeMaxRam: 64, - HacknetNodeMaxCores: 16, - /* Faction and Company favor */ BaseFavorToDonate: 150, DonateMoneyToRepDivisor: 1e6, diff --git a/src/Hacknet/HacknetHelpers.jsx b/src/Hacknet/HacknetHelpers.jsx new file mode 100644 index 000000000..38246f75a --- /dev/null +++ b/src/Hacknet/HacknetHelpers.jsx @@ -0,0 +1,431 @@ +import { HacknetNode, + BaseCostForHacknetNode, + HacknetNodePurchaseNextMult, + HacknetNodeMaxLevel, + HacknetNodeMaxRam, + HacknetNodeMaxCores } from "./HacknetNode"; +import { HacknetServer, + BaseCostForHacknetServer, + HacknetServerPurchaseMult, + HacknetServerMaxLevel, + HacknetServerMaxRam, + HacknetServerMaxCores, + HacknetServerMaxCache, + MaxNumberHacknetServers } from "./HacknetServer"; +import { HashManager } from "./HashManager"; +import { HashUpgrades } from "./HashUpgrades"; + +import { generateRandomContractOnHome } from "../CodingContractGenerator"; +import { iTutorialSteps, iTutorialNextStep, + ITutorial} from "../InteractiveTutorial"; +import { Player } from "../Player"; +import { AddToAllServers } from "../Server/AllServers"; +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"; + +let hacknetNodesDiv; +function hacknetNodesInit() { + hacknetNodesDiv = document.getElementById("hacknet-nodes-container"); +} + +document.addEventListener("DOMContentLoaded", hacknetNodesInit, false); + +// Returns a boolean indicating whether the player has Hacknet Servers +// (the upgraded form of Hacknet Nodes) +export function hasHacknetServers() { + return (Player.bitNodeN === 9 || SourceFileFlags[9] > 0); +} + +export function purchaseHacknet() { + /* INTERACTIVE TUTORIAL */ + if (ITutorial.isRunning) { + if (ITutorial.currStep === iTutorialSteps.HacknetNodesIntroduction) { + iTutorialNextStep(); + } else { + return; + } + } + + /* END INTERACTIVE TUTORIAL */ + + if (hasHacknetServers()) { + const cost = getCostOfNextHacknetServer(); + if (isNaN(cost)) { + throw new Error(`Calculated cost of purchasing HacknetServer is NaN`) + } + + if (!Player.canAfford(cost)) { return -1; } + + // Auto generate a hostname for this Server + const numOwned = Player.hacknetNodes.length; + const name = `hacknet-node-${numOwned}`; + const server = new HacknetServer({ + adminRights: true, + hostname: name, + player: Player, + }); + + Player.loseMoney(cost); + Player.hacknetNodes.push(server); + + // Configure the HacknetServer to actually act as a Server + AddToAllServers(server); + const homeComputer = Player.getHomeComputer(); + homeComputer.serversOnNetwork.push(server.ip); + server.serversOnNetwork.push(homeComputer.ip); + + return numOwned; + } else { + const cost = getCostOfNextHacknetNode(); + if (isNaN(cost)) { + throw new Error(`Calculated cost of purchasing HacknetNode is NaN`); + } + + if (!Player.canAfford(cost)) { return -1; } + + // Auto generate a name for the Node + const numOwned = Player.hacknetNodes.length; + const name = "hacknet-node-" + numOwned; + const node = new HacknetNode(name); + node.updateMoneyGainRate(Player); + + Player.loseMoney(cost); + Player.hacknetNodes.push(node); + + return numOwned; + } +} + +export function hasMaxNumberHacknetServers() { + return hasHacknetServers() && Player.hacknetNodes.length >= MaxNumberHacknetServers; +} + +export function getCostOfNextHacknetNode() { + // Cost increases exponentially based on how many you own + const numOwned = Player.hacknetNodes.length; + const mult = HacknetNodePurchaseNextMult; + + return BaseCostForHacknetNode * Math.pow(mult, numOwned) * Player.hacknet_node_purchase_cost_mult; +} + +export function getCostOfNextHacknetServer() { + const numOwned = Player.hacknetNodes.length; + const mult = HacknetServerPurchaseMult; + + if (numOwned > MaxNumberHacknetServers) { return Infinity; } + + return BaseCostForHacknetServer * Math.pow(mult, numOwned) * Player.hacknet_node_purchase_cost_mult; +} + +//Calculate the maximum number of times the Player can afford to upgrade a Hacknet Node +export function getMaxNumberLevelUpgrades(nodeObj, maxLevel) { + if (maxLevel == null) { + throw new Error(`getMaxNumberLevelUpgrades() called without maxLevel arg`); + } + + if (Player.money.lt(nodeObj.calculateLevelUpgradeCost(1, Player))) { + return 0; + } + + let min = 1; + let max = maxLevel - 1; + let levelsToMax = maxLevel - nodeObj.level; + if (Player.money.gt(nodeObj.calculateLevelUpgradeCost(levelsToMax, Player))) { + return levelsToMax; + } + + while (min <= max) { + var curr = (min + max) / 2 | 0; + if (curr !== maxLevel && + Player.money.gt(nodeObj.calculateLevelUpgradeCost(curr, Player)) && + Player.money.lt(nodeObj.calculateLevelUpgradeCost(curr + 1, Player))) { + return Math.min(levelsToMax, curr); + } else if (Player.money.lt(nodeObj.calculateLevelUpgradeCost(curr, Player))) { + max = curr - 1; + } else if (Player.money.gt(nodeObj.calculateLevelUpgradeCost(curr, Player))) { + min = curr + 1; + } else { + return Math.min(levelsToMax, curr); + } + } + return 0; +} + +export function getMaxNumberRamUpgrades(nodeObj, maxLevel) { + if (maxLevel == null) { + throw new Error(`getMaxNumberRamUpgrades() called without maxLevel arg`); + } + + if (Player.money.lt(nodeObj.calculateRamUpgradeCost(1, Player))) { + return 0; + } + + let levelsToMax; + if (nodeObj instanceof HacknetServer) { + levelsToMax = Math.round(Math.log2(maxLevel / nodeObj.maxRam)); + } else { + levelsToMax = Math.round(Math.log2(maxLevel / nodeObj.ram)); + } + if (Player.money.gt(nodeObj.calculateRamUpgradeCost(levelsToMax, Player))) { + return levelsToMax; + } + + //We'll just loop until we find the max + for (let i = levelsToMax-1; i >= 0; --i) { + if (Player.money.gt(nodeObj.calculateRamUpgradeCost(i, Player))) { + return i; + } + } + return 0; +} + +export function getMaxNumberCoreUpgrades(nodeObj, maxLevel) { + if (maxLevel == null) { + throw new Error(`getMaxNumberCoreUpgrades() called without maxLevel arg`); + } + + if (Player.money.lt(nodeObj.calculateCoreUpgradeCost(1, Player))) { + return 0; + } + + let min = 1; + let max = maxLevel - 1; + const levelsToMax = maxLevel - nodeObj.cores; + if (Player.money.gt(nodeObj.calculateCoreUpgradeCost(levelsToMax, Player))) { + return levelsToMax; + } + + //Use a binary search to find the max possible number of upgrades + while (min <= max) { + let curr = (min + max) / 2 | 0; + if (curr != maxLevel && + Player.money.gt(nodeObj.calculateCoreUpgradeCost(curr, Player)) && + Player.money.lt(nodeObj.calculateCoreUpgradeCost(curr + 1, Player))) { + return Math.min(levelsToMax, curr); + } else if (Player.money.lt(nodeObj.calculateCoreUpgradeCost(curr, Player))) { + max = curr - 1; + } else if (Player.money.gt(nodeObj.calculateCoreUpgradeCost(curr, Player))) { + min = curr + 1; + } else { + return Math.min(levelsToMax, curr); + } + } + + return 0; +} + +export function getMaxNumberCacheUpgrades(nodeObj, maxLevel) { + if (maxLevel == null) { + throw new Error(`getMaxNumberCacheUpgrades() called without maxLevel arg`); + } + + if (!Player.canAfford(nodeObj.calculateCacheUpgradeCost(1))) { + return 0; + } + + let min = 1; + let max = maxLevel - 1; + const levelsToMax = maxLevel - nodeObj.cache; + if (Player.canAfford(nodeObj.calculateCacheUpgradeCost(levelsToMax))) { + return levelsToMax; + } + + // Use a binary search to find the max possible number of upgrades + while (min <= max) { + let curr = (min + max) / 2 | 0; + if (curr != maxLevel && + Player.canAfford(nodeObj.calculateCacheUpgradeCost(curr)) && + !Player.canAfford(nodeObj.calculateCacheUpgradeCost(curr + 1))) { + return Math.min(levelsToMax, curr); + } else if (!Player.canAfford(nodeObj.calculateCacheUpgradeCost(curr))) { + max = curr -1 ; + } else if (Player.canAfford(nodeObj.calculateCacheUpgradeCost(curr))) { + min = curr + 1; + } else { + return Math.min(levelsToMax, curr); + } + } + + return 0; +} + +// Initial construction of Hacknet Nodes UI +export function renderHacknetNodesUI() { + if (!routing.isOn(Page.HacknetNodes)) { return; } + + ReactDOM.render(, hacknetNodesDiv); +} + +export function clearHacknetNodesUI() { + if (hacknetNodesDiv instanceof HTMLElement) { + ReactDOM.unmountComponentAtNode(hacknetNodesDiv); + } + + hacknetNodesDiv.style.display = "none"; +} + +export function processHacknetEarnings(numCycles) { + // Determine if player has Hacknet Nodes or Hacknet Servers, then + // call the appropriate function + if (Player.hacknetNodes.length === 0) { return 0; } + if (hasHacknetServers()) { + return processAllHacknetServerEarnings(); + } else if (Player.hacknetNodes[0] instanceof HacknetNode) { + return processAllHacknetNodeEarnings(); + } else { + return 0; + } +} + +function processAllHacknetNodeEarnings(numCycles) { + let total = 0; + for (let i = 0; i < Player.hacknetNodes.length; ++i) { + total += processSingleHacknetNodeEarnings(numCycles, Player.hacknetNodes[i]); + } + + return total; +} + +function processSingleHacknetNodeEarnings(numCycles, nodeObj) { + const totalEarnings = nodeObj.process(numCycles); + Player.gainMoney(totalEarnings); + Player.recordMoneySource(totalEarnings, "hacknetnode"); + + return totalEarnings; +} + +function processAllHacknetServerEarnings(numCycles) { + if (!(Player.hashManager instanceof HashManager)) { + throw new Error(`Player does not have a HashManager (should be in 'hashManager' prop)`) + } + + let hashes = 0; + for (let i = 0; i < Player.hacknetNodes.length; ++i) { + hashes += Player.hacknetNodes[i].process(numCycles); + } + + Player.hashManager.storeHashes(hashes); + + return hashes; +} + +export function getHacknetNode(name) { + for (var i = 0; i < Player.hacknetNodes.length; ++i) { + if (Player.hacknetNodes[i].name == name) { + return Player.hacknetNodes[i]; + } + } + + return null; +} + +export function purchaseHashUpgrade(upgName, upgTarget) { + if (!(Player.hashManager instanceof HashManager)) { + console.error(`Player does not have a HashManager`); + return false; + } + + // HashManager handles the transaction. This just needs to actually implement + // the effects of the upgrade + if (Player.hashManager.upgrade(upgName)) { + const upg = HashUpgrades[upgName]; + + switch (upgName) { + case "Sell for Money": { + Player.gainMoney(upg.value); + break; + } + case "Sell for Corporation Funds": { + // This will throw if player doesn't have a corporation + try { + Player.corporation.funds = Player.corporation.funds.plus(upg.value); + } catch(e) { + Player.hashManager.refundUpgrade(upgName); + return false; + } + break; + } + case "Reduce Minimum Security": { + try { + const target = GetServerByHostname(upgTarget); + if (target == null) { + console.error(`Invalid target specified in purchaseHashUpgrade(): ${upgTarget}`); + return false; + } + + target.changeMinimumSecurity(upg.value, true); + } catch(e) { + Player.hashManager.refundUpgrade(upgName); + return false; + } + break; + } + case "Increase Maximum Money": { + try { + const target = GetServerByHostname(upgTarget); + if (target == null) { + console.error(`Invalid target specified in purchaseHashUpgrade(): ${upgTarget}`); + return false; + } + + target.changeMaximumMoney(upg.value, true); + } catch(e) { + Player.hashManager.refundUpgrade(upgName); + return false; + } + break; + } + case "Improve Studying": { + // Multiplier handled by HashManager + break; + } + case "Improve Gym Training": { + // Multiplier handled by HashManager + break; + } + case "Exchange for Corporation Research": { + // This will throw if player doesn't have a corporation + try { + for (const division of Player.corporation.divisions) { + division.sciResearch.qty += upg.value; + } + } catch(e) { + Player.hashManager.refundUpgrade(upgName); + return false; + } + break; + } + case "Exchange for Bladeburner Rank": { + // This will throw if player doesn't have a corporation + try { + for (const division of Player.corporation.divisions) { + division.sciResearch.qty += upg.value; + } + } catch(e) { + Player.hashManager.refundUpgrade(upgName); + return false; + } + break; + } + case "Generate Coding Contract": { + generateRandomContractOnHome(); + break; + } + default: + console.warn(`Unrecognized upgrade name ${upgName}. Upgrade has no effect`) + return false; + } + + console.log("Hash Upgrade successfully purchased"); + return true; + } + + return false; +} diff --git a/src/Hacknet/HacknetNode.ts b/src/Hacknet/HacknetNode.ts new file mode 100644 index 000000000..51b9b2025 --- /dev/null +++ b/src/Hacknet/HacknetNode.ts @@ -0,0 +1,285 @@ +/** + * Hacknet Node Class + * + * Hacknet Nodes are specialized machines that passively earn the player money over time. + * They can be upgraded to increase their production + */ +import { IHacknetNode } from "./IHacknetNode"; + +import { CONSTANTS } from "../Constants"; + +import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; +import { IPlayer } from "../PersonObjects/IPlayer"; + +import { dialogBoxCreate } from "../../utils/DialogBox"; +import { Generic_fromJSON, + Generic_toJSON, + Reviver } from "../../utils/JSONReviver"; + +// Constants for Hacknet Node production +export const HacknetNodeMoneyGainPerLevel: number = 1.6; // Base production per level + +// Constants for Hacknet Node purchase/upgrade costs +export const BaseCostForHacknetNode: number = 1000; +export const BaseCostFor1GBOfRamHacknetNode: number = 30e3; +export const BaseCostForHacknetNodeCore: number = 500e3; +export const HacknetNodePurchaseNextMult: number = 1.85; // Multiplier when purchasing an additional hacknet node +export const HacknetNodeUpgradeLevelMult: number = 1.04; // Multiplier for cost when upgrading level +export const HacknetNodeUpgradeRamMult: number = 1.28; // Multiplier for cost when upgrading RAM +export const HacknetNodeUpgradeCoreMult: number = 1.48; // Multiplier for cost when buying another core + +// Constants for max upgrade levels for Hacknet Nodes +export const HacknetNodeMaxLevel: number = 200; +export const HacknetNodeMaxRam: number = 64; +export const HacknetNodeMaxCores: number = 16; + +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; + + // Node's Level + level: number = 1; + + // Node's production per second + moneyGainRatePerSecond: number = 0; + + // Identifier for Node. Includes the full "name" (hacknet-node-N) + name: string; + + // How long this Node has existed, in seconds + onlineTimeSeconds: number = 0; + + // Node's RAM (GB) + ram: number = 1; + + // Total money earned by this Node + totalMoneyGenerated: number = 0; + + constructor(name: string="") { + this.name = name; + } + + // Get the cost to upgrade this Node's number of cores + calculateCoreUpgradeCost(levels: number=1, p: IPlayer): number { + const sanitizedLevels = Math.round(levels); + if (isNaN(sanitizedLevels) || sanitizedLevels < 1) { + return 0; + } + + if (this.cores >= HacknetNodeMaxCores) { + return Infinity; + } + + const coreBaseCost = BaseCostForHacknetNodeCore; + const mult = HacknetNodeUpgradeCoreMult; + let totalCost = 0; + let currentCores = this.cores; + for (let i = 0; i < sanitizedLevels; ++i) { + totalCost += (coreBaseCost * Math.pow(mult, currentCores-1)); + ++currentCores; + } + + totalCost *= p.hacknet_node_core_cost_mult; + + return totalCost; + } + + // Get the cost to upgrade this Node's level + calculateLevelUpgradeCost(levels: number=1, p: IPlayer): number { + const sanitizedLevels = Math.round(levels); + if (isNaN(sanitizedLevels) || sanitizedLevels < 1) { + return 0; + } + + if (this.level >= HacknetNodeMaxLevel) { + return Infinity; + } + + const mult = HacknetNodeUpgradeLevelMult; + let totalMultiplier = 0; + let currLevel = this.level; + for (let i = 0; i < sanitizedLevels; ++i) { + totalMultiplier += Math.pow(mult, currLevel); + ++currLevel; + } + + return BaseCostForHacknetNode / 2 * totalMultiplier * p.hacknet_node_level_cost_mult; + } + + // Get the cost to upgrade this Node's RAM + calculateRamUpgradeCost(levels: number=1, p: IPlayer): number { + const sanitizedLevels = Math.round(levels); + if (isNaN(sanitizedLevels) || sanitizedLevels < 1) { + return 0; + } + + if (this.ram >= HacknetNodeMaxRam) { + return Infinity; + } + + let totalCost = 0; + let numUpgrades = Math.round(Math.log2(this.ram)); + let currentRam = this.ram; + + for (let i = 0; i < sanitizedLevels; ++i) { + let baseCost = currentRam * BaseCostFor1GBOfRamHacknetNode; + let mult = Math.pow(HacknetNodeUpgradeRamMult, numUpgrades); + + totalCost += (baseCost * mult); + + currentRam *= 2; + ++numUpgrades; + } + + totalCost *= p.hacknet_node_ram_cost_mult; + + return totalCost; + } + + // Process this Hacknet Node in the game loop. + // Returns the amount of money generated + process(numCycles: number=1): number { + const seconds = numCycles * CONSTANTS.MilliPerCycle / 1000; + let gain = this.moneyGainRatePerSecond * seconds; + if (isNaN(gain)) { + console.error(`Hacknet Node ${this.name} calculated earnings of NaN`); + gain = 0; + } + + this.totalMoneyGenerated += gain; + this.onlineTimeSeconds += seconds; + + return gain; + } + + // Upgrade this Node's number of cores, if possible + // Returns a boolean indicating whether new cores were successfully bought + purchaseCoreUpgrade(levels: number=1, p: IPlayer): boolean { + const sanitizedLevels = Math.round(levels); + const cost = this.calculateCoreUpgradeCost(sanitizedLevels, p); + if (isNaN(cost) || sanitizedLevels < 0) { + return false; + } + + // Fail if we're already at max + if (this.cores >= HacknetNodeMaxCores) { + return false; + } + + // If the specified number of upgrades would exceed the max Cores, calculate + // the max possible number of upgrades and use that + if (this.cores + sanitizedLevels > HacknetNodeMaxCores) { + const diff = Math.max(0, HacknetNodeMaxCores - this.cores); + return this.purchaseCoreUpgrade(diff, p); + } + + if (!p.canAfford(cost)) { + return false; + } + + p.loseMoney(cost); + this.cores = Math.round(this.cores + sanitizedLevels); // Just in case of floating point imprecision + this.updateMoneyGainRate(p); + + return true; + } + + // Upgrade this Node's level, if possible + // Returns a boolean indicating whether the level was successfully updated + purchaseLevelUpgrade(levels: number=1, p: IPlayer): boolean { + const sanitizedLevels = Math.round(levels); + const cost = this.calculateLevelUpgradeCost(sanitizedLevels, p); + if (isNaN(cost) || sanitizedLevels < 0) { + return false; + } + + // If we're at max level, return false + if (this.level >= HacknetNodeMaxLevel) { + return false; + } + + // If the number of specified upgrades would exceed the max level, calculate + // the maximum number of upgrades and use that + if (this.level + sanitizedLevels > HacknetNodeMaxLevel) { + var diff = Math.max(0, HacknetNodeMaxLevel - this.level); + return this.purchaseLevelUpgrade(diff, p); + } + + if (!p.canAfford(cost)) { + return false; + } + + p.loseMoney(cost); + this.level = Math.round(this.level + sanitizedLevels); // Just in case of floating point imprecision + this.updateMoneyGainRate(p); + + return true; + } + + // Upgrade this Node's RAM, if possible + // Returns a boolean indicating whether the RAM was successfully upgraded + purchaseRamUpgrade(levels: number=1, p: IPlayer): boolean { + const sanitizedLevels = Math.round(levels); + const cost = this.calculateRamUpgradeCost(sanitizedLevels, p); + if (isNaN(cost) || sanitizedLevels < 0) { + return false; + } + + // Fail if we're already at max + if (this.ram >= HacknetNodeMaxRam) { + return false; + } + + // If the number of specified upgrades would exceed the max RAM, calculate the + // max possible number of upgrades and use that + if (this.ram * Math.pow(2, sanitizedLevels) > HacknetNodeMaxRam) { + var diff = Math.max(0, Math.log2(Math.round(HacknetNodeMaxRam / this.ram))); + return this.purchaseRamUpgrade(diff, p); + } + + if (!p.canAfford(cost)) { + return false; + } + + p.loseMoney(cost); + for (let i = 0; i < sanitizedLevels; ++i) { + this.ram *= 2; // Ram is always doubled + } + this.ram = Math.round(this.ram); // Handle any floating point precision issues + this.updateMoneyGainRate(p); + + return true; + } + + // Re-calculate this Node's production and update the moneyGainRatePerSecond prop + updateMoneyGainRate(p: IPlayer): void { + //How much extra $/s is gained per level + var gainPerLevel = HacknetNodeMoneyGainPerLevel; + + this.moneyGainRatePerSecond = (this.level * gainPerLevel) * + Math.pow(1.035, this.ram - 1) * + ((this.cores + 5) / 6) * + p.hacknet_node_money_mult * + BitNodeMultipliers.HacknetNodeMoney; + if (isNaN(this.moneyGainRatePerSecond)) { + this.moneyGainRatePerSecond = 0; + dialogBoxCreate("Error in calculating Hacknet Node production. Please report to game developer", false); + } + } + + /** + * Serialize the current object to a JSON save state. + */ + toJSON(): any { + return Generic_toJSON("HacknetNode", this); + } +} + +Reviver.constructors.HacknetNode = HacknetNode; diff --git a/src/Hacknet/HacknetServer.ts b/src/Hacknet/HacknetServer.ts new file mode 100644 index 000000000..15022cd1b --- /dev/null +++ b/src/Hacknet/HacknetServer.ts @@ -0,0 +1,348 @@ +/** + * Hacknet Servers - Reworked Hacknet Node mechanic for BitNode-9 + */ +import { CONSTANTS } from "../Constants"; + +import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; +import { IHacknetNode } from "../Hacknet/IHacknetNode"; +import { IPlayer } from "../PersonObjects/IPlayer"; +import { BaseServer } from "../Server/BaseServer"; +import { RunningScript } from "../Script/RunningScript"; + +import { dialogBoxCreate } from "../../utils/DialogBox"; +import { createRandomIp } from "../../utils/IPAddress"; + +import { Generic_fromJSON, + Generic_toJSON, + Reviver } from "../../utils/JSONReviver"; + +// Constants for Hacknet Server stats/production +export const HacknetServerHashesPerLevel: number = 0.001; + +// Constants for Hacknet Server purchase/upgrade costs +export const BaseCostForHacknetServer: number = 10e3; +export const BaseCostFor1GBHacknetServerRam: number = 200e3; +export const BaseCostForHacknetServerCore: number = 1e6; +export const BaseCostForHacknetServerCache: number = 10e6; + +export const HacknetServerPurchaseMult: number = 3.2; // Multiplier for puchasing an additional Hacknet Server +export const HacknetServerUpgradeLevelMult: number = 1.1; // Multiplier for cost when upgrading level +export const HacknetServerUpgradeRamMult: number = 1.4; // Multiplier for cost when upgrading RAM +export const HacknetServerUpgradeCoreMult: number = 1.55; // Multiplier for cost when buying another core +export const HacknetServerUpgradeCacheMult: number = 1.85; // Multiplier for cost when upgrading cache + +export const MaxNumberHacknetServers: number = 25; // Max number of Hacknet Servers you can own + +// Constants for max upgrade levels for Hacknet Server +export const HacknetServerMaxLevel: number = 300; +export const HacknetServerMaxRam: number = 8192; +export const HacknetServerMaxCores: number = 128; +export const HacknetServerMaxCache: number = 15; // Max cache level. So max capacity is 2 ^ 12 + +interface IConstructorParams { + adminRights?: boolean; + hostname: string; + ip?: string; + isConnectedTo?: boolean; + maxRam?: number; + organizationName?: string; + player?: IPlayer; +} + +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; + + // Number of cores. Improves hash production + cores: number = 1; + + // Number of hashes that can be stored by this Hacknet Server + hashCapacity: number = 0; + + // Hashes produced per second + hashRate: number = 0; + + // Similar to Node level. Improves hash production + level: number = 1; + + // How long this HacknetServer has existed, in seconds + onlineTimeSeconds: number = 0; + + // Total number of hashes earned by this + totalHashesGenerated: number = 0; + + constructor(params: IConstructorParams={ hostname: "", ip: createRandomIp() }) { + super(params); + + this.maxRam = 1; + this.updateHashCapacity(); + + if (params.player) { + this.updateHashRate(params.player); + } + } + + calculateCacheUpgradeCost(levels: number): number { + const sanitizedLevels = Math.round(levels); + if (isNaN(sanitizedLevels) || sanitizedLevels < 1) { + return 0; + } + + if (this.cache >= HacknetServerMaxCache) { + return Infinity; + } + + const mult = HacknetServerUpgradeCacheMult; + let totalCost = 0; + let currentCache = this.cache; + for (let i = 0; i < sanitizedLevels; ++i) { + totalCost += Math.pow(mult, currentCache - 1); + ++currentCache; + } + totalCost *= BaseCostForHacknetServerCache; + + return totalCost; + } + + calculateCoreUpgradeCost(levels: number, p: IPlayer): number { + const sanitizedLevels = Math.round(levels); + if (isNaN(sanitizedLevels) || sanitizedLevels < 1) { + return 0; + } + + if (this.cores >= HacknetServerMaxCores) { + return Infinity; + } + + const mult = HacknetServerUpgradeCoreMult; + let totalCost = 0; + let currentCores = this.cores; + for (let i = 0; i < sanitizedLevels; ++i) { + totalCost += Math.pow(mult, currentCores-1); + ++currentCores; + } + totalCost *= BaseCostForHacknetServerCore; + totalCost *= p.hacknet_node_core_cost_mult; + + return totalCost; + } + + calculateLevelUpgradeCost(levels: number, p: IPlayer): number { + const sanitizedLevels = Math.round(levels); + if (isNaN(sanitizedLevels) || sanitizedLevels < 1) { + return 0; + } + + if (this.level >= HacknetServerMaxLevel) { + return Infinity; + } + + const mult = HacknetServerUpgradeLevelMult; + let totalMultiplier = 0; + let currLevel = this.level; + for (let i = 0; i < sanitizedLevels; ++i) { + totalMultiplier += Math.pow(mult, currLevel); + ++currLevel; + } + + return 10 * BaseCostForHacknetServer * totalMultiplier * p.hacknet_node_level_cost_mult; + } + + calculateRamUpgradeCost(levels: number, p: IPlayer): number { + const sanitizedLevels = Math.round(levels); + if (isNaN(sanitizedLevels) || sanitizedLevels < 1) { + return 0; + } + + if (this.maxRam >= HacknetServerMaxRam) { + return Infinity; + } + + let totalCost = 0; + let numUpgrades = Math.round(Math.log2(this.maxRam)); + let currentRam = this.maxRam; + for (let i = 0; i < sanitizedLevels; ++i) { + let baseCost = currentRam * BaseCostFor1GBHacknetServerRam; + let mult = Math.pow(HacknetServerUpgradeRamMult, numUpgrades); + + totalCost += (baseCost * mult); + + currentRam *= 2; + ++numUpgrades; + } + totalCost *= p.hacknet_node_ram_cost_mult; + + return totalCost; + } + + // Process this Hacknet Server in the game loop. + // Returns the number of hashes generated + process(numCycles: number=1): number { + const seconds = numCycles * CONSTANTS.MilliPerCycle / 1000; + + return this.hashRate * seconds; + } + + // Returns a boolean indicating whether the cache was successfully upgraded + purchaseCacheUpgrade(levels: number, p: IPlayer): boolean { + const sanitizedLevels = Math.round(levels); + const cost = this.calculateCacheUpgradeCost(levels); + if (isNaN(cost) || cost <= 0 || sanitizedLevels <= 0) { + return false; + } + + if (this.cache >= HacknetServerMaxCache) { + return false; + } + + // If the specified number of upgrades would exceed the max, try to purchase + // the maximum possible + if (this.cache + levels > HacknetServerMaxCache) { + const diff = Math.max(0, HacknetServerMaxCache - this.cache); + return this.purchaseCacheUpgrade(diff, p); + } + + if (!p.canAfford(cost)) { + return false; + } + + p.loseMoney(cost); + this.cache = Math.round(this.cache + sanitizedLevels); + this.updateHashCapacity(); + + return true; + } + + // Returns a boolean indicating whether the number of cores was successfully upgraded + purchaseCoreUpgrade(levels: number, p: IPlayer): boolean { + const sanitizedLevels = Math.round(levels); + const cost = this.calculateCoreUpgradeCost(sanitizedLevels, p); + if (isNaN(cost) || cost <= 0 || sanitizedLevels <= 0) { + return false; + } + + if (this.cores >= HacknetServerMaxCores) { + return false; + } + + // If the specified number of upgrades would exceed the max, try to purchase + // the maximum possible + if (this.cores + sanitizedLevels > HacknetServerMaxCores) { + const diff = Math.max(0, HacknetServerMaxCores - this.cores); + return this.purchaseCoreUpgrade(diff, p); + } + + if (!p.canAfford(cost)) { + return false; + } + + p.loseMoney(cost); + this.cores = Math.round(this.cores + sanitizedLevels); + this.updateHashRate(p); + + return true; + } + + // Returns a boolean indicating whether the level was successfully upgraded + purchaseLevelUpgrade(levels: number, p: IPlayer): boolean { + const sanitizedLevels = Math.round(levels); + const cost = this.calculateLevelUpgradeCost(sanitizedLevels, p); + if (isNaN(cost) || cost <= 0 || sanitizedLevels <= 0) { + return false; + } + + if (this.level >= HacknetServerMaxLevel) { + return false; + } + + // If the specified number of upgrades would exceed the max, try to purchase the + // maximum possible + if (this.level + sanitizedLevels > HacknetServerMaxLevel) { + const diff = Math.max(0, HacknetServerMaxLevel - this.level); + return this.purchaseLevelUpgrade(diff, p); + } + + if (!p.canAfford(cost)) { + return false; + } + + p.loseMoney(cost); + this.level = Math.round(this.level + sanitizedLevels); + this.updateHashRate(p); + + return true; + } + + // Returns a boolean indicating whether the RAM was successfully upgraded + purchaseRamUpgrade(levels: number, p: IPlayer): boolean { + const sanitizedLevels = Math.round(levels); + const cost = this.calculateRamUpgradeCost(sanitizedLevels, p); + if(isNaN(cost) || cost <= 0 || sanitizedLevels <= 0) { + return false; + } + + if (this.maxRam >= HacknetServerMaxRam) { + return false; + } + + // If the specified number of upgrades would exceed the max, try to purchase + // just the maximum possible + if (this.maxRam * Math.pow(2, sanitizedLevels) > HacknetServerMaxRam) { + const diff = Math.max(0, Math.log2(Math.round(HacknetServerMaxRam / this.maxRam))); + return this.purchaseRamUpgrade(diff, p); + } + + if (!p.canAfford(cost)) { + return false; + } + + p.loseMoney(cost); + for (let i = 0; i < sanitizedLevels; ++i) { + this.maxRam *= 2; + } + this.maxRam = Math.round(this.maxRam); + + return true; + } + + /** + * Whenever a script is run, we must update this server's hash rate + */ + runScript(script: RunningScript, p?: IPlayer): void { + super.runScript(script); + if (p) { + this.updateHashRate(p); + } + } + + updateHashCapacity(): void { + this.hashCapacity = 16 * Math.pow(2, this.cache); + } + + updateHashRate(p: IPlayer): void { + const baseGain = HacknetServerHashesPerLevel * this.level; + const coreMultiplier = Math.pow(1.1, this.cores - 1); + const ramRatio = (1 - this.ramUsed / this.maxRam); + + const hashRate = baseGain * coreMultiplier * ramRatio; + + this.hashRate = hashRate * p.hacknet_node_money_mult * BitNodeMultipliers.HacknetNodeMoney; + + if (isNaN(this.hashRate)) { + this.hashRate = 0; + dialogBoxCreate(`Error calculating Hacknet Server hash production. This is a bug. Please report to game dev`, false); + } + } + + // Serialize the current object to a JSON save state + toJSON(): any { + return Generic_toJSON("HacknetServer", this); + } +} + +Reviver.constructors.HacknetServer = HacknetServer; diff --git a/src/Hacknet/HashManager.ts b/src/Hacknet/HashManager.ts new file mode 100644 index 000000000..4aa9fa5f8 --- /dev/null +++ b/src/Hacknet/HashManager.ts @@ -0,0 +1,151 @@ +/** + * This is a central class for storing and managing the player's hashes, + * which are generated by Hacknet Servers + * + * It is also used to keep track of what upgrades the player has bought with + * his hashes, and contains method for grabbing the data/multipliers from + * those upgrades + */ +import { HacknetServer } from "./HacknetServer"; +import { HashUpgrades } from "./HashUpgrades"; + +import { IMap } from "../types"; +import { IPlayer } from "../PersonObjects/IPlayer"; +import { Generic_fromJSON, + Generic_toJSON, + 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; + + // Number of hashes currently in storage + hashes: number = 0; + + // Map of Hash Upgrade Name -> levels in that upgrade + upgrades: IMap = {}; + + constructor() { + for (const name in HashUpgrades) { + this.upgrades[name] = 0; + } + } + + /** + * Generic helper function for getting a multiplier from a HashUpgrade + */ + getMult(upgName: string): number { + const upg = HashUpgrades[upgName]; + const currLevel = this.upgrades[upgName]; + if (upg == null || currLevel == null) { + console.error(`Could not find Hash Study upgrade`); + return 1; + } + + return 1 + ((upg.value * currLevel) / 100); + } + + /** + * One of the Hash upgrades improves studying. This returns that multiplier + */ + getStudyMult(): number { + const upgName = "Improve Studying"; + + return this.getMult(upgName); + } + + /** + * One of the Hash upgrades improves gym training. This returns that multiplier + */ + getTrainingMult(): number { + const upgName = "Improve Gym Training"; + + return this.getMult(upgName); + } + + /** + * Get the cost (in hashes) of an upgrade + */ + getUpgradeCost(upgName: string): number { + const upg = HashUpgrades[upgName]; + const currLevel = this.upgrades[upgName]; + if (upg == null || currLevel == null) { + console.error(`Invalid Upgrade Name given to HashManager.getUpgradeCost(): ${upgName}`); + return Infinity; + } + + return upg.getCost(currLevel); + } + + storeHashes(numHashes: number): void { + this.hashes += numHashes; + this.hashes = Math.min(this.hashes, this.capacity); + } + + /** + * Reverts an upgrade and refunds the hashes used to buy it + */ + refundUpgrade(upgName: string): void { + const upg = HashUpgrades[upgName]; + const currLevel = this.upgrades[upgName]; + if (upg == null || currLevel == null || currLevel === 0) { + console.error(`Invalid Upgrade Name given to HashManager.upgrade(): ${upgName}`); + return; + } + + // Reduce the level first, so we get the right cost + --this.upgrades[upgName]; + const cost = upg.getCost(currLevel); + this.hashes += cost; + } + + updateCapacity(p: IPlayer): void { + if (p.hacknetNodes.length <= 0) { this.capacity = 0; } + if (!(p.hacknetNodes[0] instanceof HacknetServer)) { this.capacity = 0; } + + let total: number = 0; + for (let i = 0; i < p.hacknetNodes.length; ++i) { + const hacknetServer = (p.hacknetNodes[i]); + total += hacknetServer.hashCapacity; + } + + this.capacity = total; + } + + /** + * Returns boolean indicating whether or not the upgrade was successfully purchased + * Note that this does NOT actually implement the effect + */ + upgrade(upgName: string): boolean { + const upg = HashUpgrades[upgName]; + const currLevel = this.upgrades[upgName]; + if (upg == null || currLevel == null) { + console.error(`Invalid Upgrade Name given to HashManager.upgrade(): ${upgName}`); + return false; + } + + const cost = upg.getCost(currLevel); + + if (this.hashes < cost) { + return false; + } + + this.hashes -= cost; + ++this.upgrades[upgName]; + + return true; + } + + //Serialize the current object to a JSON save state. + toJSON(): any { + return Generic_toJSON("HashManager", this); + } +} + +Reviver.constructors.HashManager = HashManager; diff --git a/src/Hacknet/HashUpgrade.ts b/src/Hacknet/HashUpgrade.ts new file mode 100644 index 000000000..9f76e995b --- /dev/null +++ b/src/Hacknet/HashUpgrade.ts @@ -0,0 +1,48 @@ +/** + * Object representing an upgrade that can be purchased with hashes + */ +export interface IConstructorParams { + costPerLevel: number; + desc: string; + hasTargetServer?: boolean; + name: string; + value: number; +} + +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; + + /** + * Description of what the upgrade does + */ + desc: string = ""; + + /** + * Boolean indicating that this upgrade's effect affects a single server, + * the "target" server + */ + hasTargetServer: boolean = false; + + // Name of upgrade + name: string = ""; + + // Generic value used to indicate the potency/amount of this upgrade's effect + // The meaning varies between different upgrades + value: number = 0; + + constructor(p: IConstructorParams) { + this.costPerLevel = p.costPerLevel; + this.desc = p.desc; + this.hasTargetServer = p.hasTargetServer ? p.hasTargetServer : false; + this.name = p.name; + this.value = p.value; + } + + getCost(levels: number): number { + return Math.round((levels + 1) * this.costPerLevel); + } +} diff --git a/src/Hacknet/HashUpgrades.ts b/src/Hacknet/HashUpgrades.ts new file mode 100644 index 000000000..0a89e2525 --- /dev/null +++ b/src/Hacknet/HashUpgrades.ts @@ -0,0 +1,18 @@ +/** + * Map of all Hash Upgrades + * Key = Hash name, Value = HashUpgrade object + */ +import { HashUpgrade, + IConstructorParams } from "./HashUpgrade"; +import { HashUpgradesMetadata } from "./data/HashUpgradesMetadata"; +import { IMap } from "../types"; + +export const HashUpgrades: IMap = {}; + +function createHashUpgrade(p: IConstructorParams) { + HashUpgrades[p.name] = new HashUpgrade(p); +} + +for (const metadata of HashUpgradesMetadata) { + createHashUpgrade(metadata); +} diff --git a/src/Hacknet/IHacknetNode.ts b/src/Hacknet/IHacknetNode.ts new file mode 100644 index 000000000..32ec81f53 --- /dev/null +++ b/src/Hacknet/IHacknetNode.ts @@ -0,0 +1,16 @@ +// Interface for a Hacknet Node. Implemented by both a basic Hacknet Node, +// and the upgraded Hacknet Server in BitNode-9 +import { IPlayer } from "../PersonObjects/IPlayer"; + +export interface IHacknetNode { + cores: number; + level: number; + onlineTimeSeconds: number; + + calculateCoreUpgradeCost: (levels: number, p: IPlayer) => number; + calculateLevelUpgradeCost: (levels: number, p: IPlayer) => number; + calculateRamUpgradeCost: (levels: number, p: IPlayer) => number; + purchaseCoreUpgrade: (levels: number, p: IPlayer) => boolean; + purchaseLevelUpgrade: (levels: number, p: IPlayer) => boolean; + purchaseRamUpgrade: (levels: number, p: IPlayer) => boolean; +} diff --git a/src/Hacknet/data/HashUpgradesMetadata.ts b/src/Hacknet/data/HashUpgradesMetadata.ts new file mode 100644 index 000000000..d1904ec35 --- /dev/null +++ b/src/Hacknet/data/HashUpgradesMetadata.ts @@ -0,0 +1,64 @@ +// Metadata used to construct all Hash Upgrades +import { IConstructorParams } from "../HashUpgrade"; + +export const HashUpgradesMetadata: IConstructorParams[] = [ + { + costPerLevel: 2, + desc: "Sell hashes for $1m", + name: "Sell for Money", + value: 1e6, + }, + { + costPerLevel: 100, + desc: "Sell hashes for $1b in Corporation funds", + name: "Sell for Corporation Funds", + value: 1e9, + }, + { + costPerLevel: 100, + desc: "Use hashes to decrease the minimum security of a single server by 5%. " + + "Note that a server's minimum security cannot go below 1.", + hasTargetServer: true, + name: "Reduce Minimum Security", + value: 0.95, + }, + { + costPerLevel: 100, + desc: "Use hashes to increase the maximum amount of money on a single server by 5%", + hasTargetServer: true, + name: "Increase Maximum Money", + value: 1.05, + }, + { + costPerLevel: 100, + desc: "Use hashes to improve the experience earned when studying at a university. " + + "This effect persists until you install Augmentations", + name: "Improve Studying", + value: 20, // Improves studying by value% + }, + { + costPerLevel: 100, + desc: "Use hashes to improve the experience earned when training at the gym. This effect " + + "persists until you install Augmentations", + name: "Improve Gym Training", + value: 20, // Improves training by value% + }, + { + costPerLevel: 250, + desc: "Exchange hashes for 1k Scientific Research in all of your Corporation's Industries", + name: "Exchange for Corporation Research", + value: 1000, + }, + { + costPerLevel: 250, + desc: "Exchange hashes for 100 Bladeburner Rank", + name: "Exchange for Bladeburner Rank", + value: 100, + }, + { + costPerLevel: 200, + desc: "Generate a random Coding Contract on your home computer", + name: "Generate Coding Contract", + value: 1, + }, +] diff --git a/src/Hacknet/ui/GeneralInfo.jsx b/src/Hacknet/ui/GeneralInfo.jsx new file mode 100644 index 000000000..3e4b7cd1d --- /dev/null +++ b/src/Hacknet/ui/GeneralInfo.jsx @@ -0,0 +1,56 @@ +/** + * React Component for the Hacknet Node UI + * + * Displays general information about Hacknet Nodes + */ +import React from "react"; + +import { hasHacknetServers } from "../HacknetHelpers"; + +export class GeneralInfo extends React.Component { + getSecondParagraph() { + if (hasHacknetServers()) { + return `Here, you can purchase a Hacknet Server, an upgraded version of the Hacknet Node. ` + + `Hacknet Servers will perform computations and operations on the network, earning ` + + `you hashes. Hashes can be spent on a variety of different upgrades.`; + } else { + return `Here, you can purchase a Hacknet Node, a specialized machine that can connect ` + + `and contribute its resources to the Hacknet networ. This allows you to take ` + + `a small percentage of profits from hacks performed on the network. Essentially, ` + + `you are renting out your Node's computing power.`; + } + } + + getThirdParagraph() { + if (hasHacknetServers()) { + return `Hacknet Servers can also be used as servers to run scripts. However, running scripts ` + + `on a server will reduce its hash rate (hashes generated per second). A Hacknet Server's hash ` + + `rate will be reduced by the percentage of RAM that is being used by that Server to run ` + + `scripts.` + } else { + return `Each Hacknet Node you purchase will passively earn you money. Each Hacknet Node ` + + `can be upgraded in order to increase its computing power and thereby increase ` + + `the profit you earn from it.`; + } + } + + render() { + return ( +
+

+ The Hacknet is a global, decentralized network of machines. It is used by + hackers all around the world to anonymously share computing power and + perform distributed cyberattacks without the fear of being traced. +

+
+

+ {this.getSecondParagraph()} +

+
+

+ {this.getThirdParagraph()} +

+
+ ) + } +} diff --git a/src/Hacknet/ui/HacknetNode.jsx b/src/Hacknet/ui/HacknetNode.jsx new file mode 100644 index 000000000..6ba40d09a --- /dev/null +++ b/src/Hacknet/ui/HacknetNode.jsx @@ -0,0 +1,153 @@ +/** + * React Component for the Hacknet Node UI. + * This Component displays the panel for a single Hacknet Node + */ +import React from "react"; + +import { HacknetNodeMaxLevel, + HacknetNodeMaxRam, + HacknetNodeMaxCores } from "../HacknetNode"; +import { getMaxNumberLevelUpgrades, + getMaxNumberRamUpgrades, + getMaxNumberCoreUpgrades } from "../HacknetHelpers"; + +import { Player } from "../../Player"; + +import { numeralWrapper } from "../../ui/numeralFormat"; + +export class HacknetNode extends React.Component { + render() { + const node = this.props.node; + const purchaseMult = this.props.purchaseMultiplier; + const recalculate = this.props.recalculate; + + // Upgrade Level Button + let upgradeLevelText, upgradeLevelClass; + if (node.level >= HacknetNodeMaxLevel) { + upgradeLevelText = "MAX LEVEL"; + upgradeLevelClass = "std-button-disabled"; + } else { + let multiplier = 0; + if (purchaseMult === "MAX") { + multiplier = getMaxNumberLevelUpgrades(node, HacknetNodeMaxLevel); + } else { + const levelsToMax = HacknetNodeMaxLevel - node.level; + multiplier = Math.min(levelsToMax, purchaseMult); + } + + const upgradeLevelCost = node.calculateLevelUpgradeCost(multiplier, Player); + upgradeLevelText = `Upgrade x${multiplier} - ${numeralWrapper.formatMoney(upgradeLevelCost)}`; + if (Player.money.lt(upgradeLevelCost)) { + upgradeLevelClass = "std-button-disabled"; + } else { + upgradeLevelClass = "std-button"; + } + } + const upgradeLevelOnClick = () => { + let numUpgrades = purchaseMult; + if (purchaseMult === "MAX") { + numUpgrades = getMaxNumberLevelUpgrades(node, HacknetNodeMaxLevel); + } + node.purchaseLevelUpgrade(numUpgrades, Player); + recalculate(); + return false; + } + + let upgradeRamText, upgradeRamClass; + if (node.ram >= HacknetNodeMaxRam) { + upgradeRamText = "MAX RAM"; + upgradeRamClass = "std-button-disabled"; + } else { + let multiplier = 0; + if (purchaseMult === "MAX") { + multiplier = getMaxNumberRamUpgrades(node, HacknetNodeMaxRam); + } else { + const levelsToMax = Math.round(Math.log2(HacknetNodeMaxRam / node.ram)); + multiplier = Math.min(levelsToMax, purchaseMult); + } + + const upgradeRamCost = node.calculateRamUpgradeCost(multiplier, Player); + upgradeRamText = `Upgrade x${multiplier} - ${numeralWrapper.formatMoney(upgradeRamCost)}`; + if (Player.money.lt(upgradeRamCost)) { + upgradeRamClass = "std-button-disabled"; + } else { + upgradeRamClass = "std-button"; + } + } + const upgradeRamOnClick = () => { + let numUpgrades = purchaseMult; + if (purchaseMult === "MAX") { + numUpgrades = getMaxNumberRamUpgrades(node, HacknetNodeMaxRam); + } + node.purchaseRamUpgrade(numUpgrades, Player); + recalculate(); + return false; + } + + let upgradeCoresText, upgradeCoresClass; + if (node.cores >= HacknetNodeMaxCores) { + upgradeCoresText = "MAX CORES"; + upgradeCoresClass = "std-button-disabled"; + } else { + let multiplier = 0; + if (purchaseMult === "MAX") { + multiplier = getMaxNumberCoreUpgrades(node, HacknetNodeMaxCores); + } else { + const levelsToMax = HacknetNodeMaxCores - node.cores; + multiplier = Math.min(levelsToMax, purchaseMult); + } + + const upgradeCoreCost = node.calculateCoreUpgradeCost(multiplier, Player); + upgradeCoresText = `Upgrade x${multiplier} - ${numeralWrapper.formatMoney(upgradeCoreCost)}`; + if (Player.money.lt(upgradeCoreCost)) { + upgradeCoresClass = "std-button-disabled"; + } else { + upgradeCoresClass = "std-button"; + } + } + const upgradeCoresOnClick = () => { + let numUpgrades = purchaseMult; + if (purchaseMult === "MAX") { + numUpgrades = getMaxNumberCoreUpgrades(node, HacknetNodeMaxCores); + } + node.purchaseCoreUpgrade(numUpgrades, Player); + recalculate(); + return false; + } + + return ( +
  • +
    +
    +

    Node name:

    + {node.name} +
    +
    +

    Production:

    + + {numeralWrapper.formatMoney(node.totalMoneyGenerated)} ({numeralWrapper.formatMoney(node.moneyGainRatePerSecond)} / sec) + +
    +
    +

    Level:

    {node.level} + +
    +
    +

    RAM:

    {node.ram}GB + +
    +
    +

    Cores:

    {node.cores} + +
    +
    +
  • + ) + } +} diff --git a/src/Hacknet/ui/HacknetServer.jsx b/src/Hacknet/ui/HacknetServer.jsx new file mode 100644 index 000000000..5e69dc387 --- /dev/null +++ b/src/Hacknet/ui/HacknetServer.jsx @@ -0,0 +1,200 @@ +/** + * React Component for the Hacknet Node UI. + * This Component displays the panel for a single Hacknet Node + */ +import React from "react"; + +import { HacknetServerMaxLevel, + HacknetServerMaxRam, + HacknetServerMaxCores, + HacknetServerMaxCache } from "../HacknetServer"; +import { getMaxNumberLevelUpgrades, + getMaxNumberRamUpgrades, + getMaxNumberCoreUpgrades, + getMaxNumberCacheUpgrades } from "../HacknetHelpers"; + +import { Player } from "../../Player"; + +import { numeralWrapper } from "../../ui/numeralFormat"; + +export class HacknetServer extends React.Component { + render() { + const node = this.props.node; + const purchaseMult = this.props.purchaseMultiplier; + const recalculate = this.props.recalculate; + + // Upgrade Level Button + let upgradeLevelText, upgradeLevelClass; + if (node.level >= HacknetServerMaxLevel) { + upgradeLevelText = "MAX LEVEL"; + upgradeLevelClass = "std-button-disabled"; + } else { + let multiplier = 0; + if (purchaseMult === "MAX") { + multiplier = getMaxNumberLevelUpgrades(node, HacknetServerMaxLevel); + } else { + const levelsToMax = HacknetServerMaxLevel - node.level; + multiplier = Math.min(levelsToMax, purchaseMult); + } + + const upgradeLevelCost = node.calculateLevelUpgradeCost(multiplier, Player); + upgradeLevelText = `Upgrade x${multiplier} - ${numeralWrapper.formatMoney(upgradeLevelCost)}`; + if (Player.money.lt(upgradeLevelCost)) { + upgradeLevelClass = "std-button-disabled"; + } else { + upgradeLevelClass = "std-button"; + } + } + const upgradeLevelOnClick = () => { + let numUpgrades = purchaseMult; + if (purchaseMult === "MAX") { + numUpgrades = getMaxNumberLevelUpgrades(node, HacknetServerMaxLevel); + } + node.purchaseLevelUpgrade(numUpgrades, Player); + recalculate(); + return false; + } + + // Upgrade RAM Button + let upgradeRamText, upgradeRamClass; + if (node.maxRam >= HacknetServerMaxRam) { + upgradeRamText = "MAX RAM"; + upgradeRamClass = "std-button-disabled"; + } else { + let multiplier = 0; + if (purchaseMult === "MAX") { + multiplier = getMaxNumberRamUpgrades(node, HacknetServerMaxRam); + } else { + const levelsToMax = Math.round(Math.log2(HacknetServerMaxRam / node.maxRam)); + multiplier = Math.min(levelsToMax, purchaseMult); + } + + const upgradeRamCost = node.calculateRamUpgradeCost(multiplier, Player); + upgradeRamText = `Upgrade x${multiplier} - ${numeralWrapper.formatMoney(upgradeRamCost)}`; + if (Player.money.lt(upgradeRamCost)) { + upgradeRamClass = "std-button-disabled"; + } else { + upgradeRamClass = "std-button"; + } + } + const upgradeRamOnClick = () => { + let numUpgrades = purchaseMult; + if (purchaseMult === "MAX") { + numUpgrades = getMaxNumberRamUpgrades(node, HacknetServerMaxRam); + } + node.purchaseRamUpgrade(numUpgrades, Player); + recalculate(); + return false; + } + + // Upgrade Cores Button + let upgradeCoresText, upgradeCoresClass; + if (node.cores >= HacknetServerMaxCores) { + upgradeCoresText = "MAX CORES"; + upgradeCoresClass = "std-button-disabled"; + } else { + let multiplier = 0; + if (purchaseMult === "MAX") { + multiplier = getMaxNumberCoreUpgrades(node, HacknetServerMaxCores); + } else { + const levelsToMax = HacknetServerMaxCores - node.cores; + multiplier = Math.min(levelsToMax, purchaseMult); + } + + const upgradeCoreCost = node.calculateCoreUpgradeCost(multiplier, Player); + upgradeCoresText = `Upgrade x${multiplier} - ${numeralWrapper.formatMoney(upgradeCoreCost)}`; + if (Player.money.lt(upgradeCoreCost)) { + upgradeCoresClass = "std-button-disabled"; + } else { + upgradeCoresClass = "std-button"; + } + } + const upgradeCoresOnClick = () => { + let numUpgrades = purchaseMult; + if (purchaseMult === "MAX") { + numUpgrades = getMaxNumberCoreUpgrades(node, HacknetServerMaxCores); + } + node.purchaseCoreUpgrade(numUpgrades, Player); + recalculate(); + return false; + } + + // Upgrade Cache button + let upgradeCacheText, upgradeCacheClass; + if (node.cache >= HacknetServerMaxCache) { + upgradeCacheText = "MAX CACHE"; + upgradeCacheClass = "std-button-disabled"; + } else { + let multiplier = 0; + if (purchaseMult === "MAX") { + multiplier = getMaxNumberCacheUpgrades(node, HacknetServerMaxCache); + } else { + const levelsToMax = HacknetServerMaxCache - node.cache; + multiplier = Math.min(levelsToMax, purchaseMult); + } + + const upgradeCacheCost = node.calculateCacheUpgradeCost(multiplier); + upgradeCacheText = `Upgrade x${multiplier} - ${numeralWrapper.formatMoney(upgradeCacheCost)}`; + if (Player.money.lt(upgradeCacheCost)) { + upgradeCacheClass = "std-button-disabled"; + } else { + upgradeCacheClass = "std-button"; + } + } + const upgradeCacheOnClick = () => { + let numUpgrades = purchaseMult; + if (purchaseMult === "MAX") { + numUpgrades = getMaxNumberCacheUpgrades(node, HacknetServerMaxCache); + } + node.purchaseCacheUpgrade(numUpgrades, Player); + recalculate(); + Player.hashManager.updateCapacity(Player); + return false; + } + + return ( +
  • +
    +
    +

    Node name:

    + {node.hostname} +
    +
    +

    Production:

    + + {numeralWrapper.formatBigNumber(node.totalHashesGenerated)} ({numeralWrapper.formatBigNumber(node.hashRate)} / sec) + +
    +
    +

    Hash Capacity:

    + {node.hashCapacity} +
    +
    +

    Level:

    {node.level} + +
    +
    +

    RAM:

    {node.maxRam}GB + +
    +
    +

    Cores:

    {node.cores} + +
    +
    +

    Cache Level:

    {node.cache} + +
    +
    +
  • + ) + } +} diff --git a/src/Hacknet/ui/HashUpgradePopup.jsx b/src/Hacknet/ui/HashUpgradePopup.jsx new file mode 100644 index 000000000..720f73a51 --- /dev/null +++ b/src/Hacknet/ui/HashUpgradePopup.jsx @@ -0,0 +1,137 @@ +/** + * Create the pop-up for purchasing upgrades with hashes + */ +import React from "react"; + +import { purchaseHashUpgrade } from "../HacknetHelpers"; +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 { ServerDropdown, + ServerType } from "../../ui/React/ServerDropdown" + +import { dialogBoxCreate } from "../../../utils/DialogBox"; + +class HashUpgrade extends React.Component { + constructor(props) { + super(props); + + this.state = { + selectedServer: "foodnstuff", + } + + this.changeTargetServer = this.changeTargetServer.bind(this); + this.purchase = this.purchase.bind(this, this.props.hashManager, this.props.upg); + } + + changeTargetServer(e) { + this.setState({ + selectedServer: e.target.value + }); + } + + purchase(hashManager, upg) { + const canPurchase = hashManager.hashes >= hashManager.getUpgradeCost(upg.name); + if (canPurchase) { + const res = purchaseHashUpgrade(upg.name, this.state.selectedServer); + if (res) { + this.props.rerender(); + } else { + dialogBoxCreate("Failed to purchase upgrade. This may be because you do not have enough hashes, " + + "or because you do not have access to the feature this upgrade affects."); + } + } + } + + render() { + const hashManager = this.props.hashManager; + const upg = this.props.upg; + const cost = hashManager.getUpgradeCost(upg.name); + + // Purchase button + const canPurchase = hashManager.hashes >= cost; + const btnClass = canPurchase ? "std-button" : "std-button-disabled"; + + // We'll reuse a Bladeburner css class + return ( +
    +

    {upg.name}

    +

    Cost: {numeralWrapper.format(cost, "0.000a")}

    +

    {upg.desc}

    + + { + upg.hasTargetServer && + + } +
    + ) + } +} + +export class HashUpgradePopup extends React.Component { + constructor(props) { + super(props); + + this.closePopup = this.closePopup.bind(this); + + this.state = { + totalHashes: Player.hashManager.hashes, + } + } + + componentDidMount() { + this.interval = setInterval(() => this.tick(), 1e3); + } + + componentWillUnmount() { + clearInterval(this.interval); + } + + closePopup() { + removePopup(this.props.popupId); + } + + tick() { + this.setState({ + totalHashes: Player.hashManager.hashes, + }) + } + + render() { + const rerender = this.props.rerender; + + const hashManager = Player.hashManager; + if (!(hashManager instanceof HashManager)) { + throw new Error(`Player does not have a HashManager)`); + } + + const upgradeElems = Object.keys(HashUpgrades).map((upgName) => { + const upg = HashUpgrades[upgName]; + return + }); + + return ( +
    + +

    Spend your hashes on a variety of different upgrades

    +

    Hashes: {numeralWrapper.formatBigNumber(this.state.totalHashes)}

    + {upgradeElems} +
    + ) + } +} diff --git a/src/Hacknet/ui/MultiplierButtons.jsx b/src/Hacknet/ui/MultiplierButtons.jsx new file mode 100644 index 000000000..3fe12477c --- /dev/null +++ b/src/Hacknet/ui/MultiplierButtons.jsx @@ -0,0 +1,41 @@ +/** + * React Component for the Multiplier buttons on the Hacknet page. + * These buttons let the player control how many Nodes/Upgrades they're + * purchasing when using the UI (x1, x5, x10, MAX) + */ +import React from "react"; + +import { PurchaseMultipliers } from "./Root"; + +function MultiplierButton(props) { + return ( + + ) +} + +export function MultiplierButtons(props) { + if (props.purchaseMultiplier == null) { + throw new Error(`MultiplierButtons constructed without required props`); + } + + const mults = ["x1", "x5", "x10", "MAX"]; + const onClicks = props.onClicks; + const buttons = []; + for (let i = 0; i < mults.length; ++i) { + const mult = mults[i]; + const btnProps = { + className: props.purchaseMultiplier === PurchaseMultipliers[mult] ? "std-button-disabled" : "std-button", + key: mult, + onClick: onClicks[i], + text: mult, + } + + buttons.push() + } + + return ( + + {buttons} + + ) +} diff --git a/src/Hacknet/ui/PlayerInfo.jsx b/src/Hacknet/ui/PlayerInfo.jsx new file mode 100644 index 000000000..03a6e31fb --- /dev/null +++ b/src/Hacknet/ui/PlayerInfo.jsx @@ -0,0 +1,51 @@ +/** + * React Component for displaying Player info and stats on the Hacknet Node UI. + * This includes: + * - Player's money + * - Player's production from Hacknet Nodes + */ +import React from "react"; + +import { hasHacknetServers } from "../HacknetHelpers"; +import { Player } from "../../Player"; +import { numeralWrapper } from "../../ui/numeralFormat"; + +export function PlayerInfo(props) { + const hasServers = hasHacknetServers(); + + let prod; + if (hasServers) { + prod = numeralWrapper.format(props.totalProduction, "0.000a") + " hashes / sec"; + } else { + prod = numeralWrapper.formatMoney(props.totalProduction) + " / sec"; + } + + let hashInfo; + if (hasServers) { + hashInfo = numeralWrapper.format(Player.hashManager.hashes, "0.000a") + " / " + + numeralWrapper.format(Player.hashManager.capacity, "0.000a"); + } + + return ( +

    + Money: + {numeralWrapper.formatMoney(Player.money.toNumber())}
    + + { + hasServers && + Hashes: + } + { + hasServers && + {hashInfo} + } + { + hasServers && +
    + } + + Total Hacknet Node Production: + {prod} +

    + ) +} diff --git a/src/Hacknet/ui/PurchaseButton.jsx b/src/Hacknet/ui/PurchaseButton.jsx new file mode 100644 index 000000000..eac9b233d --- /dev/null +++ b/src/Hacknet/ui/PurchaseButton.jsx @@ -0,0 +1,40 @@ +/** + * React Component for the button that is used to purchase new Hacknet Nodes + */ +import React from "react"; + +import { hasHacknetServers, + hasMaxNumberHacknetServers } from "../HacknetHelpers"; +import { Player } from "../../Player"; +import { numeralWrapper } from "../../ui/numeralFormat"; + +export function PurchaseButton(props) { + if (props.multiplier == null || props.onClick == null) { + throw new Error(`PurchaseButton constructed without required props`); + } + + const cost = props.cost; + let className = Player.canAfford(cost) ? "std-button" : "std-button-disabled"; + let text; + let style = null; + if (hasHacknetServers()) { + if (hasMaxNumberHacknetServers()) { + className = "std-button-disabled"; + text = "Hacknet Server limit reached"; + style = {color: "red"}; + } else { + text = `Purchase Hacknet Server - ${numeralWrapper.formatMoney(cost)}`; + } + } else { + text = `Purchase Hacknet Node - ${numeralWrapper.formatMoney(cost)}`; + } + + return ( + + + ) +} diff --git a/src/Hacknet/ui/Root.jsx b/src/Hacknet/ui/Root.jsx new file mode 100644 index 000000000..3e1a95633 --- /dev/null +++ b/src/Hacknet/ui/Root.jsx @@ -0,0 +1,144 @@ +/** + * Root React Component for the Hacknet Node UI + */ +import React from "react"; + +import { GeneralInfo } from "./GeneralInfo"; +import { HacknetNode } from "./HacknetNode"; +import { HacknetServer } from "./HacknetServer"; +import { HashUpgradePopup } from "./HashUpgradePopup"; +import { MultiplierButtons } from "./MultiplierButtons"; +import { PlayerInfo } from "./PlayerInfo"; +import { PurchaseButton } from "./PurchaseButton"; + +import { getCostOfNextHacknetNode, + getCostOfNextHacknetServer, + hasHacknetServers, + purchaseHacknet } from "../HacknetHelpers"; + +import { Player } from "../../Player"; + +import { createPopup } from "../../ui/React/createPopup"; + +export const PurchaseMultipliers = Object.freeze({ + "x1": 1, + "x5": 5, + "x10": 10, + "MAX": "MAX", +}); + +export class HacknetRoot extends React.Component { + constructor(props) { + super(props); + + this.state = { + purchaseMultiplier: PurchaseMultipliers.x1, + totalProduction: 0, // Total production ($ / s) of Hacknet Nodes + } + + this.createHashUpgradesPopup = this.createHashUpgradesPopup.bind(this); + } + + componentDidMount() { + this.recalculateTotalProduction(); + } + + createHashUpgradesPopup() { + const id = "hacknet-server-hash-upgrades-popup"; + createPopup(id, HashUpgradePopup, { popupId: id, rerender: this.createHashUpgradesPopup }); + } + + recalculateTotalProduction() { + let total = 0; + for (let i = 0; i < Player.hacknetNodes.length; ++i) { + if (hasHacknetServers()) { + total += Player.hacknetNodes[i].hashRate; + } else { + total += Player.hacknetNodes[i].moneyGainRatePerSecond; + } + } + + this.setState({ + totalProduction: total, + }); + } + + setPurchaseMultiplier(mult) { + this.setState({ + purchaseMultiplier: mult, + }); + } + + render() { + // Cost to purchase a new Hacknet Node + let purchaseCost; + if (hasHacknetServers()) { + purchaseCost = getCostOfNextHacknetServer(); + } else { + purchaseCost = getCostOfNextHacknetNode(); + } + + // onClick event handler for purchase button + const purchaseOnClick = () => { + if (purchaseHacknet() >= 0) { + this.recalculateTotalProduction(); + Player.hashManager.updateCapacity(Player); + } + } + + // onClick event handlers for purchase multiplier buttons + const purchaseMultiplierOnClicks = [ + this.setPurchaseMultiplier.bind(this, PurchaseMultipliers.x1), + this.setPurchaseMultiplier.bind(this, PurchaseMultipliers.x5), + this.setPurchaseMultiplier.bind(this, PurchaseMultipliers.x10), + this.setPurchaseMultiplier.bind(this, PurchaseMultipliers.MAX), + ]; + + // HacknetNode components + const nodes = Player.hacknetNodes.map((node) => { + if (hasHacknetServers()) { + return ( + + ) + } else { + return ( + + ) + } + }); + + return ( +
    +

    Hacknet Nodes

    + + + + +
    +
    + + +
    + + { + hasHacknetServers() && + + } + +
      {nodes}
    +
    + ) + } +} diff --git a/src/HacknetNode.js b/src/HacknetNode.js deleted file mode 100644 index 9421b9346..000000000 --- a/src/HacknetNode.js +++ /dev/null @@ -1,694 +0,0 @@ -import { BitNodeMultipliers } from "./BitNode/BitNodeMultipliers"; -import { CONSTANTS } from "./Constants"; -import { Engine } from "./engine"; -import {iTutorialSteps, iTutorialNextStep, - ITutorial} from "./InteractiveTutorial"; -import {Player} from "./Player"; -import {Page, routing} from "./ui/navigationTracking"; -import { numeralWrapper } from "./ui/numeralFormat"; - -import {dialogBoxCreate} from "../utils/DialogBox"; -import {clearEventListeners} from "../utils/uiHelpers/clearEventListeners"; -import {Reviver, Generic_toJSON, - Generic_fromJSON} from "../utils/JSONReviver"; -import {createElement} from "../utils/uiHelpers/createElement"; -import {getElementById} from "../utils/uiHelpers/getElementById"; - -// Stores total money gain rate from all of the player's Hacknet Nodes -let TotalHacknetNodeProduction = 0; - -/** - * Overwrites the inner text of the specified HTML element if it is different from what currently exists. - * @param {string} elementId The HTML ID to find the first instance of. - * @param {string} text The inner text that should be set. - */ -function updateText(elementId, text) { - var el = getElementById(elementId); - if (el.innerText != text) { - el.innerText = text; - } -}; - -/* HacknetNode.js */ -function hacknetNodesInit() { - var performMapping = function(x) { - getElementById("hacknet-nodes-" + x.id + "-multiplier") - .addEventListener("click", function() { - hacknetNodePurchaseMultiplier = x.multiplier; - updateHacknetNodesMultiplierButtons(); - updateHacknetNodesContent(); - return false; - }); - }; - - var mappings = [ - { id: "1x", multiplier: 1 }, - { id: "5x", multiplier: 5 }, - { id: "10x", multiplier: 10 }, - { id: "max", multiplier: 0 } - ]; - for (var elem of mappings) { - // Encapsulate in a function so that the appropriate scope is kept in the click handler. - performMapping(elem); - } -} - -document.addEventListener("DOMContentLoaded", hacknetNodesInit, false); - -function HacknetNode(name) { - this.level = 1; - this.ram = 1; //GB - this.cores = 1; - - this.name = name; - - this.totalMoneyGenerated = 0; - this.onlineTimeSeconds = 0; - - this.moneyGainRatePerSecond = 0; -} - -HacknetNode.prototype.updateMoneyGainRate = function() { - //How much extra $/s is gained per level - var gainPerLevel = CONSTANTS.HacknetNodeMoneyGainPerLevel; - - this.moneyGainRatePerSecond = (this.level * gainPerLevel) * - Math.pow(1.035, this.ram-1) * - ((this.cores + 5) / 6) * - Player.hacknet_node_money_mult * - BitNodeMultipliers.HacknetNodeMoney; - if (isNaN(this.moneyGainRatePerSecond)) { - this.moneyGainRatePerSecond = 0; - dialogBoxCreate("Error in calculating Hacknet Node production. Please report to game developer"); - } - - updateTotalHacknetProduction(); -} - -HacknetNode.prototype.calculateLevelUpgradeCost = function(levels=1) { - levels = Math.round(levels); - if (isNaN(levels) || levels < 1) { - return 0; - } - - if (this.level >= CONSTANTS.HacknetNodeMaxLevel) { - return Infinity; - } - - var mult = CONSTANTS.HacknetNodeUpgradeLevelMult; - var totalMultiplier = 0; //Summed - var currLevel = this.level; - for (var i = 0; i < levels; ++i) { - totalMultiplier += Math.pow(mult, currLevel); - ++currLevel; - } - - return CONSTANTS.BaseCostForHacknetNode / 2 * totalMultiplier * Player.hacknet_node_level_cost_mult; -} - -HacknetNode.prototype.purchaseLevelUpgrade = function(levels=1) { - levels = Math.round(levels); - var cost = this.calculateLevelUpgradeCost(levels); - if (isNaN(cost) || levels < 0) { - return false; - } - - //If we're at max level, return false - if (this.level >= CONSTANTS.HacknetNodeMaxLevel) { - return false; - } - - //If the number of specified upgrades would exceed the max level, calculate - //the maximum number of upgrades and use that - if (this.level + levels > CONSTANTS.HacknetNodeMaxLevel) { - var diff = Math.max(0, CONSTANTS.HacknetNodeMaxLevel - this.level); - return this.purchaseLevelUpgrade(diff); - } - - if (Player.money.lt(cost)) { - return false; - } - - Player.loseMoney(cost); - this.level = Math.round(this.level + levels); //Just in case of floating point imprecision - this.updateMoneyGainRate(); - return true; -} - -HacknetNode.prototype.calculateRamUpgradeCost = function(levels=1) { - levels = Math.round(levels); - if (isNaN(levels) || levels < 1) { - return 0; - } - - if (this.ram >= CONSTANTS.HacknetNodeMaxRam) { - return Infinity; - } - - let totalCost = 0; - let numUpgrades = Math.round(Math.log2(this.ram)); - let currentRam = this.ram; - - for (let i = 0; i < levels; ++i) { - let baseCost = currentRam * CONSTANTS.BaseCostFor1GBOfRamHacknetNode; - let mult = Math.pow(CONSTANTS.HacknetNodeUpgradeRamMult, numUpgrades); - - totalCost += (baseCost * mult); - - currentRam *= 2; - ++numUpgrades; - } - - totalCost *= Player.hacknet_node_ram_cost_mult - return totalCost; -} - -HacknetNode.prototype.purchaseRamUpgrade = function(levels=1) { - levels = Math.round(levels); - var cost = this.calculateRamUpgradeCost(levels); - if (isNaN(cost) || levels < 0) { - return false; - } - - // Fail if we're already at max - if (this.ram >= CONSTANTS.HacknetNodeMaxRam) { - return false; - } - - //If the number of specified upgrades would exceed the max RAM, calculate the - //max possible number of upgrades and use that - if (this.ram * Math.pow(2, levels) > CONSTANTS.HacknetNodeMaxRam) { - var diff = Math.max(0, Math.log2(Math.round(CONSTANTS.HacknetNodeMaxRam / this.ram))); - return this.purchaseRamUpgrade(diff); - } - - if (Player.money.lt(cost)) { - return false; - } - - Player.loseMoney(cost); - for (let i = 0; i < levels; ++i) { - this.ram *= 2; //Ram is always doubled - } - this.ram = Math.round(this.ram); //Handle any floating point precision issues - this.updateMoneyGainRate(); - return true; -} - -HacknetNode.prototype.calculateCoreUpgradeCost = function(levels=1) { - levels = Math.round(levels); - if (isNaN(levels) || levels < 1) { - return 0; - } - - if (this.cores >= CONSTANTS.HacknetNodeMaxCores) { - return Infinity; - } - - const coreBaseCost = CONSTANTS.BaseCostForHacknetNodeCore; - const mult = CONSTANTS.HacknetNodeUpgradeCoreMult; - let totalCost = 0; - let currentCores = this.cores; - for (let i = 0; i < levels; ++i) { - totalCost += (coreBaseCost * Math.pow(mult, currentCores-1)); - ++currentCores; - } - - totalCost *= Player.hacknet_node_core_cost_mult; - - return totalCost; -} - -HacknetNode.prototype.purchaseCoreUpgrade = function(levels=1) { - levels = Math.round(levels); - var cost = this.calculateCoreUpgradeCost(levels); - if (isNaN(cost) || levels < 0) { - return false; - } - - //Fail if we're already at max - if (this.cores >= CONSTANTS.HacknetNodeMaxCores) { - return false; - } - - //If the specified number of upgrades would exceed the max Cores, calculate - //the max possible number of upgrades and use that - if (this.cores + levels > CONSTANTS.HacknetNodeMaxCores) { - var diff = Math.max(0, CONSTANTS.HacknetNodeMaxCores - this.cores); - return this.purchaseCoreUpgrade(diff); - } - - if (Player.money.lt(cost)) { - return false; - } - - Player.loseMoney(cost); - this.cores = Math.round(this.cores + levels); //Just in case of floating point imprecision - this.updateMoneyGainRate(); - return true; -} - -/* Saving and loading HackNets */ -HacknetNode.prototype.toJSON = function() { - return Generic_toJSON("HacknetNode", this); -} - -HacknetNode.fromJSON = function(value) { - return Generic_fromJSON(HacknetNode, value.data); -} - -Reviver.constructors.HacknetNode = HacknetNode; - -function purchaseHacknet() { - /* INTERACTIVE TUTORIAL */ - if (ITutorial.isRunning) { - if (ITutorial.currStep === iTutorialSteps.HacknetNodesIntroduction) { - iTutorialNextStep(); - } else { - return; - } - } - - /* END INTERACTIVE TUTORIAL */ - - var cost = getCostOfNextHacknetNode(); - if (isNaN(cost)) { - throw new Error("Cost is NaN"); - } - - if (Player.money.lt(cost)) { - //dialogBoxCreate("You cannot afford to purchase a Hacknet Node!"); - return -1; - } - - //Auto generate a name for the node for now...TODO - var numOwned = Player.hacknetNodes.length; - var name = "hacknet-node-" + numOwned; - var node = new HacknetNode(name); - node.updateMoneyGainRate(); - - Player.loseMoney(cost); - Player.hacknetNodes.push(node); - - if (routing.isOn(Page.HacknetNodes)) { - displayHacknetNodesContent(); - } - updateTotalHacknetProduction(); - return numOwned; -} - -//Calculates the total production from all HacknetNodes -function updateTotalHacknetProduction() { - var total = 0; - for (var i = 0; i < Player.hacknetNodes.length; ++i) { - total += Player.hacknetNodes[i].moneyGainRatePerSecond; - } - TotalHacknetNodeProduction = total; -} - -function getCostOfNextHacknetNode() { - //Cost increases exponentially based on how many you own - var numOwned = Player.hacknetNodes.length; - var mult = CONSTANTS.HacknetNodePurchaseNextMult; - return CONSTANTS.BaseCostForHacknetNode * Math.pow(mult, numOwned) * Player.hacknet_node_purchase_cost_mult; -} - -var hacknetNodePurchaseMultiplier = 1; -function updateHacknetNodesMultiplierButtons() { - var mult1x = document.getElementById("hacknet-nodes-1x-multiplier"); - var mult5x = document.getElementById("hacknet-nodes-5x-multiplier"); - var mult10x = document.getElementById("hacknet-nodes-10x-multiplier"); - var multMax = document.getElementById("hacknet-nodes-max-multiplier"); - mult1x.setAttribute("class", "a-link-button"); - mult5x.setAttribute("class", "a-link-button"); - mult10x.setAttribute("class", "a-link-button"); - multMax.setAttribute("class", "a-link-button"); - if (Player.hacknetNodes.length == 0) { - mult1x.setAttribute("class", "a-link-button-inactive"); - mult5x.setAttribute("class", "a-link-button-inactive"); - mult10x.setAttribute("class", "a-link-button-inactive"); - multMax.setAttribute("class", "a-link-button-inactive"); - } else if (hacknetNodePurchaseMultiplier == 1) { - mult1x.setAttribute("class", "a-link-button-inactive"); - } else if (hacknetNodePurchaseMultiplier == 5) { - mult5x.setAttribute("class", "a-link-button-inactive"); - } else if (hacknetNodePurchaseMultiplier == 10) { - mult10x.setAttribute("class", "a-link-button-inactive"); - } else { - multMax.setAttribute("class", "a-link-button-inactive"); - } -} - -//Calculate the maximum number of times the Player can afford to upgrade a Hacknet Node -function getMaxNumberLevelUpgrades(nodeObj) { - if (Player.money.lt(nodeObj.calculateLevelUpgradeCost(1))) { - return 0; - } - - var min = 1; - var max = CONSTANTS.HacknetNodeMaxLevel - 1; - var levelsToMax = CONSTANTS.HacknetNodeMaxLevel - nodeObj.level; - if (Player.money.gt(nodeObj.calculateLevelUpgradeCost(levelsToMax))) { - return levelsToMax; - } - - while (min <= max) { - var curr = (min + max) / 2 | 0; - if (curr != CONSTANTS.HacknetNodeMaxLevel && - Player.money.gt(nodeObj.calculateLevelUpgradeCost(curr)) && - Player.money.lt(nodeObj.calculateLevelUpgradeCost(curr + 1))) { - return Math.min(levelsToMax, curr); - } else if (Player.money.lt(nodeObj.calculateLevelUpgradeCost(curr))) { - max = curr - 1; - } else if (Player.money.gt(nodeObj.calculateLevelUpgradeCost(curr))) { - min = curr + 1; - } else { - return Math.min(levelsToMax, curr); - } - } - return 0; -} - -function getMaxNumberRamUpgrades(nodeObj) { - if (Player.money.lt(nodeObj.calculateRamUpgradeCost(1))) { - return 0; - } - - const levelsToMax = Math.round(Math.log2(CONSTANTS.HacknetNodeMaxRam / nodeObj.ram)); - if (Player.money.gt(nodeObj.calculateRamUpgradeCost(levelsToMax))) { - return levelsToMax; - } - - //We'll just loop until we find the max - for (let i = levelsToMax-1; i >= 0; --i) { - if (Player.money.gt(nodeObj.calculateRamUpgradeCost(i))) { - return i; - } - } - return 0; -} - -function getMaxNumberCoreUpgrades(nodeObj) { - if (Player.money.lt(nodeObj.calculateCoreUpgradeCost(1))) { - return 0; - } - - var min = 1; - var max = CONSTANTS.HacknetNodeMaxCores - 1; - const levelsToMax = CONSTANTS.HacknetNodeMaxCores - nodeObj.cores; - if (Player.money.gt(nodeObj.calculateCoreUpgradeCost(levelsToMax))) { - return levelsToMax; - } - - //Use a binary search to find the max possible number of upgrades - while (min <= max) { - let curr = (min + max) / 2 | 0; - if (curr != CONSTANTS.HacknetNodeMaxCores && - Player.money.gt(nodeObj.calculateCoreUpgradeCost(curr)) && - Player.money.lt(nodeObj.calculateCoreUpgradeCost(curr + 1))) { - return Math.min(levelsToMax, curr); - } else if (Player.money.lt(nodeObj.calculateCoreUpgradeCost(curr))) { - max = curr - 1; - } else if (Player.money.gt(nodeObj.calculateCoreUpgradeCost(curr))) { - min = curr + 1; - } else { - return Math.min(levelsToMax, curr); - } - } - return 0; -} - -//Creates Hacknet Node DOM elements when the page is opened -function displayHacknetNodesContent() { - //Update Hacknet Nodes button - var newPurchaseButton = clearEventListeners("hacknet-nodes-purchase-button"); - - newPurchaseButton.addEventListener("click", function() { - purchaseHacknet(); - return false; - }); - - //Handle Purchase multiplier buttons - updateHacknetNodesMultiplierButtons(); - - //Remove all old hacknet Node DOM elements - var hacknetNodesList = document.getElementById("hacknet-nodes-list"); - while (hacknetNodesList.firstChild) { - hacknetNodesList.removeChild(hacknetNodesList.firstChild); - } - - //Then re-create them - for (var i = 0; i < Player.hacknetNodes.length; ++i) { - createHacknetNodeDomElement(Player.hacknetNodes[i]); - } - - updateTotalHacknetProduction(); - updateHacknetNodesContent(); -} - -//Update information on all Hacknet Node DOM elements -function updateHacknetNodesContent() { - //Set purchase button to inactive if not enough money, and update its price display - var cost = getCostOfNextHacknetNode(); - var purchaseButton = getElementById("hacknet-nodes-purchase-button"); - var formattedCost = numeralWrapper.formatMoney(cost); - - updateText("hacknet-nodes-purchase-button", `Purchase Hacknet Node - ${formattedCost}`); - - if (Player.money.lt(cost)) { - purchaseButton.setAttribute("class", "a-link-button-inactive"); - } else { - purchaseButton.setAttribute("class", "a-link-button"); - } - - //Update player's money - updateText("hacknet-nodes-player-money", numeralWrapper.formatMoney(Player.money.toNumber())); - updateText("hacknet-nodes-total-production", numeralWrapper.formatMoney(TotalHacknetNodeProduction) + " / sec"); - - //Update information in each owned hacknet node - for (var i = 0; i < Player.hacknetNodes.length; ++i) { - updateHacknetNodeDomElement(Player.hacknetNodes[i]); - } -} - -//Creates a single Hacknet Node DOM element -function createHacknetNodeDomElement(nodeObj) { - var nodeName = nodeObj.name; - - var nodeLevelContainer = createElement("div", { - class: "hacknet-node-level-container row", - innerHTML: "

    Level:

    " - }); - - var nodeRamContainer = createElement("div", { - class: "hacknet-node-ram-container row", - innerHTML: "

    RAM:

    " - }); - - var nodeCoresContainer = createElement("div", { - class: "hacknet-node-cores-container row", - innerHTML: "

    Cores:

    " - }) - var containingDiv = createElement("div", { - class: "hacknet-node-container", - innerHTML: "
    " + - "

    Node name:

    " + - "" + - "
    " + - "
    " + - "

    Production:

    " + - "" + - "" + - "
    " - }); - containingDiv.appendChild(nodeLevelContainer); - containingDiv.appendChild(nodeRamContainer); - containingDiv.appendChild(nodeCoresContainer); - - var listItem = createElement("li", { - class: "hacknet-node" - }); - listItem.appendChild(containingDiv); - - //Upgrade buttons - nodeLevelContainer.appendChild(createElement("a", { - id: "hacknet-node-upgrade-level-" + nodeName, - class: "a-link-button-inactive", - clickListener: function() { - let numUpgrades = hacknetNodePurchaseMultiplier; - if (hacknetNodePurchaseMultiplier == 0) { - numUpgrades = getMaxNumberLevelUpgrades(nodeObj); - } - nodeObj.purchaseLevelUpgrade(numUpgrades); - updateHacknetNodesContent(); - return false; - } - })); - - nodeRamContainer.appendChild(createElement("a", { - id: "hacknet-node-upgrade-ram-" + nodeName, - class: "a-link-button-inactive", - clickListener: function() { - let numUpgrades = hacknetNodePurchaseMultiplier; - if (hacknetNodePurchaseMultiplier == 0) { - numUpgrades = getMaxNumberRamUpgrades(nodeObj); - } - nodeObj.purchaseRamUpgrade(numUpgrades); - updateHacknetNodesContent(); - return false; - } - })); - - nodeCoresContainer.appendChild(createElement("a", { - id: "hacknet-node-upgrade-core-" + nodeName, - class: "a-link-button-inactive", - clickListener: function() { - let numUpgrades = hacknetNodePurchaseMultiplier; - if (hacknetNodePurchaseMultiplier == 0) { - numUpgrades = getMaxNumberCoreUpgrades(nodeObj); - } - nodeObj.purchaseCoreUpgrade(numUpgrades); - updateHacknetNodesContent(); - return false; - } - })); - - document.getElementById("hacknet-nodes-list").appendChild(listItem); - - //Set the text and stuff inside the DOM element - updateHacknetNodeDomElement(nodeObj); -} - -//Updates information on a single hacknet node DOM element -function updateHacknetNodeDomElement(nodeObj) { - var nodeName = nodeObj.name; - - updateText("hacknet-node-name-" + nodeName, nodeName); - updateText("hacknet-node-total-production-" + nodeName, numeralWrapper.formatMoney(nodeObj.totalMoneyGenerated)); - updateText("hacknet-node-production-rate-" + nodeName, "(" + numeralWrapper.formatMoney(nodeObj.moneyGainRatePerSecond) + " / sec)"); - updateText("hacknet-node-level-" + nodeName, nodeObj.level); - updateText("hacknet-node-ram-" + nodeName, nodeObj.ram + "GB"); - updateText("hacknet-node-cores-" + nodeName, nodeObj.cores); - - //Upgrade level - var upgradeLevelButton = getElementById("hacknet-node-upgrade-level-" + nodeName); - - if (nodeObj.level >= CONSTANTS.HacknetNodeMaxLevel) { - updateText("hacknet-node-upgrade-level-" + nodeName, "MAX LEVEL"); - upgradeLevelButton.setAttribute("class", "a-link-button-inactive"); - } else { - let multiplier = 0; - if (hacknetNodePurchaseMultiplier == 0) { - //Max - multiplier = getMaxNumberLevelUpgrades(nodeObj); - } else { - var levelsToMax = CONSTANTS.HacknetNodeMaxLevel - nodeObj.level; - multiplier = Math.min(levelsToMax, hacknetNodePurchaseMultiplier); - } - - var upgradeLevelCost = nodeObj.calculateLevelUpgradeCost(multiplier); - updateText("hacknet-node-upgrade-level-" + nodeName, "Upgrade x" + multiplier + " - " + numeralWrapper.formatMoney(upgradeLevelCost)) - if (Player.money.lt(upgradeLevelCost)) { - upgradeLevelButton.setAttribute("class", "a-link-button-inactive"); - } else { - upgradeLevelButton.setAttribute("class", "a-link-button"); - } - } - - //Upgrade RAM - var upgradeRamButton = getElementById("hacknet-node-upgrade-ram-" + nodeName); - - if (nodeObj.ram >= CONSTANTS.HacknetNodeMaxRam) { - updateText("hacknet-node-upgrade-ram-" + nodeName, "MAX RAM"); - upgradeRamButton.setAttribute("class", "a-link-button-inactive"); - } else { - let multiplier = 0; - if (hacknetNodePurchaseMultiplier == 0) { - multiplier = getMaxNumberRamUpgrades(nodeObj); - } else { - var levelsToMax = Math.round(Math.log2(CONSTANTS.HacknetNodeMaxRam / nodeObj.ram)); - multiplier = Math.min(levelsToMax, hacknetNodePurchaseMultiplier); - } - - var upgradeRamCost = nodeObj.calculateRamUpgradeCost(multiplier); - updateText("hacknet-node-upgrade-ram-" + nodeName, "Upgrade x" + multiplier + " - " + numeralWrapper.formatMoney(upgradeRamCost)); - if (Player.money.lt(upgradeRamCost)) { - upgradeRamButton.setAttribute("class", "a-link-button-inactive"); - } else { - upgradeRamButton.setAttribute("class", "a-link-button"); - } - } - - //Upgrade Cores - var upgradeCoreButton = getElementById("hacknet-node-upgrade-core-" + nodeName); - - if (nodeObj.cores >= CONSTANTS.HacknetNodeMaxCores) { - updateText("hacknet-node-upgrade-core-" + nodeName, "MAX CORES"); - upgradeCoreButton.setAttribute("class", "a-link-button-inactive"); - } else { - let multiplier = 0; - if (hacknetNodePurchaseMultiplier == 0) { - multiplier = getMaxNumberCoreUpgrades(nodeObj); - } else { - var levelsToMax = CONSTANTS.HacknetNodeMaxCores - nodeObj.cores; - multiplier = Math.min(levelsToMax, hacknetNodePurchaseMultiplier); - } - var upgradeCoreCost = nodeObj.calculateCoreUpgradeCost(multiplier); - updateText("hacknet-node-upgrade-core-" + nodeName, "Upgrade x" + multiplier + " - " + numeralWrapper.formatMoney(upgradeCoreCost)); - if (Player.money.lt(upgradeCoreCost)) { - upgradeCoreButton.setAttribute("class", "a-link-button-inactive"); - } else { - upgradeCoreButton.setAttribute("class", "a-link-button"); - } - } -} - - -function processAllHacknetNodeEarnings(numCycles) { - var total = 0; - for (var i = 0; i < Player.hacknetNodes.length; ++i) { - total += processSingleHacknetNodeEarnings(numCycles, Player.hacknetNodes[i]); - } - - return total; -} - -function processSingleHacknetNodeEarnings(numCycles, nodeObj) { - var cyclesPerSecond = 1000 / Engine._idleSpeed; - var earningPerCycle = nodeObj.moneyGainRatePerSecond / cyclesPerSecond; - if (isNaN(earningPerCycle)) { - console.error("Hacknet Node '" + nodeObj.name + "' Calculated earnings is NaN"); - earningPerCycle = 0; - } - - var totalEarnings = numCycles * earningPerCycle; - nodeObj.totalMoneyGenerated += totalEarnings; - nodeObj.onlineTimeSeconds += (numCycles * (Engine._idleSpeed / 1000)); - Player.gainMoney(totalEarnings); - Player.recordMoneySource(totalEarnings, "hacknetnode"); - return totalEarnings; -} - -function getHacknetNode(name) { - for (var i = 0; i < Player.hacknetNodes.length; ++i) { - if (Player.hacknetNodes[i].name == name) { - return Player.hacknetNodes[i]; - } - } - - return null; -} - -export { - HacknetNode, - displayHacknetNodesContent, - getCostOfNextHacknetNode, - getHacknetNode, - getMaxNumberLevelUpgrades, - hacknetNodesInit, - processAllHacknetNodeEarnings, - purchaseHacknet, - updateHacknetNodesContent, - updateHacknetNodesMultiplierButtons, - updateTotalHacknetProduction -}; diff --git a/src/NetscriptEnvironment.js b/src/NetscriptEnvironment.js index dcdacbb77..480e4b45f 100644 --- a/src/NetscriptEnvironment.js +++ b/src/NetscriptEnvironment.js @@ -1,4 +1,3 @@ -import {HacknetNode} from "./HacknetNode"; import {NetscriptFunctions} from "./NetscriptFunctions"; import {NetscriptPort} from "./NetscriptPort"; @@ -56,37 +55,6 @@ Environment.prototype = { } }, - setArrayElement: function(name, idx, value) { - if (!(idx instanceof Array)) { - throw new Error("idx parameter is not an Array"); - } - var scope = this.lookup(name); - if (!scope && this.parent) { - throw new Error("Undefined variable " + name); - } - var arr = (scope || this).vars[name]; - if (!(arr.constructor === Array || arr instanceof Array)) { - throw new Error("Variable is not an array: " + name); - } - var res = arr; - for (var iterator = 0; iterator < idx.length-1; ++iterator) { - var i = idx[iterator]; - if (!(res instanceof Array) || i >= res.length) { - throw new Error("Out-of-bounds array access"); - } - res = res[i]; - } - - //Cant assign to ports or HacknetNodes - if (res[idx[idx.length-1]] instanceof HacknetNode) { - throw new Error("Cannot assign a Hacknet Node handle to a new value"); - } - if (res[idx[idx.length-1]] instanceof NetscriptPort) { - throw new Error("Cannot assign a Netscript Port handle to a new value"); - } - return res[idx[idx.length-1]] = value; - }, - //Creates (or overwrites) a variable in the current scope def: function(name, value) { return this.vars[name] = value; diff --git a/src/NetscriptEvaluator.js b/src/NetscriptEvaluator.js index c301f2b76..97e030ab4 100644 --- a/src/NetscriptEvaluator.js +++ b/src/NetscriptEvaluator.js @@ -196,7 +196,7 @@ export function runScriptFromScript(server, scriptname, args, workerScript, thre } var runningScriptObj = new RunningScript(script, args); runningScriptObj.threads = threads; - server.runningScripts.push(runningScriptObj); //Push onto runningScripts + server.runScript(runningScriptObj, Player); // Push onto runningScripts addWorkerScript(runningScriptObj, server); return Promise.resolve(true); } diff --git a/src/NetscriptFunctions.js b/src/NetscriptFunctions.js index 669bce884..c9380c790 100644 --- a/src/NetscriptFunctions.js +++ b/src/NetscriptFunctions.js @@ -30,7 +30,7 @@ import { joinFaction, purchaseAugmentation } from "./Faction/FactionHelpers"; import { FactionWorkType } from "./Faction/FactionWorkTypeEnum"; import { getCostOfNextHacknetNode, - purchaseHacknet } from "./HacknetNode"; + purchaseHacknet } from "./Hacknet/HacknetNode"; import {Locations} from "./Locations"; import { Message } from "./Message/Message"; import { Messages } from "./Message/MessageHelpers"; @@ -278,27 +278,27 @@ function NetscriptFunctions(workerScript) { }, upgradeLevel : function(i, n) { var node = getHacknetNode(i); - return node.purchaseLevelUpgrade(n); + return node.purchaseLevelUpgrade(n, Player); }, upgradeRam : function(i, n) { var node = getHacknetNode(i); - return node.purchaseRamUpgrade(n); + return node.purchaseRamUpgrade(n, Player); }, upgradeCore : function(i, n) { var node = getHacknetNode(i); - return node.purchaseCoreUpgrade(n); + return node.purchaseCoreUpgrade(n, Player); }, getLevelUpgradeCost : function(i, n) { var node = getHacknetNode(i); - return node.calculateLevelUpgradeCost(n); + return node.calculateLevelUpgradeCost(n, Player); }, getRamUpgradeCost : function(i, n) { var node = getHacknetNode(i); - return node.calculateRamUpgradeCost(n); + return node.calculateRamUpgradeCost(n, Player); }, getCoreUpgradeCost : function(i, n) { var node = getHacknetNode(i); - return node.calculateCoreUpgradeCost(n); + return node.calculateCoreUpgradeCost(n, Player); } }, sprintf : sprintf, diff --git a/src/PersonObjects/IPlayer.ts b/src/PersonObjects/IPlayer.ts index c41247a2e..c3406d3c7 100644 --- a/src/PersonObjects/IPlayer.ts +++ b/src/PersonObjects/IPlayer.ts @@ -9,6 +9,8 @@ import { Sleeve } from "./Sleeve/Sleeve"; import { IMap } from "../types"; import { IPlayerOwnedAugmentation } from "../Augmentation/PlayerOwnedAugmentation"; +import { HacknetNode } from "../Hacknet/HacknetNode"; +import { HacknetServer } from "../Hacknet/HacknetServer"; import { IPlayerOwnedSourceFile } from "../SourceFile/PlayerOwnedSourceFile"; import { MoneySourceTracker } from "../utils/MoneySourceTracker"; @@ -22,7 +24,7 @@ export interface IPlayer { corporation: any; currentServer: string; factions: string[]; - hacknetNodes: any[]; + hacknetNodes: (HacknetNode | HacknetServer)[]; hasWseAccount: boolean; jobs: IMap; karma: number; diff --git a/src/Player.js b/src/Player.js index 01903d82c..c7ee6502e 100644 --- a/src/Player.js +++ b/src/Player.js @@ -21,6 +21,7 @@ import { Faction } from "./Faction/Faction"; import { Factions } from "./Faction/Factions"; import { displayFactionContent } from "./Faction/FactionHelpers"; import {Gang, resetGangs} from "./Gang"; +import { HashManager } from "./Hacknet/HashManager"; import {Locations} from "./Locations"; import {hasBn11SF, hasWallStreetSF,hasAISF} from "./NetscriptFunctions"; import { Sleeve } from "./PersonObjects/Sleeve/Sleeve"; @@ -111,10 +112,13 @@ function PlayerObject() { // Company at which player is CURRENTLY working (only valid when the player is actively working) this.companyName = ""; // Name of Company. Must match a key value in Companies map - //Servers + // Servers this.currentServer = ""; //IP address of Server currently being accessed through terminal this.purchasedServers = []; //IP Addresses of purchased servers + + // Hacknet Nodes/Servers this.hacknetNodes = []; + this.hashManager = new HashManager(); //Factions this.factions = []; //Names of all factions player has joined @@ -1391,45 +1395,46 @@ PlayerObject.prototype.startClass = function(costMult, expMult, className) { //Find cost and exp gain per game cycle var cost = 0; var hackExp = 0, strExp = 0, defExp = 0, dexExp = 0, agiExp = 0, chaExp = 0; + const hashManager = this.hashManager; switch (className) { case CONSTANTS.ClassStudyComputerScience: - hackExp = baseStudyComputerScienceExp * expMult / gameCPS; + hackExp = baseStudyComputerScienceExp * expMult / gameCPS * hashManager.getStudyMult(); break; case CONSTANTS.ClassDataStructures: cost = CONSTANTS.ClassDataStructuresBaseCost * costMult / gameCPS; - hackExp = baseDataStructuresExp * expMult / gameCPS; + hackExp = baseDataStructuresExp * expMult / gameCPS * hashManager.getStudyMult(); break; case CONSTANTS.ClassNetworks: cost = CONSTANTS.ClassNetworksBaseCost * costMult / gameCPS; - hackExp = baseNetworksExp * expMult / gameCPS; + hackExp = baseNetworksExp * expMult / gameCPS * hashManager.getStudyMult(); break; case CONSTANTS.ClassAlgorithms: cost = CONSTANTS.ClassAlgorithmsBaseCost * costMult / gameCPS; - hackExp = baseAlgorithmsExp * expMult / gameCPS; + hackExp = baseAlgorithmsExp * expMult / gameCPS * hashManager.getStudyMult(); break; case CONSTANTS.ClassManagement: cost = CONSTANTS.ClassManagementBaseCost * costMult / gameCPS; - chaExp = baseManagementExp * expMult / gameCPS; + chaExp = baseManagementExp * expMult / gameCPS * hashManager.getStudyMult(); break; case CONSTANTS.ClassLeadership: cost = CONSTANTS.ClassLeadershipBaseCost * costMult / gameCPS; - chaExp = baseLeadershipExp * expMult / gameCPS; + chaExp = baseLeadershipExp * expMult / gameCPS * hashManager.getStudyMult(); break; case CONSTANTS.ClassGymStrength: cost = CONSTANTS.ClassGymBaseCost * costMult / gameCPS; - strExp = baseGymExp * expMult / gameCPS; + strExp = baseGymExp * expMult / gameCPS * hashManager.getTrainingMult(); break; case CONSTANTS.ClassGymDefense: cost = CONSTANTS.ClassGymBaseCost * costMult / gameCPS; - defExp = baseGymExp * expMult / gameCPS; + defExp = baseGymExp * expMult / gameCPS * hashManager.getTrainingMult(); break; case CONSTANTS.ClassGymDexterity: cost = CONSTANTS.ClassGymBaseCost * costMult / gameCPS; - dexExp = baseGymExp * expMult / gameCPS; + dexExp = baseGymExp * expMult / gameCPS * hashManager.getTrainingMult(); break; case CONSTANTS.ClassGymAgility: cost = CONSTANTS.ClassGymBaseCost * costMult / gameCPS; - agiExp = baseGymExp * expMult / gameCPS; + agiExp = baseGymExp * expMult / gameCPS * hashManager.getTrainingMult(); break; default: throw new Error("ERR: Invalid/unrecognized class name"); diff --git a/src/RedPill.js b/src/RedPill.js index 43a913c90..5420e43c5 100644 --- a/src/RedPill.js +++ b/src/RedPill.js @@ -213,9 +213,7 @@ function loadBitVerse(destroyedBitNodeNum, flume=false) { var elemId = "bitnode-" + i.toString(); var elem = clearEventListeners(elemId); if (elem == null) {return;} - if (i === 1 || i === 2 || i === 3 || i === 4 || i === 5 || - i === 6 || i === 7 || i === 8 || i === 10 || i === 11 || - i === 12) { + if (i >= 1 && i <= 12) { elem.addEventListener("click", function() { var bitNodeKey = "BitNode" + i; var bitNode = BitNodes[bitNodeKey]; diff --git a/src/SaveObject.js b/src/SaveObject.js index 5edc37780..d382765c9 100755 --- a/src/SaveObject.js +++ b/src/SaveObject.js @@ -10,7 +10,8 @@ import { processPassiveFactionRepGain } from "./Faction/FactionHelpers"; import { loadFconf } from "./Fconf/Fconf"; import { FconfSettings } from "./Fconf/FconfSettings"; import {loadAllGangs, AllGangs} from "./Gang"; -import {processAllHacknetNodeEarnings} from "./HacknetNode"; +import { hasHacknetServers, + processHacknetEarnings } from "./Hacknet/HacknetHelpers"; import { loadMessages, initMessages, Messages } from "./Message/MessageHelpers"; import {Player, loadPlayer} from "./Player"; import { loadAllRunningScripts } from "./Script/ScriptHelpers"; @@ -490,7 +491,10 @@ function loadImportedGame(saveObj, saveString) { } //Hacknet Nodes offline progress - var offlineProductionFromHacknetNodes = processAllHacknetNodeEarnings(numCyclesOffline); + var offlineProductionFromHacknetNodes = processHacknetEarnings(numCyclesOffline); + const hacknetProdInfo = hasHacknetServers() ? + `${numeralWrapper.format(offlineProductionFromHacknetNodes, "0.000a")} hashes` : + `${numeralWrapper.formatMoney(offlineProductionFromHacknetNodes)}`; //Passive faction rep gain offline processPassiveFactionRepGain(numCyclesOffline); @@ -515,8 +519,8 @@ function loadImportedGame(saveObj, saveString) { const timeOfflineString = convertTimeMsToTimeElapsedString(time); dialogBoxCreate(`Offline for ${timeOfflineString}. While you were offline, your scripts ` + "generated " + - numeralWrapper.formatMoney(offlineProductionFromScripts) + " and your Hacknet Nodes generated " + - numeralWrapper.formatMoney(offlineProductionFromHacknetNodes) + ""); + numeralWrapper.formatMoney(offlineProductionFromScripts) + "
    " + + "and your Hacknet Nodes generated " + hacknetProdInfo + ""); return true; } diff --git a/src/Server/BaseServer.ts b/src/Server/BaseServer.ts new file mode 100644 index 000000000..b09ff9534 --- /dev/null +++ b/src/Server/BaseServer.ts @@ -0,0 +1,206 @@ +/** + * Abstract Base Class for any Server object + */ +import { CodingContract } from "../CodingContracts"; +import { Message } from "../Message/Message"; +import { RunningScript } from "../Script/RunningScript"; +import { Script } from "../Script/Script"; +import { TextFile } from "../TextFile"; + +import { isScriptFilename } from "../Script/ScriptHelpersTS"; + +import { createRandomIp } from "../../utils/IPAddress"; + +interface IConstructorParams { + adminRights?: boolean; + hostname: string; + ip?: string; + isConnectedTo?: boolean; + maxRam?: number; + organizationName?: string; +} + +export abstract class BaseServer { + // Coding Contract files on this server + contracts: CodingContract[] = []; + + // How many CPU cores this server has. Maximum of 8. + // Currently, this only affects hacking missions + cpuCores: number = 1; + + // Flag indicating whether the FTP port is open + ftpPortOpen: boolean = false; + + // Flag indicating whether player has admin/root access to this server + hasAdminRights: boolean = false; + + // Hostname. Must be unique + hostname: string = ""; + + // Flag indicating whether HTTP Port is open + httpPortOpen: boolean = false; + + // IP Address. Must be unique + ip: string = ""; + + // Flag indicating whether player is curently connected to this server + isConnectedTo: boolean = false; + + // RAM (GB) available on this server + maxRam: number = 0; + + // Message files AND Literature files on this Server + // For Literature files, this array contains only the filename (string) + // For Messages, it contains the actual Message object + // TODO Separate literature files into its own property + messages: (Message | string)[] = []; + + // Name of company/faction/etc. that this server belongs to. + // Optional, not applicable to all Servers + organizationName: string = ""; + + // Programs on this servers. Contains only the names of the programs + programs: string[] = []; + + // RAM (GB) used. i.e. unavailable RAM + ramUsed: number = 0; + + // RunningScript files on this server + runningScripts: RunningScript[] = []; + + // Script files on this Server + scripts: Script[] = []; + + // Contains the IP Addresses of all servers that are immediately + // reachable from this one + serversOnNetwork: string[] = []; + + // Flag indicating whether SMTP Port is open + smtpPortOpen: boolean = false; + + // Flag indicating whether SQL Port is open + sqlPortOpen: boolean = false; + + // Flag indicating whether the SSH Port is open + sshPortOpen: boolean = false; + + // Text files on this server + textFiles: TextFile[] = []; + + constructor(params: IConstructorParams={ hostname: "", ip: createRandomIp() }) { + this.ip = params.ip ? params.ip : createRandomIp(); + + this.hostname = params.hostname; + this.organizationName = params.organizationName != null ? params.organizationName : ""; + this.isConnectedTo = params.isConnectedTo != null ? params.isConnectedTo : false; + + //Access information + this.hasAdminRights = params.adminRights != null ? params.adminRights : false; + } + + addContract(contract: CodingContract) { + this.contracts.push(contract); + } + + getContract(contractName: string): CodingContract | null { + for (const contract of this.contracts) { + if (contract.fn === contractName) { + return contract; + } + } + return null; + } + + // Given the name of the script, returns the corresponding + // script object on the server (if it exists) + getScript(scriptName: string): Script | null { + for (let i = 0; i < this.scripts.length; i++) { + if (this.scripts[i].filename === scriptName) { + return this.scripts[i]; + } + } + + return null; + } + + removeContract(contract: CodingContract) { + if (contract instanceof CodingContract) { + this.contracts = this.contracts.filter((c) => { + return c.fn !== contract.fn; + }); + } else { + this.contracts = this.contracts.filter((c) => { + return c.fn !== contract; + }); + } + } + + /** + * Called when a script is run on this server. + * All this function does is add a RunningScript object to the + * `runningScripts` array. It does NOT check whether the script actually can + * be run. + */ + runScript(script: RunningScript): void { + this.runningScripts.push(script); + } + + setMaxRam(ram: number): void { + this.maxRam = ram; + } + + /** + * Write to a script file + * Overwrites existing files. Creates new files if the script does not eixst + */ + writeToScriptFile(fn: string, code: string) { + var ret = {success: false, overwritten: false}; + if (!isScriptFilename(fn)) { return ret; } + + //Check if the script already exists, and overwrite it if it does + for (let i = 0; i < this.scripts.length; ++i) { + if (fn === this.scripts[i].filename) { + let script = this.scripts[i]; + script.code = code; + script.updateRamUsage(); + script.module = ""; + ret.overwritten = true; + ret.success = true; + return ret; + } + } + + //Otherwise, create a new script + const newScript = new Script(); + newScript.filename = fn; + newScript.code = code; + newScript.updateRamUsage(); + newScript.server = this.ip; + this.scripts.push(newScript); + ret.success = true; + return ret; + } + + // Write to a text file + // Overwrites existing files. Creates new files if the text file does not exist + writeToTextFile(fn: string, txt: string) { + var ret = { success: false, overwritten: false }; + if (!fn.endsWith("txt")) { return ret; } + + //Check if the text file already exists, and overwrite if it does + for (let i = 0; i < this.textFiles.length; ++i) { + if (this.textFiles[i].fn === fn) { + ret.overwritten = true; + this.textFiles[i].text = txt; + ret.success = true; + return ret; + } + } + + //Otherwise create a new text file + var newFile = new TextFile(fn, txt); + this.textFiles.push(newFile); + ret.success = true; + return ret; + } +} diff --git a/src/Server/Server.ts b/src/Server/Server.ts index bc3056d14..f11398c37 100644 --- a/src/Server/Server.ts +++ b/src/Server/Server.ts @@ -1,16 +1,12 @@ -// Class representing a single generic Server +// Class representing a single hackable Server +import { BaseServer } from "./BaseServer"; // TODO This import is a circular import. Try to fix it in the future import { GetServerByHostname } from "./ServerHelpers"; import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; -import { CodingContract } from "../CodingContracts"; -import { Message } from "../Message/Message"; -import { RunningScript } from "../Script/RunningScript"; -import { Script } from "../Script/Script"; -import { isScriptFilename } from "../Script/ScriptHelpersTS"; -import { TextFile } from "../TextFile"; +import { createRandomString } from "../utils/createRandomString"; import { createRandomIp } from "../../utils/IPAddress"; import { Generic_fromJSON, Generic_toJSON, @@ -31,7 +27,7 @@ interface IConstructorParams { serverGrowth?: number; } -export class Server { +export class Server extends BaseServer { // Initializes a Server Object from a JSON save state static fromJSON(value: any): Server { return Generic_fromJSON(Server, value.data); @@ -41,47 +37,13 @@ export class Server { // (i.e. security level when the server was created) baseDifficulty: number = 1; - // Coding Contract files on this server - contracts: CodingContract[] = []; - - // How many CPU cores this server has. Maximum of 8. - // Currently, this only affects hacking missions - cpuCores: number = 1; - - // Flag indicating whether the FTP port is open - ftpPortOpen: boolean = false; - // Server Security Level hackDifficulty: number = 1; - // Flag indicating whether player has admin/root access to this server - hasAdminRights: boolean = false; - - // Hostname. Must be unique - hostname: string = ""; - - // Flag indicating whether HTTP Port is open - httpPortOpen: boolean = false; - - // IP Address. Must be unique - ip: string = ""; - - // Flag indicating whether player is curently connected to this server - isConnectedTo: boolean = false; - // Flag indicating whether this server has been manually hacked (ie. // hacked through Terminal) by the player manuallyHacked: boolean = false; - // RAM (GB) available on this server - maxRam: number = 0; - - // Message files AND Literature files on this Server - // For Literature files, this array contains only the filename (string) - // For Messages, it contains the actual Message object - // TODO Separate literature files into its own property - messages: (Message | string)[] = []; - // Minimum server security level that this server can be weakened to minDifficulty: number = 1; @@ -97,67 +59,35 @@ export class Server { // How many ports are currently opened on the server openPortCount: number = 0; - // Name of company/faction/etc. that this server belongs to. - // Optional, not applicable to all Servers - organizationName: string = ""; - - // Programs on this servers. Contains only the names of the programs - programs: string[] = []; - // Flag indicating wehther this is a purchased server purchasedByPlayer: boolean = false; - // RAM (GB) used. i.e. unavailable RAM - ramUsed: number = 0; - // Hacking level required to hack this server requiredHackingSkill: number = 1; - // RunningScript files on this server - runningScripts: RunningScript[] = []; - - // Script files on this Server - scripts: Script[] = []; - // Parameter that affects how effectively this server's money can // be increased using the grow() Netscript function serverGrowth: number = 1; - // Contains the IP Addresses of all servers that are immediately - // reachable from this one - serversOnNetwork: string[] = []; - - // Flag indicating whether SMTP Port is open - smtpPortOpen: boolean = false; - - // Flag indicating whether SQL Port is open - sqlPortOpen: boolean = false; - - // Flag indicating whether the SSH Port is open - sshPortOpen: boolean = false; - - // Text files on this server - textFiles: TextFile[] = []; - constructor(params: IConstructorParams={hostname: "", ip: createRandomIp() }) { - /* Properties */ - //Connection information - this.ip = params.ip ? params.ip : createRandomIp(); + super(params); - var hostname = params.hostname; - var i = 0; - var suffix = ""; - while (GetServerByHostname(hostname+suffix) != null) { - //Server already exists - suffix = "-" + i; - ++i; + // "hacknet-node-X" hostnames are reserved for Hacknet Servers + if (this.hostname.startsWith("hacknet-node-")) { + this.hostname = createRandomString(10); + } + + // Validate hostname by ensuring there are no repeats + if (GetServerByHostname(this.hostname) != null) { + // Use a for loop to ensure that we don't get suck in an infinite loop somehow + let hostname: string = this.hostname; + for (let i = 0; i < 200; ++i) { + hostname = `${this.hostname}-${i}`; + if (GetServerByHostname(hostname) == null) { break; } + } + this.hostname = hostname; } - this.hostname = hostname + suffix; - this.organizationName = params.organizationName != null ? params.organizationName : ""; - this.isConnectedTo = params.isConnectedTo != null ? params.isConnectedTo : false; - //Access information - this.hasAdminRights = params.adminRights != null ? params.adminRights : false; this.purchasedByPlayer = params.purchasedByPlayer != null ? params.purchasedByPlayer : false; //RAM, CPU speed and Scripts @@ -178,23 +108,9 @@ export class Server { this.numOpenPortsRequired = params.numOpenPortsRequired != null ? params.numOpenPortsRequired : 5; }; - setMaxRam(ram: number): void { - this.maxRam = ram; - } - - // Given the name of the script, returns the corresponding - // script object on the server (if it exists) - getScript(scriptName: string): Script | null { - for (let i = 0; i < this.scripts.length; i++) { - if (this.scripts[i].filename === scriptName) { - return this.scripts[i]; - } - } - - return null; - } - - // Ensures that the server's difficulty (server security) doesn't get too high + /** + * Ensures that the server's difficulty (server security) doesn't get too high + */ capDifficulty(): void { if (this.hackDifficulty < this.minDifficulty) {this.hackDifficulty = this.minDifficulty;} if (this.hackDifficulty < 1) {this.hackDifficulty = 1;} @@ -204,97 +120,54 @@ export class Server { if (this.hackDifficulty > 1000000) {this.hackDifficulty = 1000000;} } - // Strengthens a server's security level (difficulty) by the specified amount + /** + * Change this server's minimum security + * @param n - Value by which to increase/decrease the server's minimum security + * @param perc - Whether it should be changed by a percentage, or a flat value + */ + changeMinimumSecurity(n: number, perc: boolean=false): void { + if (perc) { + this.minDifficulty *= n; + } else { + this.minDifficulty += n; + } + + // Server security cannot go below 1 + this.minDifficulty = Math.max(1, this.minDifficulty); + } + + /** + * Strengthens a server's security level (difficulty) by the specified amount + */ fortify(amt: number): void { this.hackDifficulty += amt; this.capDifficulty(); } - // Lowers the server's security level (difficulty) by the specified amount) + /** + * Change this server's maximum money + * @param n - Value by which to change the server's maximum money + * @param perc - Whether it should be changed by a percentage, or a flat value + */ + changeMaximumMoney(n: number, perc: boolean=false): void { + if (perc) { + this.moneyMax *= n; + } else { + this.moneyMax += n; + } + } + + /** + * Lowers the server's security level (difficulty) by the specified amount) + */ weaken(amt: number): void { this.hackDifficulty -= (amt * BitNodeMultipliers.ServerWeakenRate); this.capDifficulty(); } - // Write to a script file - // Overwrites existing files. Creates new files if the script does not eixst - writeToScriptFile(fn: string, code: string) { - var ret = {success: false, overwritten: false}; - if (!isScriptFilename(fn)) { return ret; } - - //Check if the script already exists, and overwrite it if it does - for (let i = 0; i < this.scripts.length; ++i) { - if (fn === this.scripts[i].filename) { - let script = this.scripts[i]; - script.code = code; - script.updateRamUsage(); - script.module = ""; - ret.overwritten = true; - ret.success = true; - return ret; - } - } - - //Otherwise, create a new script - const newScript = new Script(); - newScript.filename = fn; - newScript.code = code; - newScript.updateRamUsage(); - newScript.server = this.ip; - this.scripts.push(newScript); - ret.success = true; - return ret; - } - - // Write to a text file - // Overwrites existing files. Creates new files if the text file does not exist - writeToTextFile(fn: string, txt: string) { - var ret = { success: false, overwritten: false }; - if (!fn.endsWith("txt")) { return ret; } - - //Check if the text file already exists, and overwrite if it does - for (let i = 0; i < this.textFiles.length; ++i) { - if (this.textFiles[i].fn === fn) { - ret.overwritten = true; - this.textFiles[i].text = txt; - ret.success = true; - return ret; - } - } - - //Otherwise create a new text file - var newFile = new TextFile(fn, txt); - this.textFiles.push(newFile); - ret.success = true; - return ret; - } - - addContract(contract: CodingContract) { - this.contracts.push(contract); - } - - removeContract(contract: CodingContract) { - if (contract instanceof CodingContract) { - this.contracts = this.contracts.filter((c) => { - return c.fn !== contract.fn; - }); - } else { - this.contracts = this.contracts.filter((c) => { - return c.fn !== contract; - }); - } - } - - getContract(contractName: string) { - for (const contract of this.contracts) { - if (contract.fn === contractName) { - return contract; - } - } - return null; - } - - // Serialize the current object to a JSON save state + /** + * Serialize the current object to a JSON save state + */ toJSON(): any { return Generic_toJSON("Server", this); } diff --git a/src/Terminal.js b/src/Terminal.js index d2744b2c9..08595bc5a 100644 --- a/src/Terminal.js +++ b/src/Terminal.js @@ -19,6 +19,7 @@ import {calculateHackingChance, calculateHackingTime, calculateGrowTime, calculateWeakenTime} from "./Hacking"; +import { HacknetServer } from "./Hacknet/HacknetServer"; import {TerminalHelpText, HelpTexts} from "./HelpText"; import {iTutorialNextStep, iTutorialSteps, ITutorial} from "./InteractiveTutorial"; @@ -760,18 +761,19 @@ let Terminal = { finishAnalyze: function(cancelled = false) { if (cancelled == false) { let currServ = Player.getCurrentServer(); + const isHacknet = currServ instanceof HacknetServer; post(currServ.hostname + ": "); post("Organization name: " + currServ.organizationName); var rootAccess = ""; if (currServ.hasAdminRights) {rootAccess = "YES";} else {rootAccess = "NO";} post("Root Access: " + rootAccess); - post("Required hacking skill: " + currServ.requiredHackingSkill); + if (!isHacknet) { post("Required hacking skill: " + currServ.requiredHackingSkill); } post("Server security level: " + numeralWrapper.format(currServ.hackDifficulty, '0.000a')); post("Chance to hack: " + numeralWrapper.format(calculateHackingChance(currServ), '0.00%')); post("Time to hack: " + numeralWrapper.format(calculateHackingTime(currServ), '0.000') + " seconds"); post("Total money available on server: " + numeralWrapper.format(currServ.moneyAvailable, '$0,0.00')); - post("Required number of open ports for NUKE: " + currServ.numOpenPortsRequired); + if (!isHacknet) { post("Required number of open ports for NUKE: " + currServ.numOpenPortsRequired); } if (currServ.sshPortOpen) { post("SSH port: Open") @@ -2240,7 +2242,7 @@ let Terminal = { post("May take a few seconds to start up the process..."); var runningScriptObj = new RunningScript(script, args); runningScriptObj.threads = numThreads; - server.runningScripts.push(runningScriptObj); + server.runScript(runningScriptObj, Player); addWorkerScript(runningScriptObj, server); return; diff --git a/src/engine.jsx b/src/engine.jsx index 87d8fffe4..b1e5064e2 100644 --- a/src/engine.jsx +++ b/src/engine.jsx @@ -30,8 +30,10 @@ import { FconfSettings } from "./Fconf/FconfSetti import {displayLocationContent, initLocationButtons} from "./Location"; import {Locations} from "./Locations"; -import {displayHacknetNodesContent, processAllHacknetNodeEarnings, - updateHacknetNodesContent} from "./HacknetNode"; +import { hasHacknetServers, + renderHacknetNodesUI, + clearHacknetNodesUI, + processHacknetEarnings } from "./Hacknet/HacknetHelpers"; import {iTutorialStart} from "./InteractiveTutorial"; import {initLiterature} from "./Literature"; import { checkForMessagesToSend, initMessages } from "./Message/MessageHelpers"; @@ -109,6 +111,7 @@ import "../css/mainmenu.scss"; import "../css/characteroverview.scss"; import "../css/terminal.scss"; import "../css/scripteditor.scss"; +import "../css/hacknetnodes.scss"; import "../css/menupages.scss"; import "../css/redpill.scss"; import "../css/stockmarket.scss"; @@ -294,8 +297,8 @@ const Engine = { loadHacknetNodesContent: function() { Engine.hideAllContent(); Engine.Display.hacknetNodesContent.style.display = "block"; - displayHacknetNodesContent(); routing.navigateTo(Page.HacknetNodes); + renderHacknetNodesUI(); MainMenuLinks.HacknetNodes.classList.add("active"); }, @@ -506,7 +509,7 @@ const Engine = { Engine.Display.characterContent.style.display = "none"; Engine.Display.scriptEditorContent.style.display = "none"; Engine.Display.activeScriptsContent.style.display = "none"; - Engine.Display.hacknetNodesContent.style.display = "none"; + clearHacknetNodesUI(); Engine.Display.worldContent.style.display = "none"; Engine.Display.createProgramContent.style.display = "none"; Engine.Display.factionsContent.style.display = "none"; @@ -870,7 +873,7 @@ const Engine = { updateOnlineScriptTimes(numCycles); //Hacknet Nodes - processAllHacknetNodeEarnings(numCycles); + processHacknetEarnings(numCycles); }, //Counters for the main event loop. Represent the number of game cycles are required @@ -932,7 +935,7 @@ const Engine = { if (Engine.Counters.updateDisplays <= 0) { Engine.displayCharacterOverviewInfo(); if (routing.isOn(Page.HacknetNodes)) { - updateHacknetNodesContent(); + renderHacknetNodesUI(); } else if (routing.isOn(Page.CreateProgram)) { displayCreateProgramContent(); } else if (routing.isOn(Page.Sleeves)) { @@ -1183,7 +1186,10 @@ const Engine = { } //Hacknet Nodes offline progress - var offlineProductionFromHacknetNodes = processAllHacknetNodeEarnings(numCyclesOffline); + var offlineProductionFromHacknetNodes = processHacknetEarnings(numCyclesOffline); + const hacknetProdInfo = hasHacknetServers() ? + `${numeralWrapper.format(offlineProductionFromHacknetNodes, "0.000a")} hashes` : + `${numeralWrapper.formatMoney(offlineProductionFromHacknetNodes)}`; //Passive faction rep gain offline processPassiveFactionRepGain(numCyclesOffline); @@ -1237,8 +1243,8 @@ const Engine = { const timeOfflineString = convertTimeMsToTimeElapsedString(time); dialogBoxCreate(`Offline for ${timeOfflineString}. While you were offline, your scripts ` + "generated " + - numeralWrapper.formatMoney(offlineProductionFromScripts) + " and your Hacknet Nodes generated " + - numeralWrapper.formatMoney(offlineProductionFromHacknetNodes) + ""); + numeralWrapper.formatMoney(offlineProductionFromScripts) + "
    " + + "and your Hacknet Nodes generated " + hacknetProdInfo + ""); //Close main menu accordions for loaded game var visibleMenuTabs = [terminal, createScript, activeScripts, stats, hacknetnodes, city, tutorial, options, dev]; diff --git a/src/index.html b/src/index.html index d07c437f7..885c2dce4 100644 --- a/src/index.html +++ b/src/index.html @@ -203,35 +203,7 @@ if (htmlWebpackPlugin.options.googleAnalytics.trackingId) { %>
    -

    Hacknet Nodes

    - - Purchase Hacknet Node -
    -
    -

    - Money:
    - Total Hacknet Node Production: -

    - - x1 - x5 - x10 - MAX - -
    -
      -
    +
    diff --git a/src/ui/React/ServerDropdown.jsx b/src/ui/React/ServerDropdown.jsx new file mode 100644 index 000000000..81c25d3b6 --- /dev/null +++ b/src/ui/React/ServerDropdown.jsx @@ -0,0 +1,65 @@ +/** + * Creates a dropdown (select HTML element) with server hostnames as options + * + * Configurable to only contain certain types of servers + */ +import React from "react"; +import { AllServers } from "../../Server/AllServers"; + +import { HacknetServer } from "../../Hacknet/HacknetServer"; + +// TODO make this an enum when this gets converted to TypeScript +export const ServerType = { + All: 0, + Foreign: 1, // Hackable, non-owned servers + Owned: 2, // Home Computer, Purchased Servers, and Hacknet Servers + Purchased: 3, // Everything from Owned except home computer +} + +export class ServerDropdown extends React.Component { + /** + * Checks if the server should be shown in the dropdown menu, based on the + * 'serverType' property + */ + isValidServer(s) { + const type = this.props.serverType; + switch (type) { + case ServerType.All: + return true; + case ServerType.Foreign: + return (s.hostname !== "home" && !s.purchasedByPlayer); + case ServerType.Owned: + return s.purchasedByPlayer || (s instanceof HacknetServer) || s.hostname === "home"; + case ServerType.Purchased: + return s.purchasedByPlayer || (s instanceof HacknetServer); + default: + console.warn(`Invalid ServerType specified for ServerDropdown component: ${type}`); + return false; + } + } + + /** + * Given a Server object, creates a Option element + */ + renderOption(s) { + return ( + + ) + } + + render() { + const servers = []; + for (const serverName in AllServers) { + const server = AllServers[serverName]; + if (this.isValidServer(server)) { + servers.push(this.renderOption(server)); + } + } + + return ( + + ) + } +} diff --git a/src/ui/React/createPopup.ts b/src/ui/React/createPopup.ts new file mode 100644 index 000000000..2974549fb --- /dev/null +++ b/src/ui/React/createPopup.ts @@ -0,0 +1,56 @@ +/** + * Create a pop-up dialog box using React. + * + * Calling this function with the same ID and React Root Component will trigger a re-render + * + * @param id The (hopefully) unique identifier for the popup container + * @param rootComponent Root React Component + */ +import * as React from "react"; +import * as ReactDOM from "react-dom"; + +import { createElement } from "../../../utils/uiHelpers/createElement"; +import { removeElementById } from "../../../utils/uiHelpers/removeElementById"; + +type ReactComponent = new(...args: any[]) => React.Component; + +export function createPopup(id: string, rootComponent: ReactComponent, props: object): HTMLElement { + let container = document.getElementById(id); + let content = document.getElementById(`${id}-content`); + if (container == null || content == null) { + container = createElement("div", { + class: "popup-box-container", + display: "flex", + id: id, + }); + + content = createElement("div", { + class: "popup-box-content", + id: `${id}-content`, + }); + + container.appendChild(content); + + try { + document.getElementById("entire-game-container")!.appendChild(container); + } catch(e) { + console.error(`Exception caught when creating popup: ${e}`); + } + } + + ReactDOM.render(React.createElement(rootComponent, props), content); + + return container; +} + +/** + * Closes a popup created with the createPopup() function above + */ +export function removePopup(id: string): void { + let content = document.getElementById(`${id}-content`); + if (content == null) { return; } + + ReactDOM.unmountComponentAtNode(content); + + removeElementById(id); +} diff --git a/src/utils/createRandomString.ts b/src/utils/createRandomString.ts new file mode 100644 index 000000000..d963e8a41 --- /dev/null +++ b/src/utils/createRandomString.ts @@ -0,0 +1,12 @@ +// Function that generates a random gibberish string of length n +const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + +export function createRandomString(n: number): string { + let str: string = ""; + + for (let i = 0; i < n; ++i) { + str += chars.charAt(Math.floor(Math.random() * chars.length)); + } + + return str; +} From 3cf18f100a50462aee773f0fb3bf455ca4b045e4 Mon Sep 17 00:00:00 2001 From: danielyxie Date: Mon, 25 Mar 2019 21:38:57 -0700 Subject: [PATCH 06/17] Added several resuable React components for commonly-used elements --- src/ui/React/ParagraphWithTooltip.tsx | 23 ++++++++ src/ui/React/PopupCloseButton.tsx | 65 +++++++++++++++++++++++ src/ui/React/StdButton.tsx | 24 +++++++++ utils/uiHelpers/createPopupCloseButton.ts | 4 +- 4 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 src/ui/React/ParagraphWithTooltip.tsx create mode 100644 src/ui/React/PopupCloseButton.tsx create mode 100644 src/ui/React/StdButton.tsx diff --git a/src/ui/React/ParagraphWithTooltip.tsx b/src/ui/React/ParagraphWithTooltip.tsx new file mode 100644 index 000000000..ac0a675a3 --- /dev/null +++ b/src/ui/React/ParagraphWithTooltip.tsx @@ -0,0 +1,23 @@ +/** + * Text (p Element) with Tooltip + */ +import * as React from "react"; + +export interface IParagraphWithTooltipProps { + style?: object; + text: string; + tooltip: string; +} + +export class ParagraphWithTooltip extends React.Component { + render() { + return ( +

    + {this.props.text} + + {this.props.tooltip} + +

    + ) + } +} diff --git a/src/ui/React/PopupCloseButton.tsx b/src/ui/React/PopupCloseButton.tsx new file mode 100644 index 000000000..7749db4f2 --- /dev/null +++ b/src/ui/React/PopupCloseButton.tsx @@ -0,0 +1,65 @@ +/** + * Close button for popup dialog boxes + * It creates an event handler such that pressing Esc will close the binded popup + * + * Should only be used in other React components, otherwise it may not be properly + * unmounted + */ +import * as React from "react"; +import * as ReactDOM from "react-dom"; + +import { KEY } from "../../../utils/helpers/keyCodes"; + +export interface IPopupCloseButtonProps { + class?: string; + popup: HTMLElement | string; + style?: object; + text: string; +} + +export class PopupCloseButton extends React.Component { + constructor(props: IPopupCloseButtonProps) { + super(props); + + this.closePopup = this.closePopup.bind(this); + this.keyListener = this.keyListener.bind(this); + } + + componentDidMount() { + document.addEventListener("keydown", this.keyListener); + } + + componentWillUnmount() { + document.removeEventListener("keydown", this.keyListener); + } + + closePopup() { + let popup: HTMLElement | null; + if (typeof this.props.popup === "string") { + popup = document.getElementById(this.props.popup); + } else { + popup = this.props.popup; + } + + // TODO Check if this is okay? This is essentially calling to unmount a parent component + if (popup instanceof HTMLElement) { + ReactDOM.unmountComponentAtNode(popup); + } + } + + keyListener(e: KeyboardEvent) { + if (e.keyCode === KEY.ESC) { + this.closePopup(); + } + } + + render() { + const className = this.props.class ? this.props.class : "std-button"; + + return ( + + ) + } +} diff --git a/src/ui/React/StdButton.tsx b/src/ui/React/StdButton.tsx new file mode 100644 index 000000000..21f8ab180 --- /dev/null +++ b/src/ui/React/StdButton.tsx @@ -0,0 +1,24 @@ +/** + * Basic stateless button + * Uses the 'std-button' css class + */ +import * as React from "react"; + +export interface IStdButtonProps { + disabled?: boolean; + onClick?: (e: React.MouseEvent) => any; + style?: object; + text: string; +} + +export class StdButton extends React.Component { + render() { + const className = this.props.disabled ? "std-button-disabled" : "std-button"; + + return ( + + ) + } +} diff --git a/utils/uiHelpers/createPopupCloseButton.ts b/utils/uiHelpers/createPopupCloseButton.ts index 8fb185bcc..22c34bcd7 100644 --- a/utils/uiHelpers/createPopupCloseButton.ts +++ b/utils/uiHelpers/createPopupCloseButton.ts @@ -1,4 +1,6 @@ -/* Creates a Close/Cancel button that is used for removing popups */ +/** + * Creates a Close/Cancel button that is used for removing popups + */ import { createElement } from "./createElement"; import { removeElement } from "./removeElement"; From c4cb7daac586b9a5ff93ca794d54c954d833af3c Mon Sep 17 00:00:00 2001 From: danielyxie Date: Wed, 27 Mar 2019 01:36:14 -0700 Subject: [PATCH 07/17] Initial v0.46.0 changes - Fixed BN9 bugs. Rebalanced BN11 and Corporations. Added memory to Dup sleeves. Various bug fixes --- css/popupboxes.scss | 2 +- doc/source/advancedgameplay/sleeves.rst | 10 ++ .../netscript/sleeveapi/getSleeveStats.rst | 4 +- .../netscript/sleeveapi/purchaseSleeveAug.rst | 4 +- src/BitNode/BitNode.ts | 24 ++-- src/Bladeburner.js | 15 ++- src/Constants.ts | 47 +++----- src/Corporation/Corporation.jsx | 33 ++++-- src/Corporation/Material.ts | 14 +-- .../ui/CorporationUIEventHandler.js | 14 ++- src/Corporation/ui/IndustryOffice.jsx | 2 +- src/Corporation/ui/IndustryWarehouse.jsx | 8 +- src/Faction/FactionHelpers.js | 4 +- src/Hacknet/HacknetHelpers.jsx | 22 ++-- src/Hacknet/HacknetServer.ts | 7 +- src/Hacknet/HashManager.ts | 25 +++- src/Hacknet/ui/Root.jsx | 17 ++- src/Infiltration.js | 24 ++-- src/Location.js | 2 +- src/NetscriptEvaluator.js | 5 +- src/PersonObjects/IPlayer.ts | 2 +- src/PersonObjects/Sleeve/Sleeve.ts | 55 ++++++++- .../Sleeve/SleeveCovenantPurchases.ts | 50 ++------ src/PersonObjects/Sleeve/SleeveUI.ts | 3 +- src/PersonObjects/Sleeve/data/SleeveFaq.ts | 10 +- .../Sleeve/ui/CovenantPurchasesRoot.tsx | 112 ++++++++++++++++++ .../Sleeve/ui/CovenantSleeveMemoryUpgrade.tsx | 97 +++++++++++++++ .../Sleeve/ui/CovenantSleeveUpgrades.tsx | 28 +++++ src/Player.js | 28 +++-- src/Server/AllServers.ts | 4 +- src/Server/ServerHelpers.ts | 5 +- src/SourceFile.js | 8 +- src/StockMarket/StockMarket.js | 5 +- src/Terminal.js | 26 ++-- src/ui/React/Popup.tsx | 24 ++++ src/ui/React/PopupCloseButton.tsx | 6 +- src/ui/React/StdButton.tsx | 2 +- .../React/{createPopup.ts => createPopup.tsx} | 40 ++++--- 38 files changed, 579 insertions(+), 209 deletions(-) create mode 100644 src/PersonObjects/Sleeve/ui/CovenantPurchasesRoot.tsx create mode 100644 src/PersonObjects/Sleeve/ui/CovenantSleeveMemoryUpgrade.tsx create mode 100644 src/PersonObjects/Sleeve/ui/CovenantSleeveUpgrades.tsx create mode 100644 src/ui/React/Popup.tsx rename src/ui/React/{createPopup.ts => createPopup.tsx} (56%) diff --git a/css/popupboxes.scss b/css/popupboxes.scss index 174044db3..d6845b9f0 100644 --- a/css/popupboxes.scss +++ b/css/popupboxes.scss @@ -3,7 +3,7 @@ /* Pop-up boxes */ .popup-box-container { - display: none; /* Hidden by default */ + display: none; /* Initially hidden */ position: fixed; /* Stay in place */ z-index: 10; /* Sit on top */ left: 0; diff --git a/doc/source/advancedgameplay/sleeves.rst b/doc/source/advancedgameplay/sleeves.rst index b0db5b682..35eeaa9ac 100644 --- a/doc/source/advancedgameplay/sleeves.rst +++ b/doc/source/advancedgameplay/sleeves.rst @@ -80,6 +80,16 @@ when you normally install Augmentations. The cost of purchasing an Augmentation for a Duplicate Sleeve is **not** affected by how many Augmentations you have purchased for yourself, and vice versa. +Memory +~~~~~~ +Sleeve memory dictates what a sleeve's synchronization will be when its reset by +switching BitNodes. For example, if a sleeve has a memory of 10, then when you +switch BitNodes its synchronization will initially be set to 10, rather than 1. + +Memory can only be increased by purchasing upgrades from The Covenant. +It is a persistent stat, meaning it never gets reset back to 1. +The maximum possible value for a sleeve's memory is 100. + Re-sleeving ^^^^^^^^^^^ Re-sleeving is the process of digitizing and transferring your consciousness into a diff --git a/doc/source/netscript/sleeveapi/getSleeveStats.rst b/doc/source/netscript/sleeveapi/getSleeveStats.rst index 698fa9e4c..56f90388c 100644 --- a/doc/source/netscript/sleeveapi/getSleeveStats.rst +++ b/doc/source/netscript/sleeveapi/getSleeveStats.rst @@ -10,8 +10,8 @@ getSleeveStats() Netscript Function .. code-block:: javascript { - shock: current shock of the sleeve [0-1], - sync: current sync of the sleeve [0-1], + shock: current shock of the sleeve [0-100], + sync: current sync of the sleeve [0-100], hacking_skill: current hacking skill of the sleeve, strength: current strength of the sleeve, defense: current defense of the sleeve, diff --git a/doc/source/netscript/sleeveapi/purchaseSleeveAug.rst b/doc/source/netscript/sleeveapi/purchaseSleeveAug.rst index 31fff9f49..70fe4ebc2 100644 --- a/doc/source/netscript/sleeveapi/purchaseSleeveAug.rst +++ b/doc/source/netscript/sleeveapi/purchaseSleeveAug.rst @@ -4,6 +4,6 @@ purchaseSleeveAug() Netscript Function .. js:function:: purchaseSleeveAug(sleeveNumber, augName) :param int sleeveNumber: Index of the sleeve to buy an aug for. See :ref:`here ` - :param string augName: Name of the aug to buy. See :ref:`here ` + :param string augName: Name of the aug to buy. Must be an exact match - Return true if the aug was purchased and installed on the sleeve. \ No newline at end of file + Return true if the aug was purchased and installed on the sleeve. diff --git a/src/BitNode/BitNode.ts b/src/BitNode/BitNode.ts index 2d3568d70..778cb5098 100644 --- a/src/BitNode/BitNode.ts +++ b/src/BitNode/BitNode.ts @@ -201,8 +201,9 @@ export function initBitNodes() { "were able to steal billions of dollars from the world's largest electronic banks, prompting an international banking crisis as " + "governments were unable to bail out insolvent banks. Now, the world is slowly crumbling in the middle of the biggest economic crisis of all time.

    " + "In this BitNode:

    " + + "Your hacking stat and experience gain are halved
    " + "The starting and maximum amount of money available on servers is significantly decreased
    " + - "The growth rate of servers is halved
    " + + "The growth rate of servers is significantly reduced
    " + "Weakening a server is twice as effective
    " + "Company wages are decreased by 50%
    " + "Corporation valuations are 99% lower and are therefore significantly less profitable
    " + @@ -213,9 +214,9 @@ export function initBitNodes() { "upgrade its level up to a maximum of 3. This Source-File makes it so that company favor increases BOTH " + "the player's salary and reputation gain rate at that company by 1% per favor (rather than just the reputation gain). " + "This Source-File also increases the player's company salary and reputation gain multipliers by:

    " + - "Level 1: 24%
    " + - "Level 2: 36%
    " + - "Level 3: 42%"); + "Level 1: 32%
    " + + "Level 2: 48%
    " + + "Level 3: 56%"); BitNodes["BitNode12"] = new BitNode(12, "The Recursion", "Repeat.", "To iterate is human, to recurse divine.

    " + "Every time this BitNode is destroyed, it becomes slightly harder. Destroying this BitNode will give your Souce-File 12, or " + @@ -349,17 +350,20 @@ export function initBitNodeMultipliers(p: IPlayer) { BitNodeMultipliers.CodingContractMoney = 0; break; case 9: // Hacktocracy - BitNodeMultipliers.HackingLevelMultiplier = 0.3; + BitNodeMultipliers.HackingLevelMultiplier = 0.4; BitNodeMultipliers.StrengthLevelMultiplier = 0.45; BitNodeMultipliers.DefenseLevelMultiplier = 0.45; BitNodeMultipliers.DexterityLevelMultiplier = 0.45; BitNodeMultipliers.AgilityLevelMultiplier = 0.45; BitNodeMultipliers.CharismaLevelMultiplier = 0.45; BitNodeMultipliers.PurchasedServerLimit = 0; - BitNodeMultipliers.HomeComputerRamCost = 3; + BitNodeMultipliers.HomeComputerRamCost = 5; BitNodeMultipliers.CrimeMoney = 0.5; BitNodeMultipliers.ScriptHackMoney = 0.1; BitNodeMultipliers.HackExpGain = 0.1; + BitNodeMultipliers.ServerStartingMoney = 0.1; + BitNodeMultipliers.ServerMaxMoney = 0.1; + BitNodeMultipliers.ServerStartingSecurity = 2.5; break; case 10: // Digital Carbon BitNodeMultipliers.HackingLevelMultiplier = 0.2; @@ -385,9 +389,11 @@ export function initBitNodeMultipliers(p: IPlayer) { BitNodeMultipliers.BladeburnerRank = 0.8; break; case 11: //The Big Crash + BitNodeMultipliers.HackingLevelMultiplier = 0.5; + BitNodeMultipliers.HackExpGain = 0.5; BitNodeMultipliers.ServerMaxMoney = 0.1; BitNodeMultipliers.ServerStartingMoney = 0.1; - BitNodeMultipliers.ServerGrowthRate = 0.5; + BitNodeMultipliers.ServerGrowthRate = 0.2; BitNodeMultipliers.ServerWeakenRate = 2; BitNodeMultipliers.CrimeMoney = 3; BitNodeMultipliers.CompanyWorkMoney = 0.5; @@ -395,8 +401,8 @@ export function initBitNodeMultipliers(p: IPlayer) { BitNodeMultipliers.AugmentationMoneyCost = 2; BitNodeMultipliers.InfiltrationMoney = 2.5; BitNodeMultipliers.InfiltrationRep = 2.5; - BitNodeMultipliers.CorporationValuation = 0.01; - BitNodeMultipliers.CodingContractMoney = 0.5; + BitNodeMultipliers.CorporationValuation = 0.1; + BitNodeMultipliers.CodingContractMoney = 0.25; BitNodeMultipliers.FourSigmaMarketDataCost = 4; BitNodeMultipliers.FourSigmaMarketDataApiCost = 4; break; diff --git a/src/Bladeburner.js b/src/Bladeburner.js index 8e0c6d339..495109ba8 100644 --- a/src/Bladeburner.js +++ b/src/Bladeburner.js @@ -78,8 +78,8 @@ const RanksPerSkillPoint = 3; //How many ranks needed to get 1 Skill const ContractBaseMoneyGain = 250e3; //Base Money Gained per contract -const HrcHpGain = 2; // HP gained from Hyperbolic Regeneration Chamber -const HrcStaminaGain = 0.1; // Stamina gained from Hyperbolic Regeneration Chamber +const HrcHpGain = 2; // HP Gained from Hyperbolic Regeneration chamber +const HrcStaminaGain = 1; // Percentage Stamina gained from Hyperbolic Regeneration Chamber //DOM related variables var ActiveActionCssClass = "bladeburner-active-action"; @@ -1417,14 +1417,17 @@ Bladeburner.prototype.completeAction = function() { } this.startAction(this.action); // Repeat Action break; - case ActionTypes["Hyperbolic Regeneration Chamber"]: + case ActionTypes["Hyperbolic Regeneration Chamber"]: { Player.regenerateHp(HrcHpGain); - this.stamina = Math.min(this.maxStamina, this.stamina + HrcStaminaGain); + + const staminaGain = this.maxStamina * (HrcStaminaGain / 100); + this.stamina = Math.min(this.maxStamina, this.stamina + staminaGain); this.startAction(this.action); if (this.logging.general) { - this.log(`Rested in Hyperbolic Regeneration Chamber. Restored ${HrcHpGain} HP and gained ${HrcStaminaGain} stamina`); + this.log(`Rested in Hyperbolic Regeneration Chamber. Restored ${HrcHpGain} HP and gained ${numeralWrapper.format(staminaGain, "0.0")} stamina`); } break; + } default: console.error(`Bladeburner.completeAction() called for invalid action: ${this.action.type}`); break; @@ -2513,7 +2516,7 @@ Bladeburner.prototype.updateContractsUIElement = function(el, action) { display:"inline-block", innerHTML:action.desc + "\n\n" + `Estimated success chance: ${formatNumber(estimatedSuccessChance*100, 1)}% ${action.isStealth?stealthIcon:''}${action.isKill?killIcon:''}\n` + - + "Time Required (s): " + formatNumber(actionTime, 0) + "\n" + "Contracts remaining: " + Math.floor(action.count) + "\n" + "Successes: " + action.successes + "\n" + diff --git a/src/Constants.ts b/src/Constants.ts index cb56cb3d2..ae1d9c96f 100644 --- a/src/Constants.ts +++ b/src/Constants.ts @@ -116,7 +116,7 @@ export let CONSTANTS: IMap = { InfiltrationBribeBaseAmount: 100e3, //Amount per clearance level InfiltrationMoneyValue: 5e3, //Convert "secret" value to money InfiltrationRepValue: 1.4, //Convert "secret" value to faction reputation - InfiltrationExpPow: 0.7, + InfiltrationExpPow: 0.8, //Stock market constants WSEAccountCost: 200e6, @@ -273,37 +273,20 @@ export let CONSTANTS: IMap = { LatestUpdate: ` - v0.45.1 - * Added two new Corporation Researches - * General UI improvements (by hydroflame and koriar) - * Bug Fix: Sleeve Netscript API should no longer cause Dynamic RAM errors - * Bug Fix: sleeve.getSleeveStats() should now work properly + v0.46.0 + * Added BitNode-9: Hacktocracy + * Changed BitNode-11's multipliers to make it slightly harder overall + * Source-File 11 is now slightly stronger + * Added several functions to Netscript Sleeve API for buying Sleeve augmentations (by hydroflame) + * Added a new stat for Duplicate Sleeves: Memory + * Increase baseline experience earned from Infiltration, but it now gives diminishing returns (on exp) as you get to higher difficulties/levels + * In Bladeburner, stamina gained from Hyperbolic Regeneration Chamber is now a percentage of your max stamina - v0.45.0 - * Corporation changes: - ** Decreased the time of a full market cycle from 15 seconds to 10 seconds. - ** This means that each Corporation 'state' will now only take 2 seconds, rather than 3 - ** Increased initial salaries for newly-hired employees - ** Increased the cost multiplier for upgrading office size (the cost will increase faster) - ** The stats of your employees now has a slightly larger effect on production & sales - ** Added several new Research upgrades - ** Market-TA research now allows you to automatically set sale price at optimal values - ** Market-TA research now works for Products (not just Materials) - ** Reduced the amount of Scientific Research needed to unlock the Hi-Tech R&D Laboratory from 10k to 5k - ** Energy Material requirement of the Software industry reduced from 1 to 0.5 - ** It is now slightly easier to increase the Software industry's production multiplier - ** Industries now have a maximum number of allowed products, starting at 3. This can be increased through research. - ** You can now see an approximation of how each material affects an industry's production multiplier by clicking the "?" help tip next to it - ** Significantly changed the effects of the different employee positions. See updated descriptions - ** Reduced the amount of money you gain from private investors - ** Training employees is now 3x more effective - ** Bug Fix: An industry's products are now properly separated between different cities - * The QLink Augemntation is now significantly stronger, but also significantly more expensive (by hydroflame) - * Added a Netscript API for Duplicate Sleeves (by hydroflame) - * Modified the multipliers of BitNode-3 and BitNode-8 to make them slightly harder - * After installing Augmentations, Duplicate Sleeves will now default to Synchronize if their Shock is 0 - * Bug Fix: Bladeburner's Hyperbolic Regeneration Chamber should no longer instantly refill all stamina - * Bug Fix: growthAnalyze() function now properly accounts for BitNode multipliers - * Bug Fix: The cost of purchasing Augmentations for Duplicate Sleeves no longer scales with how many Augs you've purchased for yourself + * Corporation Changes: + ** 'Demand' value of products decreases more slowly + ** Bug Fix: Fixed a Corporation issue that broke the Market-TA2 Research + + * Bug Fix: Money Statistics tracker was incorrectly recording profits when selling stocks manually + * Bug Fix: Fixed an issue with the job requirement tooltip for security jobs ` } diff --git a/src/Corporation/Corporation.jsx b/src/Corporation/Corporation.jsx index cb69bd9f5..f751e21c3 100644 --- a/src/Corporation/Corporation.jsx +++ b/src/Corporation/Corporation.jsx @@ -563,13 +563,15 @@ Industry.prototype.processMaterialMarket = function(marketCycles=1) { } } -//Process change in demand and competition for this industry's products +// Process change in demand and competition for this industry's products Industry.prototype.processProductMarket = function(marketCycles=1) { - //Demand gradually decreases, and competition gradually increases - for (var name in this.products) { + // Demand gradually decreases, and competition gradually increases + for (const name in this.products) { if (this.products.hasOwnProperty(name)) { - var product = this.products[name]; - var change = getRandomInt(1, 3) * 0.0004; + const product = this.products[name]; + let change = getRandomInt(0, 3) * 0.0004; + if (change === 0) { continue; } + if (this.type === Industries.Pharmaceutical || this.type === Industries.Software || this.type === Industries.Robotics) { change *= 3; @@ -770,7 +772,17 @@ Industry.prototype.processMaterials = function(marketCycles=1, company) { * advertisingFactor * this.getSalesMultiplier()); const denominator = Math.sqrt(sqrtNumerator / sqrtDenominator); - const optimalPrice = (numerator / denominator) + mat.bCost; + let optimalPrice; + if (sqrtDenominator === 0 || denominator === 0) { + if (sqrtNumerator === 0) { + optimalPrice = 0; // No production + } else { + optimalPrice = mat.bCost + markupLimit; + console.warn(`In Corporation, found illegal 0s when trying to calculate MarketTA2 sale cost`); + } + } else { + optimalPrice = (numerator / denominator) + mat.bCost; + } // We'll store this "Optimal Price" in a property so that we don't have // to re-calculate it for the UI @@ -1089,7 +1101,12 @@ Industry.prototype.processProduct = function(marketCycles=1, product, corporatio const denominator = Math.sqrt(sqrtNumerator / sqrtDenominator); let optimalPrice; if (sqrtDenominator === 0 || denominator === 0) { - optimalPrice = 0; + if (sqrtNumerator === 0) { + optimalPrice = 0; // No production + } else { + optimalPrice = product.pCost + markupLimit; + console.warn(`In Corporation, found illegal 0s when trying to calculate MarketTA2 sale cost`); + } } else { optimalPrice = (numerator / denominator) + product.pCost; } @@ -1251,7 +1268,7 @@ Industry.prototype.getAdvertisingFactors = function() { //Returns a multiplier based on a materials demand and competition that affects sales Industry.prototype.getMarketFactor = function(mat) { - return mat.dmd * (100 - mat.cmp)/100; + return Math.max(0.1, mat.dmd * (100 - mat.cmp) / 100); } // Returns a boolean indicating whether this Industry has the specified Research diff --git a/src/Corporation/Material.ts b/src/Corporation/Material.ts index 7ad8f4ae6..abf4bb86b 100644 --- a/src/Corporation/Material.ts +++ b/src/Corporation/Material.ts @@ -86,7 +86,7 @@ export class Material { this.mku = 6; break; case "Energy": - this.dmd = 90; this.dmdR = [80, 100]; + this.dmd = 90; this.dmdR = [80, 99]; this.cmp = 80; this.cmpR = [65, 95]; this.bCost = 2000; this.mv = 0.2; this.mku = 6; @@ -122,26 +122,26 @@ export class Material { this.mku = 2; break; case "Real Estate": - this.dmd = 50; this.dmdR = [5, 100]; + this.dmd = 50; this.dmdR = [5, 99]; this.cmp = 50; this.cmpR = [25, 75]; this.bCost = 80e3; this.mv = 1.5; //Less mv bc its processed twice this.mku = 1.5; break; case "Drugs": this.dmd = 60; this.dmdR = [45, 75]; - this.cmp = 70; this.cmpR = [40, 100]; + this.cmp = 70; this.cmpR = [40, 99]; this.bCost = 40e3; this.mv = 1.6; this.mku = 1; break; case "Robots": - this.dmd = 90; this.dmdR = [80, 100]; - this.cmp = 90; this.cmpR = [80, 100]; + this.dmd = 90; this.dmdR = [80, 9]; + this.cmp = 90; this.cmpR = [80, 9]; this.bCost = 75e3; this.mv = 0.5; //Less mv bc its processed twice this.mku = 1; break; case "AI Cores": - this.dmd = 90; this.dmdR = [80, 100]; - this.cmp = 90; this.cmpR = [80, 100]; + this.dmd = 90; this.dmdR = [80, 99]; + this.cmp = 90; this.cmpR = [80, 9]; this.bCost = 15e3; this.mv = 0.8; //Less mv bc its processed twice this.mku = 0.5; break; diff --git a/src/Corporation/ui/CorporationUIEventHandler.js b/src/Corporation/ui/CorporationUIEventHandler.js index 1f6edfb2a..46dfa16b3 100644 --- a/src/Corporation/ui/CorporationUIEventHandler.js +++ b/src/Corporation/ui/CorporationUIEventHandler.js @@ -780,7 +780,12 @@ export class CorporationEventHandler { useTa2AutoSaleDiv.appendChild(useTa2AutoSaleLabel); useTa2AutoSaleDiv.appendChild(useTa2AutoSaleCheckbox); - createPopup(popupId, [ta1, useTa1AutoSaleDiv, ta2Text, ta2Input, useTa2AutoSaleDiv, closeBtn]); + 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" + }); + + createPopup(popupId, [ta1, useTa1AutoSaleDiv, ta2Text, ta2Input, useTa2AutoSaleDiv, ta2OverridesTa1, closeBtn]); } else { // Market-TA.I only createPopup(popupId, [ta1, useTa1AutoSaleDiv, closeBtn]); @@ -1052,7 +1057,12 @@ export class CorporationEventHandler { useTa2AutoSaleDiv.appendChild(useTa2AutoSaleLabel); useTa2AutoSaleDiv.appendChild(useTa2AutoSaleCheckbox); - createPopup(popupId, [ta1, useTa1AutoSaleDiv, ta2Text, ta2Input, useTa2AutoSaleDiv, closeBtn]); + 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" + }); + + createPopup(popupId, [ta1, useTa1AutoSaleDiv, ta2Text, ta2Input, useTa2AutoSaleDiv, ta2OverridesTa1, closeBtn]); } else { // Market-TA.I only createPopup(popupId, [ta1, useTa1AutoSaleDiv, closeBtn]); diff --git a/src/Corporation/ui/IndustryOffice.jsx b/src/Corporation/ui/IndustryOffice.jsx index 7a0a3a743..40f8c0d1d 100644 --- a/src/Corporation/ui/IndustryOffice.jsx +++ b/src/Corporation/ui/IndustryOffice.jsx @@ -301,7 +301,7 @@ export class IndustryOffice extends BaseReactComponent {

    Avg Employee Morale: {numeralWrapper.format(avgMorale, "0.000")}

    Avg Employee Happiness: {numeralWrapper.format(avgHappiness, "0.000")}

    -

    Avg Energy Morale: {numeralWrapper.format(avgEnergy, "0.000")}

    +

    Avg Employee Energy: {numeralWrapper.format(avgEnergy, "0.000")}

    Total Employee Salary: {numeralWrapper.formatMoney(totalSalary)}

    { vechain && diff --git a/src/Corporation/ui/IndustryWarehouse.jsx b/src/Corporation/ui/IndustryWarehouse.jsx index acb02ebd8..f36f451e4 100644 --- a/src/Corporation/ui/IndustryWarehouse.jsx +++ b/src/Corporation/ui/IndustryWarehouse.jsx @@ -218,7 +218,7 @@ function MaterialComponent(props) { mat.buy === 0 && mat.imp === 0; // Purchase material button - const purchaseButtonText = `Buy (${numeralWrapper.format(mat.buy, nf)})`; + const purchaseButtonText = `Buy (${numeralWrapper.format(mat.buy, nfB)})`; const purchaseButtonClass = tutorial ? "std-button flashing-button tooltip" : "std-button"; const purchaseButtonOnClick = eventHandler.createPurchaseMaterialPopup.bind(eventHandler, mat, division, warehouse); @@ -229,9 +229,9 @@ function MaterialComponent(props) { let sellButtonText; if (mat.sllman[0]) { if (isString(mat.sllman[1])) { - sellButtonText = `Sell (${numeralWrapper.format(mat.sll, nf)}/${mat.sllman[1]})` + sellButtonText = `Sell (${numeralWrapper.format(mat.sll, nfB)}/${mat.sllman[1]})` } else { - sellButtonText = `Sell (${numeralWrapper.format(mat.sll, nf)}/${numeralWrapper.format(mat.sllman[1], nf)})`; + sellButtonText = `Sell (${numeralWrapper.format(mat.sll, nfB)}/${numeralWrapper.format(mat.sllman[1], nfB)})`; } if (mat.marketTa2) { @@ -469,7 +469,7 @@ export class IndustryWarehouse extends BaseReactComponent { return (

    - Storage: {numeralWrapper.format(warehouse.sizeUsed, "0.000")} / {numeralWrapper.format(warehouse.size, "0.000")} + Storage: {numeralWrapper.formatBigNumber(warehouse.sizeUsed)} / {numeralWrapper.formatBigNumber(warehouse.size)}

    diff --git a/src/Faction/FactionHelpers.js b/src/Faction/FactionHelpers.js index c061c359c..f73698b10 100644 --- a/src/Faction/FactionHelpers.js +++ b/src/Faction/FactionHelpers.js @@ -14,7 +14,7 @@ import { PurchaseAugmentationsOrderSetting } from "../Settings/SettingEnums"; import { Settings } from "../Settings/Settings"; import { SourceFileFlags } from "../SourceFile/SourceFileFlags"; -import { createPurchaseSleevesFromCovenantPopup } from "../PersonObjects/Sleeve/SleeveCovenantPurchases"; +import { createSleevePurchasesFromCovenantPopup } from "../PersonObjects/Sleeve/SleeveCovenantPurchases"; import {Page, routing} from "../ui/navigationTracking"; import {numeralWrapper} from "../ui/numeralFormat"; @@ -348,7 +348,7 @@ function displayFactionContent(factionName) { class: "std-button", innerText: "Purchase Duplicate Sleeves", clickListener: () => { - createPurchaseSleevesFromCovenantPopup(Player); + createSleevePurchasesFromCovenantPopup(Player); } })); covenantPurchaseSleevesDivWrapper.appendChild(createElement("p", { diff --git a/src/Hacknet/HacknetHelpers.jsx b/src/Hacknet/HacknetHelpers.jsx index 38246f75a..50d1e5ccd 100644 --- a/src/Hacknet/HacknetHelpers.jsx +++ b/src/Hacknet/HacknetHelpers.jsx @@ -19,7 +19,8 @@ import { generateRandomContractOnHome } from "../CodingContractGenerator import { iTutorialSteps, iTutorialNextStep, ITutorial} from "../InteractiveTutorial"; import { Player } from "../Player"; -import { AddToAllServers } from "../Server/AllServers"; +import { AddToAllServers, + AllServers } from "../Server/AllServers"; import { GetServerByHostname } from "../Server/ServerHelpers"; import { SourceFileFlags } from "../SourceFile/SourceFileFlags"; import { Page, routing } from "../ui/navigationTracking"; @@ -33,9 +34,10 @@ import { HacknetRoot } from "./ui/Root"; let hacknetNodesDiv; function hacknetNodesInit() { hacknetNodesDiv = document.getElementById("hacknet-nodes-container"); + document.removeEventListener("DOMContentLoaded", hacknetNodesInit); } -document.addEventListener("DOMContentLoaded", hacknetNodesInit, false); +document.addEventListener("DOMContentLoaded", hacknetNodesInit); // Returns a boolean indicating whether the player has Hacknet Servers // (the upgraded form of Hacknet Nodes) @@ -73,7 +75,7 @@ export function purchaseHacknet() { }); Player.loseMoney(cost); - Player.hacknetNodes.push(server); + Player.hacknetNodes.push(server.ip); // Configure the HacknetServer to actually act as a Server AddToAllServers(server); @@ -308,7 +310,8 @@ function processAllHacknetServerEarnings(numCycles) { let hashes = 0; for (let i = 0; i < Player.hacknetNodes.length; ++i) { - hashes += Player.hacknetNodes[i].process(numCycles); + const hserver = AllServers[Player.hacknetNodes[i]]; // hacknetNodes array only contains the IP addresses + hashes += hserver.process(numCycles); } Player.hashManager.storeHashes(hashes); @@ -316,16 +319,6 @@ function processAllHacknetServerEarnings(numCycles) { return hashes; } -export function getHacknetNode(name) { - for (var i = 0; i < Player.hacknetNodes.length; ++i) { - if (Player.hacknetNodes[i].name == name) { - return Player.hacknetNodes[i]; - } - } - - return null; -} - export function purchaseHashUpgrade(upgName, upgTarget) { if (!(Player.hashManager instanceof HashManager)) { console.error(`Player does not have a HashManager`); @@ -423,7 +416,6 @@ export function purchaseHashUpgrade(upgName, upgTarget) { return false; } - console.log("Hash Upgrade successfully purchased"); return true; } diff --git a/src/Hacknet/HacknetServer.ts b/src/Hacknet/HacknetServer.ts index 15022cd1b..af86618d9 100644 --- a/src/Hacknet/HacknetServer.ts +++ b/src/Hacknet/HacknetServer.ts @@ -20,7 +20,7 @@ import { Generic_fromJSON, export const HacknetServerHashesPerLevel: number = 0.001; // Constants for Hacknet Server purchase/upgrade costs -export const BaseCostForHacknetServer: number = 10e3; +export const BaseCostForHacknetServer: number = 50e3; export const BaseCostFor1GBHacknetServerRam: number = 200e3; export const BaseCostForHacknetServerCore: number = 1e6; export const BaseCostForHacknetServerCache: number = 10e6; @@ -37,7 +37,7 @@ export const MaxNumberHacknetServers: number = 25; // Max number of Hac export const HacknetServerMaxLevel: number = 300; export const HacknetServerMaxRam: number = 8192; export const HacknetServerMaxCores: number = 128; -export const HacknetServerMaxCache: number = 15; // Max cache level. So max capacity is 2 ^ 12 +export const HacknetServerMaxCache: number = 15; interface IConstructorParams { adminRights?: boolean; @@ -306,6 +306,7 @@ export class HacknetServer extends BaseServer implements IHacknetNode { this.maxRam *= 2; } this.maxRam = Math.round(this.maxRam); + this.updateHashRate(p); return true; } @@ -321,7 +322,7 @@ export class HacknetServer extends BaseServer implements IHacknetNode { } updateHashCapacity(): void { - this.hashCapacity = 16 * Math.pow(2, this.cache); + this.hashCapacity = 32 * Math.pow(2, this.cache); } updateHashRate(p: IPlayer): void { diff --git a/src/Hacknet/HashManager.ts b/src/Hacknet/HashManager.ts index 4aa9fa5f8..1f01e7c24 100644 --- a/src/Hacknet/HashManager.ts +++ b/src/Hacknet/HashManager.ts @@ -11,6 +11,7 @@ import { HashUpgrades } from "./HashUpgrades"; import { IMap } from "../types"; import { IPlayer } from "../PersonObjects/IPlayer"; +import { AllServers } from "../Server/AllServers"; import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver"; @@ -106,13 +107,29 @@ export class HashManager { } updateCapacity(p: IPlayer): void { - if (p.hacknetNodes.length <= 0) { this.capacity = 0; } - if (!(p.hacknetNodes[0] instanceof HacknetServer)) { this.capacity = 0; } + if (p.hacknetNodes.length <= 0) { + this.capacity = 0; + return; + } + + // Make sure the Player's `hacknetNodes` property actually holds Hacknet Servers + const ip: string = p.hacknetNodes[0]; + if (typeof ip !== "string") { + this.capacity = 0; + return; + } + + const hserver = AllServers[ip]; + if (!(hserver instanceof HacknetServer)) { + this.capacity = 0; + return; + } + let total: number = 0; for (let i = 0; i < p.hacknetNodes.length; ++i) { - const hacknetServer = (p.hacknetNodes[i]); - total += hacknetServer.hashCapacity; + const h = AllServers[p.hacknetNodes[i]]; + total += h.hashCapacity; } this.capacity = total; diff --git a/src/Hacknet/ui/Root.jsx b/src/Hacknet/ui/Root.jsx index 3e1a95633..32a9a0694 100644 --- a/src/Hacknet/ui/Root.jsx +++ b/src/Hacknet/ui/Root.jsx @@ -17,8 +17,10 @@ import { getCostOfNextHacknetNode, purchaseHacknet } from "../HacknetHelpers"; 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, @@ -52,7 +54,12 @@ export class HacknetRoot extends React.Component { let total = 0; for (let i = 0; i < Player.hacknetNodes.length; ++i) { if (hasHacknetServers()) { - total += Player.hacknetNodes[i].hashRate; + const hserver = AllServers[Player.hacknetNodes[i]]; + if (hserver) { + total += hserver.hashRate; + } else { + console.warn(`Could not find Hacknet Server object in AllServers map (i=${i})`) + } } else { total += Player.hacknetNodes[i].moneyGainRatePerSecond; } @@ -97,10 +104,14 @@ export class HacknetRoot extends React.Component { // HacknetNode components const nodes = Player.hacknetNodes.map((node) => { if (hasHacknetServers()) { + const hserver = AllServers[node]; + if (hserver == null) { + throw new Error(`Could not find Hacknet Server object in AllServers map for IP: ${node}`); + } return ( diff --git a/src/Infiltration.js b/src/Infiltration.js index d856d8252..8997c0f18 100644 --- a/src/Infiltration.js +++ b/src/Infiltration.js @@ -54,7 +54,7 @@ function InfiltrationInstance(companyName, startLevel, val, maxClearance, diff) InfiltrationInstance.prototype.expMultiplier = function() { if (!this.clearanceLevel || isNaN(this.clearanceLevel) || !this.maxClearanceLevel ||isNaN(this.maxClearanceLevel)) return 1; - return 2 * this.clearanceLevel / this.maxClearanceLevel; + return 2.5 * this.clearanceLevel / this.maxClearanceLevel; } InfiltrationInstance.prototype.gainHackingExp = function(amt) { @@ -64,7 +64,7 @@ InfiltrationInstance.prototype.gainHackingExp = function(amt) { InfiltrationInstance.prototype.calcGainedHackingExp = function() { if(!this.hackingExpGained || isNaN(this.hackingExpGained)) return 0; - return Math.pow(this.hackingExpGained*this.expMultiplier(), CONSTANTS.InfiltrationExpPow); + return Math.pow(this.hackingExpGained * this.expMultiplier(), CONSTANTS.InfiltrationExpPow); } InfiltrationInstance.prototype.gainStrengthExp = function(amt) { @@ -73,8 +73,8 @@ InfiltrationInstance.prototype.gainStrengthExp = function(amt) { } InfiltrationInstance.prototype.calcGainedStrengthExp = function() { - if(!this.strExpGained || isNaN(this.strExpGained)) return 0; - return Math.pow(this.strExpGained*this.expMultiplier(), CONSTANTS.InfiltrationExpPow); + if (!this.strExpGained || isNaN(this.strExpGained)) return 0; + return Math.pow(this.strExpGained * this.expMultiplier(), CONSTANTS.InfiltrationExpPow); } InfiltrationInstance.prototype.gainDefenseExp = function(amt) { @@ -83,8 +83,8 @@ InfiltrationInstance.prototype.gainDefenseExp = function(amt) { } InfiltrationInstance.prototype.calcGainedDefenseExp = function() { - if(!this.defExpGained || isNaN(this.defExpGained)) return 0; - return Math.pow(this.defExpGained*this.expMultiplier(), CONSTANTS.InfiltrationExpPow); + if (!this.defExpGained || isNaN(this.defExpGained)) return 0; + return Math.pow(this.defExpGained * this.expMultiplier(), CONSTANTS.InfiltrationExpPow); } InfiltrationInstance.prototype.gainDexterityExp = function(amt) { @@ -93,8 +93,8 @@ InfiltrationInstance.prototype.gainDexterityExp = function(amt) { } InfiltrationInstance.prototype.calcGainedDexterityExp = function() { - if(!this.dexExpGained || isNaN(this.dexExpGained)) return 0; - return Math.pow(this.dexExpGained*this.expMultiplier(), CONSTANTS.InfiltrationExpPow); + if (!this.dexExpGained || isNaN(this.dexExpGained)) return 0; + return Math.pow(this.dexExpGained * this.expMultiplier(), CONSTANTS.InfiltrationExpPow); } InfiltrationInstance.prototype.gainAgilityExp = function(amt) { @@ -103,8 +103,8 @@ InfiltrationInstance.prototype.gainAgilityExp = function(amt) { } InfiltrationInstance.prototype.calcGainedAgilityExp = function() { - if(!this.agiExpGained || isNaN(this.agiExpGained)) return 0; - return Math.pow(this.agiExpGained*this.expMultiplier(), CONSTANTS.InfiltrationExpPow); + if (!this.agiExpGained || isNaN(this.agiExpGained)) return 0; + return Math.pow(this.agiExpGained * this.expMultiplier(), CONSTANTS.InfiltrationExpPow); } InfiltrationInstance.prototype.gainCharismaExp = function(amt) { @@ -113,8 +113,8 @@ InfiltrationInstance.prototype.gainCharismaExp = function(amt) { } InfiltrationInstance.prototype.calcGainedCharismaExp = function() { - if(!this.chaExpGained || isNaN(this.chaExpGained)) return 0; - return Math.pow(this.chaExpGained*this.expMultiplier(), CONSTANTS.InfiltrationExpPow); + if (!this.chaExpGained || isNaN(this.chaExpGained)) return 0; + return Math.pow(this.chaExpGained * this.expMultiplier(), CONSTANTS.InfiltrationExpPow); } InfiltrationInstance.prototype.gainIntelligenceExp = function(amt) { diff --git a/src/Location.js b/src/Location.js index 33281738f..0e791d01f 100644 --- a/src/Location.js +++ b/src/Location.js @@ -327,7 +327,7 @@ function displayLocationContent() { setJobRequirementTooltip(loc, CompanyPositions[posNames.NetworkEngineerCompanyPositions[0]], networkEngineerJob); setJobRequirementTooltip(loc, CompanyPositions[posNames.BusinessCompanyPositions[0]], businessJob); setJobRequirementTooltip(loc, CompanyPositions[posNames.BusinessConsultantCompanyPositions[0]], businessConsultantJob); - setJobRequirementTooltip(loc, CompanyPositions[posNames.SecurityCompanyPositions[0]], securityJob); + setJobRequirementTooltip(loc, CompanyPositions[posNames.SecurityCompanyPositions[2]], securityJob); setJobRequirementTooltip(loc, CompanyPositions[posNames.AgentCompanyPositions[0]], agentJob); setJobRequirementTooltip(loc, CompanyPositions[posNames.MiscCompanyPositions[1]], employeeJob); setJobRequirementTooltip(loc, CompanyPositions[posNames.PartTimeCompanyPositions[1]], employeePartTimeJob); diff --git a/src/NetscriptEvaluator.js b/src/NetscriptEvaluator.js index 97e030ab4..6196d77bd 100644 --- a/src/NetscriptEvaluator.js +++ b/src/NetscriptEvaluator.js @@ -196,8 +196,11 @@ export function runScriptFromScript(server, scriptname, args, workerScript, thre } var runningScriptObj = new RunningScript(script, args); runningScriptObj.threads = threads; - server.runScript(runningScriptObj, Player); // Push onto runningScripts addWorkerScript(runningScriptObj, server); + + // Push onto runningScripts. + // This has to come after addWorkerScript() because that fn updates RAM usage + server.runScript(runningScriptObj, Player); return Promise.resolve(true); } } diff --git a/src/PersonObjects/IPlayer.ts b/src/PersonObjects/IPlayer.ts index c3406d3c7..1b5908b7f 100644 --- a/src/PersonObjects/IPlayer.ts +++ b/src/PersonObjects/IPlayer.ts @@ -24,7 +24,7 @@ export interface IPlayer { corporation: any; currentServer: string; factions: string[]; - hacknetNodes: (HacknetNode | HacknetServer)[]; + hacknetNodes: (HacknetNode | string)[]; // HacknetNode object or IP of Hacknet Server hasWseAccount: boolean; jobs: IMap; karma: number; diff --git a/src/PersonObjects/Sleeve/Sleeve.ts b/src/PersonObjects/Sleeve/Sleeve.ts index 60ea89487..331fc4c6c 100644 --- a/src/PersonObjects/Sleeve/Sleeve.ts +++ b/src/PersonObjects/Sleeve/Sleeve.ts @@ -114,10 +114,9 @@ export class Sleeve extends Person { logs: string[] = []; /** - * Clone retains memory% of exp upon prestige. If exp would be lower than previously - * kept exp, nothing happens + * Clone retains 'memory' synchronization (and maybe exp?) upon prestige/installing Augs */ - memory: number = 0; + memory: number = 1; /** * Sleeve shock. Number between 0 and 100 @@ -339,6 +338,31 @@ export class Sleeve extends Person { p.gainMoney(gain); } + /** + * Returns the cost of upgrading this sleeve's memory by a certain amount + */ + getMemoryUpgradeCost(n: number): number { + const amt = Math.round(n); + if (amt < 0) { + return 0; + } + + if (this.memory + amt > 100) { + return this.getMemoryUpgradeCost(100 - this.memory); + } + + const mult = 1.02; + const baseCost = 1e12; + let currCost = 0; + let currMemory = this.memory-1; + for (let i = 0; i < n; ++i) { + currCost += (Math.pow(mult, currMemory)); + ++currMemory; + } + + return currCost * baseCost; + } + /** * Gets reputation gain for the current task * Only applicable when working for company or faction @@ -408,6 +432,20 @@ export class Sleeve extends Person { } } + /** + * Called on every sleeve for a Source File prestige + */ + prestige(p: IPlayer) { + this.resetTaskStatus(); + this.earningsForSleeves = createTaskTracker(); + this.earningsForPlayer = createTaskTracker(); + this.logs = []; + this.shock = 1; + this.storedCycles = 0; + this.sync = Math.max(this.memory, 1); + this.shockRecovery(p); + } + /** * Process loop * Returns an object containing the amount of experience that should be @@ -818,6 +856,15 @@ export class Sleeve extends Person { return true; } + upgradeMemory(n: number): void { + if (n < 0) { + console.warn(`Sleeve.upgradeMemory() called with negative value: ${n}`); + return; + } + + this.memory = Math.min(100, Math.round(this.memory + n)); + } + /** * Serialize the current object to a JSON save state. */ @@ -830,7 +877,7 @@ export function findSleevePurchasableAugs(sleeve: Sleeve, p: IPlayer): Augmentat // You can only purchase Augmentations that are actually available from // your factions. I.e. you must be in a faction that has the Augmentation // and you must also have enough rep in that faction in order to purchase it. - + const ownedAugNames: string[] = sleeve.augmentations.map((e) => {return e.name}); const availableAugs: Augmentation[] = []; diff --git a/src/PersonObjects/Sleeve/SleeveCovenantPurchases.ts b/src/PersonObjects/Sleeve/SleeveCovenantPurchases.ts index 496641415..1ead77eeb 100644 --- a/src/PersonObjects/Sleeve/SleeveCovenantPurchases.ts +++ b/src/PersonObjects/Sleeve/SleeveCovenantPurchases.ts @@ -1,48 +1,18 @@ /** - * Implements the purchasing of extra Duplicate Sleeves from The Covenant + * Implements the purchasing of extra Duplicate Sleeves from The Covenant, + * as well as the purchasing of upgrades (memory) */ -import { Sleeve } from "./Sleeve"; import { IPlayer } from "../IPlayer"; -import { numeralWrapper } from "../../ui/numeralFormat"; - -import { dialogBoxCreate } from "../../../utils/DialogBox"; -import { yesNoBoxCreate, - yesNoBoxClose, - yesNoBoxGetYesButton, - yesNoBoxGetNoButton } from "../../../utils/YesNoBox"; +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 function createPurchaseSleevesFromCovenantPopup(p: IPlayer) { - if (p.sleevesFromCovenant >= MaxSleevesFromCovenant) { return; } - - // First sleeve purchased costs the base amount. Then, the price of - // each successive one increases by the same amount - const baseCostPerExtraSleeve: number = 10e12; - const cost: number = (p.sleevesFromCovenant + 1) * baseCostPerExtraSleeve; - - const yesBtn = yesNoBoxGetYesButton(); - const noBtn = yesNoBoxGetNoButton(); - - yesBtn!.addEventListener("click", () => { - if (p.canAfford(cost)) { - p.loseMoney(cost); - p.sleevesFromCovenant += 1; - p.sleeves.push(new Sleeve(p)); - yesNoBoxClose(); - } else { - dialogBoxCreate("You cannot afford to purchase a Duplicate Sleeve", false); - } - }); - - noBtn!.addEventListener("click", () => { - yesNoBoxClose(); - }); - - const txt = `Would you like to purchase an additional Duplicate Sleeve from The Covenant for ` + - `${numeralWrapper.formatMoney(cost)}?

    ` + - `These Duplicate Sleeves are permanent. You can purchase a total of 5 Duplicate ` + - `Sleeves from The Covenant`; - yesNoBoxCreate(txt); +export function createSleevePurchasesFromCovenantPopup(p: IPlayer) { + const removePopupFn = removePopup.bind(null, PopupId); + createPopup(PopupId, CovenantPurchasesRoot, { p: p, closeFn: removePopupFn }); } diff --git a/src/PersonObjects/Sleeve/SleeveUI.ts b/src/PersonObjects/Sleeve/SleeveUI.ts index e7daf6d55..86fd9af0a 100644 --- a/src/PersonObjects/Sleeve/SleeveUI.ts +++ b/src/PersonObjects/Sleeve/SleeveUI.ts @@ -383,7 +383,8 @@ function updateSleeveUi(sleeve: Sleeve, elems: ISleeveUIElems) { `HP: ${numeralWrapper.format(sleeve.hp, "0,0")} / ${numeralWrapper.format(sleeve.max_hp, "0,0")}`, `City: ${sleeve.city}`, `Shock: ${numeralWrapper.format(100 - sleeve.shock, "0,0.000")}`, - `Sync: ${numeralWrapper.format(sleeve.sync, "0,0.000")}`].join("
    "); + `Sync: ${numeralWrapper.format(sleeve.sync, "0,0.000")}`, + `Memory: ${numeralWrapper.format(sleeve.memory, "0")}`].join("
    "); let repGainText: string = ""; if (sleeve.currentTask === SleeveTaskType.Company || sleeve.currentTask === SleeveTaskType.Faction) { diff --git a/src/PersonObjects/Sleeve/data/SleeveFaq.ts b/src/PersonObjects/Sleeve/data/SleeveFaq.ts index 72d3a9f99..f05f4c506 100644 --- a/src/PersonObjects/Sleeve/data/SleeveFaq.ts +++ b/src/PersonObjects/Sleeve/data/SleeveFaq.ts @@ -45,5 +45,13 @@ export const SleeveFaq: string = "are not available for sleeves.

    ", "Do sleeves get reset when installing Augmentations or switching BitNodes?
    ", -"Sleeves are reset when switching BitNodes, but not when installing Augmentations." +"Sleeves are reset when switching BitNodes, but not when installing Augmentations.

    ", + +"What is Memory?
    ", +"Sleeve memory dictates what a sleeve's synchronization will be", +"when its reset by switching BitNodes. For example, if a sleeve has a memory of 25,", +"then when you switch BitNodes its synchronization will initially be set to 25, rather than 1.

    ", +"Memory can only be increased by purchasing upgrades from The Covenant. It is a", +"persistent stat, meaning it never gets resets back to 1. The maximum possible", +"value for a sleeve's memory is 100." ].join(" "); diff --git a/src/PersonObjects/Sleeve/ui/CovenantPurchasesRoot.tsx b/src/PersonObjects/Sleeve/ui/CovenantPurchasesRoot.tsx new file mode 100644 index 000000000..bed39a39a --- /dev/null +++ b/src/PersonObjects/Sleeve/ui/CovenantPurchasesRoot.tsx @@ -0,0 +1,112 @@ +/** + * Root React component for the popup that lets player purchase Duplicate + * Sleeves and Sleeve-related upgrades from The Covenant + */ +import * as React from "react"; + +import { CovenantSleeveUpgrades } from "./CovenantSleeveUpgrades"; + +import { Sleeve } from "../Sleeve"; +import { BaseCostPerSleeve, + MaxSleevesFromCovenant, + 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 { dialogBoxCreate } from "../../../../utils/DialogBox"; + +interface IProps { + closeFn: () => void; + p: IPlayer; + rerender: () => void; +} + +interface IState { + update: number; +} + +export class CovenantPurchasesRoot extends React.Component { + constructor(props: IProps) { + super(props); + + this.state = { + update: 0, + } + + this.rerender = this.rerender.bind(this); + } + + /** + * Get the cost to purchase a new Duplicate Sleeve + */ + purchaseCost(): number { + return (this.props.p.sleevesFromCovenant + 1) * BaseCostPerSleeve; + } + + /** + * Force a rerender by just changing an arbitrary state value + */ + rerender() { + this.setState((state: IState) => ({ + update: state.update + 1, + })); + } + + render() { + // Purchasing a new Duplicate Sleeve + let purchaseDisabled = false; + if (!this.props.p.canAfford(this.purchaseCost())) { + purchaseDisabled = true; + } + if (this.props.p.sleevesFromCovenant >= MaxSleevesFromCovenant) { + purchaseDisabled = true; + } + const purchaseOnClick = () => { + if (this.props.p.sleevesFromCovenant >= MaxSleevesFromCovenant) { return; } + + if (this.props.p.canAfford(this.purchaseCost())) { + this.props.p.loseMoney(this.purchaseCost()); + this.props.p.sleevesFromCovenant += 1; + this.props.p.sleeves.push(new Sleeve(this.props.p)); + this.rerender(); + } else { + dialogBoxCreate(`You cannot afford to purchase a Duplicate Sleeve`, false); + } + } + + // Purchasing Upgrades for Sleeves + const upgradePanels = []; + for (let i = 0; i < this.props.p.sleeves.length; ++i) { + const sleeve = this.props.p.sleeves[i]; + upgradePanels.push( + + ) + } + + return ( +
    + +

    + Would you like to purchase an additional Duplicate Sleeve from The Covenant + for {numeralWrapper.formatMoney(this.purchaseCost())}? +

    +
    +

    + These Duplicate Sleeves are permanent (they persist through BitNodes). You can + purchase a total of {MaxSleevesFromCovenant} from The Covenant. +

    + +

    +

    + Here, you can also purchase upgrades for your Duplicate Sleeves. These upgrades + are also permanent, meaning they persist across BitNodes. +

    + {upgradePanels} +
    + ) + } +} diff --git a/src/PersonObjects/Sleeve/ui/CovenantSleeveMemoryUpgrade.tsx b/src/PersonObjects/Sleeve/ui/CovenantSleeveMemoryUpgrade.tsx new file mode 100644 index 000000000..f2b5ccd57 --- /dev/null +++ b/src/PersonObjects/Sleeve/ui/CovenantSleeveMemoryUpgrade.tsx @@ -0,0 +1,97 @@ +/** + * React component for a panel that lets you purchase upgrades for a Duplicate + * Sleeve's Memory (through The Covenant) + */ +import * as React from "react"; + +import { Sleeve } from "../Sleeve"; +import { IPlayer } from "../../IPlayer"; + +import { numeralWrapper } from "../../../ui/numeralFormat"; +import { StdButton } from "../../../ui/React/StdButton"; + +interface IProps { + index: number; + p: IPlayer; + rerender: () => void; + sleeve: Sleeve; +} + +interface IState { + amt: number; +} + +export class CovenantSleeveMemoryUpgrade extends React.Component { + constructor(props: IProps) { + super(props); + + this.state = { + amt: 1, + } + + this.changePurchaseAmount = this.changePurchaseAmount.bind(this); + this.purchaseMemory = this.purchaseMemory.bind(this); + } + + changePurchaseAmount(e: React.ChangeEvent): void { + const n: number = parseInt(e.target.value); + + this.setState({ + amt: n, + }); + } + + getPurchaseCost(): number { + if (isNaN(this.state.amt)) { return Infinity; } + + const maxMemory = 100 - this.props.sleeve.memory; + if (this.state.amt > maxMemory) { return Infinity; } + + return this.props.sleeve.getMemoryUpgradeCost(this.state.amt); + } + + purchaseMemory(): void { + const cost = this.getPurchaseCost(); + if (this.props.p.canAfford(cost)) { + this.props.sleeve.upgradeMemory(this.state.amt); + this.props.p.loseMoney(cost); + this.props.rerender(); + } + } + + render() { + const inputId = `sleeve-${this.props.index}-memory-upgrade-input`; + + // Memory cannot go above 100 + const maxMemory = 100 - this.props.sleeve.memory; + + // Purchase button props + const cost = this.getPurchaseCost(); + const purchaseBtnDisabled = !this.props.p.canAfford(cost); + let purchaseBtnText; + if (this.state.amt > maxMemory) { + purchaseBtnText = `Memory cannot exceed 100`; + } else if (isNaN(this.state.amt)) { + purchaseBtnText = "Invalid value"; + } else { + purchaseBtnText = `Purchase ${this.state.amt} memory - ${numeralWrapper.formatMoney(cost)}`; + } + + return ( +
    +

    Upgrade Memory

    +

    + Purchase a memory upgrade for your sleeve. Note that a sleeve's max memory + is 100 (current: {numeralWrapper.format(this.props.sleeve.memory, "0")}) +

    + + + +
    + +
    + ) + } +} diff --git a/src/PersonObjects/Sleeve/ui/CovenantSleeveUpgrades.tsx b/src/PersonObjects/Sleeve/ui/CovenantSleeveUpgrades.tsx new file mode 100644 index 000000000..317d9a1a8 --- /dev/null +++ b/src/PersonObjects/Sleeve/ui/CovenantSleeveUpgrades.tsx @@ -0,0 +1,28 @@ +/** + * React Component for a panel that lets you purchase upgrades for a single + * Duplicate Sleeve through The Covenant + */ +import * as React from "react"; + +import { CovenantSleeveMemoryUpgrade } from "./CovenantSleeveMemoryUpgrade"; + +import { Sleeve } from "../Sleeve"; +import { IPlayer } from "../../IPlayer"; + +interface IProps { + index: number; + p: IPlayer; + rerender: () => void; + sleeve: Sleeve; +} + +export class CovenantSleeveUpgrades extends React.Component { + render() { + return ( +
    +

    Duplicate Sleeve {this.props.index}

    + +
    + ) + } +} diff --git a/src/Player.js b/src/Player.js index c7ee6502e..a42e021fc 100644 --- a/src/Player.js +++ b/src/Player.js @@ -21,6 +21,7 @@ import { Faction } from "./Faction/Faction"; import { Factions } from "./Faction/Factions"; import { displayFactionContent } from "./Faction/FactionHelpers"; import {Gang, resetGangs} from "./Gang"; +import { hasHacknetServers } from "./Hacknet/HacknetHelpers"; import { HashManager } from "./Hacknet/HashManager"; import {Locations} from "./Locations"; import {hasBn11SF, hasWallStreetSF,hasAISF} from "./NetscriptFunctions"; @@ -117,7 +118,7 @@ function PlayerObject() { this.purchasedServers = []; //IP Addresses of purchased servers // Hacknet Nodes/Servers - this.hacknetNodes = []; + this.hacknetNodes = []; // Note: For Hacknet Servers, this array holds the IP addresses of the servers this.hashManager = new HashManager(); //Factions @@ -288,7 +289,7 @@ PlayerObject.prototype.prestigeAugmentation = function() { for (let i = 0; i < this.sleeves.length; ++i) { if (this.sleeves[i] instanceof Sleeve) { if (this.sleeves[i].shock >= 100) { - this.sleeves[i].synchronize(this); + this.sleeves[i].synchronize(this); } else { this.sleeves[i].shockRecovery(this); } @@ -382,7 +383,11 @@ PlayerObject.prototype.prestigeSourceFile = function() { // Duplicate sleeves are reset to level 1 every Bit Node (but the number of sleeves you have persists) this.sleeves.length = SourceFileFlags[10] + this.sleevesFromCovenant; for (let i = 0; i < this.sleeves.length; ++i) { - this.sleeves[i] = new Sleeve(this); + if (this.sleeves[i] instanceof Sleeve) { + this.sleeves[i].prestige(this); + } else { + this.sleeves[i] = new Sleeve(this); + } } this.isWorking = false; @@ -2333,10 +2338,19 @@ PlayerObject.prototype.checkForFactionInvitations = function() { var totalHacknetRam = 0; var totalHacknetCores = 0; var totalHacknetLevels = 0; - for (var i = 0; i < this.hacknetNodes.length; ++i) { - totalHacknetLevels += this.hacknetNodes[i].level; - totalHacknetRam += this.hacknetNodes[i].ram; - totalHacknetCores += this.hacknetNodes[i].cores; + for (let i = 0; i < this.hacknetNodes.length; ++i) { + if (hasHacknetServers()) { + const hserver = AllServers[this.hacknetNodes[i]]; + if (hserver) { + totalHacknetLevels += hserver.level; + totalHacknetRam += hserver.maxRam; + totalHacknetCores += hserver.cores; + } + } else { + totalHacknetLevels += this.hacknetNodes[i].level; + totalHacknetRam += this.hacknetNodes[i].ram; + totalHacknetCores += this.hacknetNodes[i].cores; + } } if (!netburnersFac.isBanned && !netburnersFac.isMember && !netburnersFac.alreadyInvited && this.hacking_skill >= 80 && totalHacknetRam >= 8 && diff --git a/src/Server/AllServers.ts b/src/Server/AllServers.ts index 6d8d91c0b..392215953 100644 --- a/src/Server/AllServers.ts +++ b/src/Server/AllServers.ts @@ -2,6 +2,8 @@ import { Server } from "./Server"; import { SpecialServerIps } from "./SpecialServerIps"; import { serverMetadata } from "./data/servers"; +import { HacknetServer } from "../Hacknet/HacknetServer"; + import { IMap } from "../types"; import { createRandomIp, ipExists } from "../../utils/IPAddress"; @@ -11,7 +13,7 @@ import { Reviver } from "../../utils/JSONReviver"; // Map of all Servers that exist in the game // Key (string) = IP // Value = Server object -export let AllServers: IMap = {}; +export let AllServers: IMap = {}; // Saftely add a Server to the AllServers map export function AddToAllServers(server: Server): void { diff --git a/src/Server/ServerHelpers.ts b/src/Server/ServerHelpers.ts index cd173fd03..e6ad5df67 100644 --- a/src/Server/ServerHelpers.ts +++ b/src/Server/ServerHelpers.ts @@ -3,6 +3,7 @@ import { Server } from "./Server"; import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; import { CONSTANTS } from "../Constants"; +import { HacknetServer } from "../Hacknet/HacknetServer"; import { IPlayer } from "../PersonObjects/IPlayer"; import { Programs } from "../Programs/Programs"; @@ -89,7 +90,7 @@ export function prestigeHomeComputer(homeComp: Server) { //Returns server object with corresponding hostname // Relatively slow, would rather not use this a lot -export function GetServerByHostname(hostname: string): Server | null { +export function GetServerByHostname(hostname: string): Server | HacknetServer | null { for (var ip in AllServers) { if (AllServers.hasOwnProperty(ip)) { if (AllServers[ip].hostname == hostname) { @@ -102,7 +103,7 @@ export function GetServerByHostname(hostname: string): Server | null { } //Get server by IP or hostname. Returns null if invalid -export function getServer(s: string): Server | null { +export function getServer(s: string): Server | HacknetServer | null { if (!isValidIPAddress(s)) { return GetServerByHostname(s); } diff --git a/src/SourceFile.js b/src/SourceFile.js index 05f66ed84..63a9f0a02 100644 --- a/src/SourceFile.js +++ b/src/SourceFile.js @@ -68,9 +68,9 @@ function initSourceFiles() { SourceFiles["SourceFile11"] = new SourceFile(11, "This Source-File makes it so that company favor increases BOTH the player's salary and reputation gain rate " + "at that company by 1% per favor (rather than just the reputation gain). This Source-File also " + " increases the player's company salary and reputation gain multipliers by:

    " + - "Level 1: 24%
    " + - "Level 2: 36%
    " + - "Level 3: 42%
    "); + "Level 1: 32%
    " + + "Level 2: 48%
    " + + "Level 3: 56%
    "); SourceFiles["SourceFile12"] = new SourceFile(12, "This Source-File increases all your multipliers by 1% per level. This effect is multiplicative with itself. " + "In other words, level N of this Source-File will result in a multiplier of 1.01^N (or 0.99^N for multipliers that decrease)"); } @@ -194,7 +194,7 @@ function applySourceFile(srcFile) { case 11: //The Big Crash var mult = 0; for (var i = 0; i < srcFile.lvl; ++i) { - mult += (24 / (Math.pow(2, i))); + mult += (32 / (Math.pow(2, i))); } var incMult = 1 + (mult / 100); Player.work_money_mult *= incMult; diff --git a/src/StockMarket/StockMarket.js b/src/StockMarket/StockMarket.js index 7e7d62091..ee3a5edfe 100644 --- a/src/StockMarket/StockMarket.js +++ b/src/StockMarket/StockMarket.js @@ -462,9 +462,10 @@ function sellStock(stock, shares) { shares = Math.round(shares); if (shares > stock.playerShares) {shares = stock.playerShares;} if (shares === 0) {return false;} - var gains = stock.price * shares - CONSTANTS.StockMarketCommission; + const gains = stock.price * shares - CONSTANTS.StockMarketCommission; + const netProfit = ((stock.price - stock.playerAvgPx) * shares) - CONSTANTS.StockMarketCommission; Player.gainMoney(gains); - Player.recordMoneySource(gains, "stock"); + Player.recordMoneySource(netProfit, "stock"); stock.playerShares = Math.round(stock.playerShares - shares); if (stock.playerShares == 0) { stock.playerAvgPx = 0; diff --git a/src/Terminal.js b/src/Terminal.js index 08595bc5a..e41bb5125 100644 --- a/src/Terminal.js +++ b/src/Terminal.js @@ -1861,17 +1861,20 @@ let Terminal = { visited[ip] = 0; } - var stack = []; - var depthQueue = [0]; - var currServ = Player.getCurrentServer(); + const stack = []; + const depthQueue = [0]; + const currServ = Player.getCurrentServer(); stack.push(currServ); while(stack.length != 0) { - var s = stack.pop(); - var d = depthQueue.pop(); + const s = stack.pop(); + const d = depthQueue.pop(); + const isHacknet = s instanceof HacknetServer; if (!all && s.purchasedByPlayer && s.hostname != "home") { - continue; //Purchased server + continue; // Purchased server } else if (visited[s.ip] || d > depth) { - continue; //Already visited or out-of-depth + continue; // Already visited or out-of-depth + } else if (!all && isHacknet) { + continue; // Hacknet Server } else { visited[s.ip] = 1; } @@ -1891,8 +1894,8 @@ let Terminal = { //var dashes = Array(d * 2 + 1).join("-"); var c = "NO"; if (s.hasAdminRights) {c = "YES";} - post(dashes + "Root Access: " + c + ", Required hacking skill: " + s.requiredHackingSkill); - post(dashes + "Number of open ports required to NUKE: " + s.numOpenPortsRequired); + post(`${dashes}Root Access: ${c} ${!isHacknet ? ", Required hacking skill: " + s.requiredHackingSkill : ""}`); + if (!isHacknet) { post(dashes + "Number of open ports required to NUKE: " + s.numOpenPortsRequired); } post(dashes + "RAM: " + s.maxRam); post(" "); } @@ -2242,9 +2245,12 @@ let Terminal = { post("May take a few seconds to start up the process..."); var runningScriptObj = new RunningScript(script, args); runningScriptObj.threads = numThreads; - server.runScript(runningScriptObj, Player); addWorkerScript(runningScriptObj, server); + + // This has to come after addWorkerScript() because that fn + // updates the RAM usage. This kinda sucks, address if possible + server.runScript(runningScriptObj, Player); return; } } diff --git a/src/ui/React/Popup.tsx b/src/ui/React/Popup.tsx new file mode 100644 index 000000000..2d84ad684 --- /dev/null +++ b/src/ui/React/Popup.tsx @@ -0,0 +1,24 @@ +/** + * React component for a popup content container + * + * Takes in a prop for rendering the content inside the popup + */ +import * as React from "react"; + +type ReactComponent = new(...args: any[]) => React.Component + +interface IProps { + content: ReactComponent; + id: string; + props: object; +} + +export class Popup extends React.Component { + render() { + return ( +
    + {React.createElement(this.props.content, this.props.props)} +
    + ) + } +} diff --git a/src/ui/React/PopupCloseButton.tsx b/src/ui/React/PopupCloseButton.tsx index 7749db4f2..dfd581926 100644 --- a/src/ui/React/PopupCloseButton.tsx +++ b/src/ui/React/PopupCloseButton.tsx @@ -9,6 +9,7 @@ import * as React from "react"; import * as ReactDOM from "react-dom"; import { KEY } from "../../../utils/helpers/keyCodes"; +import { removeElement } from "../../../utils/uiHelpers/removeElement"; export interface IPopupCloseButtonProps { class?: string; @@ -43,7 +44,8 @@ export class PopupCloseButton extends React.Component - {this.props.text}; + {this.props.text} ) } diff --git a/src/ui/React/StdButton.tsx b/src/ui/React/StdButton.tsx index 21f8ab180..592395c3e 100644 --- a/src/ui/React/StdButton.tsx +++ b/src/ui/React/StdButton.tsx @@ -17,7 +17,7 @@ export class StdButton extends React.Component { return ( ) } diff --git a/src/ui/React/createPopup.ts b/src/ui/React/createPopup.tsx similarity index 56% rename from src/ui/React/createPopup.ts rename to src/ui/React/createPopup.tsx index 2974549fb..3f9bb5e25 100644 --- a/src/ui/React/createPopup.ts +++ b/src/ui/React/createPopup.tsx @@ -4,41 +4,45 @@ * Calling this function with the same ID and React Root Component will trigger a re-render * * @param id The (hopefully) unique identifier for the popup container - * @param rootComponent Root React Component + * @param rootComponent Root React Component for the content (NOT the popup containers themselves) */ import * as React from "react"; import * as ReactDOM from "react-dom"; +import { Popup } from "./Popup"; + import { createElement } from "../../../utils/uiHelpers/createElement"; import { removeElementById } from "../../../utils/uiHelpers/removeElementById"; type ReactComponent = new(...args: any[]) => React.Component; -export function createPopup(id: string, rootComponent: ReactComponent, props: object): HTMLElement { +let gameContainer: HTMLElement; + +function getGameContainer() { + let container = document.getElementById("entire-game-container"); + if (container == null) { + throw new Error(`Failed to find game container DOM element`) + } + + gameContainer = container; + document.removeEventListener("DOMContentLoaded", getGameContainer); +} + +document.addEventListener("DOMContentLoaded", getGameContainer); + +export function createPopup(id: string, rootComponent: ReactComponent, props: object): HTMLElement | null { let container = document.getElementById(id); - let content = document.getElementById(`${id}-content`); - if (container == null || content == null) { + if (container == null) { container = createElement("div", { class: "popup-box-container", display: "flex", id: id, }); - content = createElement("div", { - class: "popup-box-content", - id: `${id}-content`, - }); - - container.appendChild(content); - - try { - document.getElementById("entire-game-container")!.appendChild(container); - } catch(e) { - console.error(`Exception caught when creating popup: ${e}`); - } + gameContainer.appendChild(container); } - ReactDOM.render(React.createElement(rootComponent, props), content); + ReactDOM.render(, container); return container; } @@ -47,7 +51,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}-content`); + let content = document.getElementById(`${id}`); if (content == null) { return; } ReactDOM.unmountComponentAtNode(content); From 5592a8bc96d5ec06f2edc40c1cbb8edbf48c3e9f Mon Sep 17 00:00:00 2001 From: danielyxie Date: Wed, 27 Mar 2019 01:53:30 -0700 Subject: [PATCH 08/17] Updated several packages --- package-lock.json | 1090 +++++++++++++++++++++++++--------------- package.json | 6 +- src/BitNode/BitNode.ts | 1 + 3 files changed, 690 insertions(+), 407 deletions(-) diff --git a/package-lock.json b/package-lock.json index eeacddaa7..3df2e1b47 100644 --- a/package-lock.json +++ b/package-lock.json @@ -718,6 +718,12 @@ "json-schema-traverse": "0.3.1" } }, + "ajv-errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", + "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", + "dev": true + }, "ajv-keywords": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", @@ -746,6 +752,12 @@ "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", "dev": true }, + "ansi-colors": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", + "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", + "dev": true + }, "ansi-escapes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.0.0.tgz", @@ -828,21 +840,11 @@ "dev": true }, "array-flatten": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.1.tgz", - "integrity": "sha1-Qmu52oQJDBg42BLIFQryCoMx4pY=", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", + "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", "dev": true }, - "array-includes": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", - "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", - "dev": true, - "requires": { - "define-properties": "1.1.2", - "es-abstract": "1.12.0" - } - }, "array-iterate": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/array-iterate/-/array-iterate-1.1.2.tgz", @@ -876,6 +878,13 @@ "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", "dev": true }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", + "dev": true, + "optional": true + }, "asn1.js": { "version": "4.10.1", "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", @@ -988,13 +997,6 @@ "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", "dev": true }, - "aws4": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", - "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=", - "dev": true, - "optional": true - }, "babel-code-frame": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", @@ -1211,9 +1213,9 @@ "dev": true }, "body-parser": { - "version": "1.18.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", - "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", + "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", "dev": true, "requires": { "bytes": "3.0.0", @@ -1221,10 +1223,10 @@ "debug": "2.6.9", "depd": "1.1.2", "http-errors": "1.6.3", - "iconv-lite": "0.4.19", + "iconv-lite": "0.4.23", "on-finished": "2.3.0", - "qs": "6.5.1", - "raw-body": "2.3.2", + "qs": "6.5.2", + "raw-body": "2.3.3", "type-is": "1.6.16" }, "dependencies": { @@ -1236,6 +1238,15 @@ "requires": { "ms": "2.0.0" } + }, + "iconv-lite": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "dev": true, + "requires": { + "safer-buffer": "2.1.2" + } } } }, @@ -1245,7 +1256,7 @@ "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", "dev": true, "requires": { - "array-flatten": "2.1.1", + "array-flatten": "2.1.2", "deep-equal": "1.0.1", "dns-equal": "1.0.0", "dns-txt": "2.0.2", @@ -2376,34 +2387,34 @@ "dev": true }, "compressible": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.14.tgz", - "integrity": "sha1-MmxfUH+7BV9UEWeCuWmoG2einac=", + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.16.tgz", + "integrity": "sha512-JQfEOdnI7dASwCuSPWIeVYwc/zMsu/+tRhoUvEfXz2gxOA2DNjmG5vhtFdBlhWPPGo+RdT9S3tgc/uH5qgDiiA==", "dev": true, "requires": { - "mime-db": "1.34.0" + "mime-db": "1.38.0" }, "dependencies": { "mime-db": { - "version": "1.34.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.34.0.tgz", - "integrity": "sha1-RS0Oz/XDA0am3B5kseruDTcZ/5o=", + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz", + "integrity": "sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==", "dev": true } } }, "compression": { - "version": "1.7.2", - "resolved": "http://registry.npmjs.org/compression/-/compression-1.7.2.tgz", - "integrity": "sha1-qv+81qr4VLROuygDU9WtFlH1mmk=", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", "dev": true, "requires": { "accepts": "1.3.5", "bytes": "3.0.0", - "compressible": "2.0.14", + "compressible": "2.0.16", "debug": "2.6.9", - "on-headers": "1.0.1", - "safe-buffer": "5.1.1", + "on-headers": "1.0.2", + "safe-buffer": "5.1.2", "vary": "1.1.2" }, "dependencies": { @@ -2415,6 +2426,12 @@ "requires": { "ms": "2.0.0" } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true } } }, @@ -2445,9 +2462,9 @@ } }, "connect-history-api-fallback": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz", - "integrity": "sha1-sGhzk0vF40T+9hGhlqb6rgruAVo=", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", + "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", "dev": true }, "console-browserify": { @@ -2873,6 +2890,65 @@ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" }, + "default-gateway": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", + "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==", + "dev": true, + "requires": { + "execa": "1.0.0", + "ip-regex": "2.1.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "1.0.4", + "path-key": "2.0.1", + "semver": "5.5.0", + "shebang-command": "1.2.0", + "which": "1.3.0" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "6.0.5", + "get-stream": "4.1.0", + "is-stream": "1.1.0", + "npm-run-path": "2.0.2", + "p-finally": "1.0.0", + "signal-exit": "3.0.2", + "strip-eof": "1.0.0" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "3.0.0" + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "1.4.1", + "once": "1.4.0" + } + } + } + }, "define-properties": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", @@ -2957,9 +3033,9 @@ "dev": true }, "detect-node": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.3.tgz", - "integrity": "sha1-ogM8CcyOFY03dI+951B4Mr1s4Sc=", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", + "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==", "dev": true }, "diff": { @@ -3631,12 +3707,12 @@ "dev": true }, "eventsource": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-0.1.6.tgz", - "integrity": "sha1-Cs7ehJ7X3RzMMsgRuxG5RNTykjI=", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz", + "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==", "dev": true, "requires": { - "original": "1.0.1" + "original": "1.0.2" } }, "evp_bytestokey": { @@ -3822,14 +3898,14 @@ } }, "express": { - "version": "4.16.3", - "resolved": "https://registry.npmjs.org/express/-/express-4.16.3.tgz", - "integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=", + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz", + "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==", "dev": true, "requires": { "accepts": "1.3.5", "array-flatten": "1.1.1", - "body-parser": "1.18.2", + "body-parser": "1.18.3", "content-disposition": "0.5.2", "content-type": "1.0.4", "cookie": "0.3.1", @@ -3846,10 +3922,10 @@ "on-finished": "2.3.0", "parseurl": "1.3.2", "path-to-regexp": "0.1.7", - "proxy-addr": "2.0.3", - "qs": "6.5.1", + "proxy-addr": "2.0.4", + "qs": "6.5.2", "range-parser": "1.2.0", - "safe-buffer": "5.1.1", + "safe-buffer": "5.1.2", "send": "0.16.2", "serve-static": "1.13.2", "setprototypeof": "1.1.0", @@ -3879,6 +3955,12 @@ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", "dev": true + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true } } }, @@ -4170,12 +4252,29 @@ } }, "follow-redirects": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.0.tgz", - "integrity": "sha512-fdrt472/9qQ6Kgjvb935ig6vJCuofpBUD14f9Vb+SLlm7xIe4Qva5gey8EKtv8lp7ahE1wilg3xL1znpVGtZIA==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.7.0.tgz", + "integrity": "sha512-m/pZQy4Gj287eNy94nivy5wchN3Kp+Q5WgUPNy5lJSZ3sgkVKSYV/ZChMAQVIgx1SqfZ2zBZtPA2YlXIWxxJOQ==", "dev": true, "requires": { - "debug": "3.1.0" + "debug": "3.2.6" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "2.1.1" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } } }, "for-in": { @@ -4562,9 +4661,9 @@ "dev": true }, "handle-thing": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-1.2.5.tgz", - "integrity": "sha1-/Xqtcmvxpf0W38KbL3pmAdJxOcQ=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.0.tgz", + "integrity": "sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ==", "dev": true }, "handlebars": { @@ -4914,9 +5013,9 @@ } }, "http-parser-js": { - "version": "0.4.13", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.13.tgz", - "integrity": "sha1-O9bW/ebjFyyTNMOzO2wZPYD+ETc=", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.0.tgz", + "integrity": "sha512-cZdEF7r4gfRIq7ezX9J0T+kQmJNOub71dWbgAXVHDct80TKP4MCETtZQ31xyv38UwgzkWPYF/Xc0ge55dW9Z9w==", "dev": true }, "http-proxy": { @@ -4926,20 +5025,28 @@ "dev": true, "requires": { "eventemitter3": "3.1.0", - "follow-redirects": "1.5.0", + "follow-redirects": "1.7.0", "requires-port": "1.0.0" } }, "http-proxy-middleware": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.18.0.tgz", - "integrity": "sha512-Fs25KVMPAIIcgjMZkVHJoKg9VcXcC1C8yb9JUgeDvVXY0S/zgVIhMb+qVswDIgtJe2DfckMSY2d6TuTEutlk6Q==", + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", + "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", "dev": true, "requires": { "http-proxy": "1.17.0", "is-glob": "4.0.0", - "lodash": "4.17.10", + "lodash": "4.17.11", "micromatch": "3.1.10" + }, + "dependencies": { + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + } } }, "http-signature": { @@ -5199,12 +5306,21 @@ } }, "internal-ip": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-1.2.0.tgz", - "integrity": "sha1-rp+/k7mEh4eF1QqN4bNWlWBYz1w=", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.2.0.tgz", + "integrity": "sha512-ZY8Rk+hlvFeuMmG5uH1MXhhdeMntmIaxaInvAmzMq/SHV8rv4Kh+6GiQNNDQd0wZFrcO+FiTBo8lui/osKOyJw==", "dev": true, "requires": { - "meow": "3.7.0" + "default-gateway": "4.2.0", + "ipaddr.js": "1.9.0" + }, + "dependencies": { + "ipaddr.js": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", + "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==", + "dev": true + } } }, "interpret": { @@ -5224,10 +5340,16 @@ "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", "dev": true }, + "ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "dev": true + }, "ipaddr.js": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.6.0.tgz", - "integrity": "sha1-4/o1e3c9phnybpXwSdBVxyeW+Gs=", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz", + "integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4=", "dev": true }, "is-absolute-url": { @@ -5992,9 +6114,9 @@ } }, "killable": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.0.tgz", - "integrity": "sha1-2ouEvUfeU5WHj5XWTQLyRJ/gXms=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", + "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==", "dev": true }, "kind-of": { @@ -6035,205 +6157,34 @@ "dev": true }, "less": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/less/-/less-3.0.4.tgz", - "integrity": "sha512-q3SyEnPKbk9zh4l36PGeW2fgynKu+FpbhiUNx/yaiBUQ3V0CbACCgb9FzYWcRgI2DJlP6eI4jc8XPrCTi55YcQ==", + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/less/-/less-3.9.0.tgz", + "integrity": "sha512-31CmtPEZraNUtuUREYjSqRkeETFdyEHSEPAGq4erDlUXtda7pzNmctdljdIagSb589d/qXGWiiP31R5JVf+v0w==", "dev": true, "requires": { + "clone": "2.1.2", "errno": "0.1.7", "graceful-fs": "4.1.11", "image-size": "0.5.5", - "mime": "1.6.0", + "mime": "1.4.1", "mkdirp": "0.5.1", "promise": "7.3.1", - "request": "2.87.0", + "request": "2.88.0", "source-map": "0.6.1" }, "dependencies": { - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", - "dev": true, - "optional": true - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true, - "optional": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true, - "optional": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true, - "optional": true - }, - "combined-stream": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", - "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", - "dev": true, - "requires": { - "delayed-stream": "1.0.0" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", "dev": true }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true, - "optional": true - }, - "form-data": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", - "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", - "dev": true, - "optional": true, - "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.6", - "mime-types": "2.1.18" - } - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true, - "optional": true - }, - "har-validator": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", - "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", - "dev": true, - "optional": true, - "requires": { - "ajv": "5.5.2", - "har-schema": "2.0.0" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, - "optional": true, - "requires": { - "assert-plus": "1.0.0", - "jsprim": "1.4.1", - "sshpk": "1.13.1" - } - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true, - "optional": true - }, - "mime-types": { - "version": "2.1.18", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", - "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", - "dev": true, - "requires": { - "mime-db": "1.33.0" - } - }, - "oauth-sign": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", - "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", - "dev": true, - "optional": true - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true, - "optional": true - }, - "promise": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", - "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", - "dev": true, - "optional": true, - "requires": { - "asap": "2.0.6" - } - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true, - "optional": true - }, - "request": { - "version": "2.87.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz", - "integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==", - "dev": true, - "optional": true, - "requires": { - "aws-sign2": "0.7.0", - "aws4": "1.6.0", - "caseless": "0.12.0", - "combined-stream": "1.0.6", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "2.3.2", - "har-validator": "5.0.3", - "http-signature": "1.2.0", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.18", - "oauth-sign": "0.8.2", - "performance-now": "2.1.0", - "qs": "6.5.2", - "safe-buffer": "5.1.1", - "tough-cookie": "2.3.3", - "tunnel-agent": "0.6.0", - "uuid": "3.2.1" - } - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "optional": true - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "5.1.1" - } } } }, @@ -6501,6 +6452,15 @@ "integrity": "sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA==", "dev": true }, + "map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "dev": true, + "requires": { + "p-defer": "1.0.0" + } + }, "map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", @@ -6972,7 +6932,7 @@ "dev": true, "requires": { "dns-packet": "1.3.1", - "thunky": "1.0.2" + "thunky": "1.0.3" } }, "multicast-dns-service-types": { @@ -7468,9 +7428,9 @@ } }, "on-headers": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz", - "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", "dev": true }, "once": { @@ -7491,9 +7451,9 @@ } }, "opn": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-5.3.0.tgz", - "integrity": "sha512-bYJHo/LOmoTd+pfiYhfZDnf9zekVJrY+cnS2a5F2x+w5ppvTqObojTP7WiFG+kVZs9Inw+qQ/lw7TroWwhdd2g==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", + "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", "dev": true, "requires": { "is-wsl": "1.1.0" @@ -7530,12 +7490,12 @@ } }, "original": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/original/-/original-1.0.1.tgz", - "integrity": "sha512-IEvtB5vM5ULvwnqMxWBLxkS13JIEXbakizMSo3yoPNPCIWzg8TG3Usn/UhXoZFM/m+FuEA20KdzPSFq/0rS+UA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", + "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==", "dev": true, "requires": { - "url-parse": "1.4.1" + "url-parse": "1.4.4" } }, "os-browserify": { @@ -7577,12 +7537,24 @@ "os-tmpdir": "1.0.2" } }, + "p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", + "dev": true + }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", "dev": true }, + "p-is-promise": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.0.0.tgz", + "integrity": "sha512-pzQPhYMCAgLAKPWD2jC3Se9fEfrD9npNos0y150EeqZll7akhEgGhTW/slB6lHku8AvYGiJ+YJ5hfHKePPgFWg==", + "dev": true + }, "p-limit": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz", @@ -7830,9 +7802,9 @@ "dev": true }, "portfinder": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.13.tgz", - "integrity": "sha1-uzLs2HwnEErm7kS1o8y/Drsa7ek=", + "version": "1.0.20", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.20.tgz", + "integrity": "sha512-Yxe4mTyDzTd59PZJY4ojZR8F+E5e97iq2ZOHPz3HDgSvYC5siNad2tLooQ5y5QHyQhc3xVqvyk/eNA3wuoa7Sw==", "dev": true, "requires": { "async": "1.5.2", @@ -8711,6 +8683,16 @@ "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", "dev": true }, + "promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "dev": true, + "optional": true, + "requires": { + "asap": "2.0.6" + } + }, "promise-inflight": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", @@ -8734,13 +8716,13 @@ "dev": true }, "proxy-addr": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.3.tgz", - "integrity": "sha512-jQTChiCJteusULxjBp8+jftSQE5Obdl3k4cnmLA6WXtK6XFuWRnvVL7aCiBqaLPM8c4ph0S4tKna8XvmIwEnXQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz", + "integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==", "dev": true, "requires": { "forwarded": "0.1.2", - "ipaddr.js": "1.6.0" + "ipaddr.js": "1.8.0" } }, "prr": { @@ -8807,9 +8789,9 @@ "dev": true }, "qs": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", - "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", "dev": true }, "query-string": { @@ -8835,9 +8817,9 @@ "dev": true }, "querystringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.0.0.tgz", - "integrity": "sha512-eTPo5t/4bgaMNZxyjWx6N2a6AuE0mq51KWvpc7nU/MAqixcI6v6KrGUKES0HaomdnolQBBXU/++X6/QQ9KL4tw==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", + "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", "dev": true }, "quick-lru": { @@ -8897,40 +8879,25 @@ "dev": true }, "raw-body": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", - "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", + "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", "dev": true, "requires": { "bytes": "3.0.0", - "http-errors": "1.6.2", - "iconv-lite": "0.4.19", + "http-errors": "1.6.3", + "iconv-lite": "0.4.23", "unpipe": "1.0.0" }, "dependencies": { - "depd": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", - "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=", - "dev": true - }, - "http-errors": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", - "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", + "iconv-lite": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", "dev": true, "requires": { - "depd": "1.1.1", - "inherits": "2.0.3", - "setprototypeof": "1.0.3", - "statuses": "1.4.0" + "safer-buffer": "2.1.2" } - }, - "setprototypeof": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", - "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=", - "dev": true } } }, @@ -9835,9 +9802,9 @@ "dev": true }, "selfsigned": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.3.tgz", - "integrity": "sha512-vmZenZ+8Al3NLHkWnhBQ0x6BkML1eCP2xEi3JE+f3D9wW9fipD9NNJHYtE9XJM4TsPaHGZJIamrSI6MTg1dU2Q==", + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.4.tgz", + "integrity": "sha512-9AukTiDmHXGXWtWjembZ5NDmVvP2695EtpgbCsxCa68w3c88B+alqbmZ4O3hZ4VWGXeGWzEVdvqgAJD8DQPCDw==", "dev": true, "requires": { "node-forge": "0.7.5" @@ -10320,26 +10287,26 @@ } }, "sockjs-client": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.1.4.tgz", - "integrity": "sha1-W6vjhrd15M8U51IJEUUmVAFsixI=", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.3.0.tgz", + "integrity": "sha512-R9jxEzhnnrdxLCNln0xg5uGHqMnkhPSTzUZH2eXcR03S/On9Yvoq2wyUZILRUhZCNVu2PmwWVoyuiPz8th8zbg==", "dev": true, "requires": { - "debug": "2.6.9", - "eventsource": "0.1.6", + "debug": "3.2.6", + "eventsource": "1.0.7", "faye-websocket": "0.11.1", "inherits": "2.0.3", "json3": "3.3.2", - "url-parse": "1.4.1" + "url-parse": "1.4.4" }, "dependencies": { "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "dev": true, "requires": { - "ms": "2.0.0" + "ms": "2.1.1" } }, "faye-websocket": { @@ -10350,6 +10317,12 @@ "requires": { "websocket-driver": "0.7.0" } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true } } }, @@ -10415,52 +10388,82 @@ "dev": true }, "spdy": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-3.4.7.tgz", - "integrity": "sha1-Qv9B7OXMD5mjpsKKq7c/XDsDrLw=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.0.tgz", + "integrity": "sha512-ot0oEGT/PGUpzf/6uk4AWLqkq+irlqHXkrdbk51oWONh3bxQmBuljxPNl66zlRRcIJStWq0QkLUCPOPjgjvU0Q==", "dev": true, "requires": { - "debug": "2.6.9", - "handle-thing": "1.2.5", + "debug": "4.1.1", + "handle-thing": "2.0.0", "http-deceiver": "1.2.7", - "safe-buffer": "5.1.1", "select-hose": "2.0.0", - "spdy-transport": "2.1.0" + "spdy-transport": "3.0.0" }, "dependencies": { "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "dev": true, "requires": { - "ms": "2.0.0" + "ms": "2.1.1" } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true } } }, "spdy-transport": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-2.1.0.tgz", - "integrity": "sha512-bpUeGpZcmZ692rrTiqf9/2EUakI6/kXX1Rpe0ib/DyOzbiexVfXkw6GnvI9hVGvIwVaUhkaBojjCZwLNRGQg1g==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", "dev": true, "requires": { - "debug": "2.6.9", - "detect-node": "2.0.3", + "debug": "4.1.1", + "detect-node": "2.0.4", "hpack.js": "2.1.6", "obuf": "1.1.2", - "readable-stream": "2.3.4", - "safe-buffer": "5.1.1", + "readable-stream": "3.2.0", "wbuf": "1.7.3" }, "dependencies": { "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "dev": true, "requires": { - "ms": "2.0.0" + "ms": "2.1.1" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "readable-stream": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.2.0.tgz", + "integrity": "sha512-RV20kLjdmpZuTF1INEb9IA3L68Nmi+Ri7ppZqo78wj//Pn62fCoJyV9zalccNzDD/OuJpMG4f+pfMl8+L6QdGw==", + "dev": true, + "requires": { + "inherits": "2.0.3", + "string_decoder": "1.2.0", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz", + "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" } } } @@ -11472,9 +11475,9 @@ } }, "thunky": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.0.2.tgz", - "integrity": "sha1-qGLgGOP7HqLsP85dVWBc9X8kc3E=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.0.3.tgz", + "integrity": "sha512-YwT8pjmNcAXBZqrubu22P4FYsh2D4dxRmnWBOL8Jk8bUcRUtc5326kx32tuTmFDAZtLOGEVNl8POAR8j896Iow==", "dev": true }, "timers-browserify": { @@ -11555,16 +11558,6 @@ "integrity": "sha1-LmhELZ9k7HILjMieZEOsbKqVACk=", "dev": true }, - "tough-cookie": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", - "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=", - "dev": true, - "optional": true, - "requires": { - "punycode": "1.4.1" - } - }, "trim": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", @@ -11621,12 +11614,12 @@ } }, "ts-loader": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-4.4.1.tgz", - "integrity": "sha512-PvL6jgVEt4RurczrTOR8uI6uRmKRfRXiv3CyMRX8+MSQLlbedfbXtbJIdkhdpbqrsumb+Lc3qrxfmXHCmODyAg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-4.5.0.tgz", + "integrity": "sha512-ihgVaSmgrX4crGV4n7yuoHPoCHbDzj9aepCZR9TgIx4SgJ9gdnB6xLHgUBb7bsFM/f0K6x9iXa65KY/Fu1Klkw==", "dev": true, "requires": { - "chalk": "2.4.1", + "chalk": "2.4.2", "enhanced-resolve": "4.0.0", "loader-utils": "1.1.0", "micromatch": "3.1.10", @@ -11643,9 +11636,9 @@ } }, "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { "ansi-styles": "3.2.1", @@ -12219,12 +12212,12 @@ } }, "url-parse": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.1.tgz", - "integrity": "sha512-x95Td74QcvICAA0+qERaVkRpTGKyBHHYdwL2LXZm5t/gBtCB9KQSO/0zQgSTYEV1p0WcvSg79TLNPSvd5IDJMQ==", + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.4.tgz", + "integrity": "sha512-/92DTTorg4JjktLNLe6GPS2/RvAd/RGr6LuktmWSMLEOa6rjnlrFXNgSbSmkNvCoL2T028A0a1JaJLzRMlFoHg==", "dev": true, "requires": { - "querystringify": "2.0.0", + "querystringify": "2.1.1", "requires-port": "1.0.0" } }, @@ -12631,47 +12624,73 @@ } }, "webpack-dev-server": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.1.4.tgz", - "integrity": "sha512-itcIUDFkHuj1/QQxzUFOEXXmxOj5bku2ScLEsOFPapnq2JRTm58gPdtnBphBJOKL2+M3p6+xygL64bI+3eyzzw==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.2.1.tgz", + "integrity": "sha512-sjuE4mnmx6JOh9kvSbPYw3u/6uxCLHNWfhWaIPwcXWsvWOPN+nc5baq4i9jui3oOBRXGonK9+OI0jVkaz6/rCw==", "dev": true, "requires": { "ansi-html": "0.0.7", - "array-includes": "3.0.3", "bonjour": "3.5.0", "chokidar": "2.0.3", - "compression": "1.7.2", - "connect-history-api-fallback": "1.5.0", - "debug": "3.1.0", + "compression": "1.7.4", + "connect-history-api-fallback": "1.6.0", + "debug": "4.1.1", "del": "3.0.0", - "express": "4.16.3", + "express": "4.16.4", "html-entities": "1.2.1", - "http-proxy-middleware": "0.18.0", - "import-local": "1.0.0", - "internal-ip": "1.2.0", + "http-proxy-middleware": "0.19.1", + "import-local": "2.0.0", + "internal-ip": "4.2.0", "ip": "1.1.5", - "killable": "1.0.0", + "killable": "1.0.1", "loglevel": "1.6.1", - "opn": "5.3.0", - "portfinder": "1.0.13", - "selfsigned": "1.10.3", + "opn": "5.5.0", + "portfinder": "1.0.20", + "schema-utils": "1.0.0", + "selfsigned": "1.10.4", + "semver": "5.7.0", "serve-index": "1.9.1", "sockjs": "0.3.19", - "sockjs-client": "1.1.4", - "spdy": "3.4.7", + "sockjs-client": "1.3.0", + "spdy": "4.0.0", "strip-ansi": "3.0.1", - "supports-color": "5.4.0", - "webpack-dev-middleware": "3.1.3", - "webpack-log": "1.2.0", - "yargs": "11.0.0" + "supports-color": "6.1.0", + "url": "0.11.0", + "webpack-dev-middleware": "3.6.1", + "webpack-log": "2.0.0", + "yargs": "12.0.2" }, "dependencies": { + "ajv": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", + "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", + "dev": true, + "requires": { + "fast-deep-equal": "2.0.1", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.4.1", + "uri-js": "4.2.2" + } + }, + "ajv-keywords": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.0.tgz", + "integrity": "sha512-aUjdRFISbuFOl0EIZc+9e4FfZp0bDZgAdOOf30bJmw8VM9v84SHyVyxDfbWxpGYbdZD/9XoKxfHVNmxPkhwyGw==", + "dev": true + }, "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, "cliui": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", @@ -12694,6 +12713,37 @@ } } }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "1.0.4", + "path-key": "2.0.1", + "semver": "5.7.0", + "shebang-command": "1.2.0", + "which": "1.3.0" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "2.1.1" + } + }, + "decamelize": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-2.0.0.tgz", + "integrity": "sha512-Ikpp5scV3MSYxY39ymh45ZLEecsTdv/Xj2CaQfI8RLMuwi7XvjX9H/fhraiSuU+C5w5NTDu4ZU72xNiZnurBPg==", + "dev": true, + "requires": { + "xregexp": "4.0.0" + } + }, "del": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/del/-/del-3.0.0.tgz", @@ -12708,10 +12758,49 @@ "rimraf": "2.6.2" } }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "6.0.5", + "get-stream": "4.1.0", + "is-stream": "1.1.0", + "npm-run-path": "2.0.2", + "p-finally": "1.0.0", + "signal-exit": "3.0.2", + "strip-eof": "1.0.0" + } + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "3.0.0" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "3.0.0" + } + }, "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", "dev": true, "requires": { "fs.realpath": "1.0.0", @@ -12729,7 +12818,7 @@ "dev": true, "requires": { "array-union": "1.0.2", - "glob": "7.1.2", + "glob": "7.1.3", "object-assign": "4.1.1", "pify": "2.3.0", "pinkie-promise": "2.0.1" @@ -12743,30 +12832,217 @@ } } }, + "import-local": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", + "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "dev": true, + "requires": { + "pkg-dir": "3.0.0", + "resolve-cwd": "2.0.0" + } + }, + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "dev": true, + "requires": { + "invert-kv": "2.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "3.0.0", + "path-exists": "3.0.0" + } + }, + "mem": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.2.0.tgz", + "integrity": "sha512-5fJxa68urlY0Ir8ijatKa3eRz5lwXnRCTvo9+TbTGAuTFJOwpGcY0X05moBd0nW45965Njt4CDI2GFQoG8DvqA==", + "dev": true, + "requires": { + "map-age-cleaner": "0.1.3", + "mimic-fn": "2.0.0", + "p-is-promise": "2.0.0" + } + }, + "mime": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.0.tgz", + "integrity": "sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w==", + "dev": true + }, + "mimic-fn": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.0.0.tgz", + "integrity": "sha512-jbex9Yd/3lmICXwYT6gA/j2mNQGU48wCh/VzRd+/Y/PjYQtlg1gLMdZqvu9s/xH7qKvngxRObl56XZR609IMbA==", + "dev": true + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "dev": true, + "requires": { + "execa": "1.0.0", + "lcid": "2.0.0", + "mem": "4.2.0" + } + }, + "p-limit": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "dev": true, + "requires": { + "p-try": "2.1.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "2.2.0" + } + }, + "p-try": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.1.0.tgz", + "integrity": "sha512-H2RyIJ7+A3rjkwKC2l5GGtU4H1vkxKCAGsWasNVd0Set+6i4znxbWy6/j16YDPJDWxhsgZiKAstMEP8wCdSpjA==", + "dev": true + }, "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "3.0.0" + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "1.4.1", + "once": "1.4.0" + } + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "6.10.0", + "ajv-errors": "1.0.1", + "ajv-keywords": "3.4.0" + } + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "3.0.0" + } + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true + }, + "webpack-dev-middleware": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.6.1.tgz", + "integrity": "sha512-XQmemun8QJexMEvNFbD2BIg4eSKrmSIMrTfnl2nql2Sc6OGAYFyb8rwuYrCjl/IiEYYuyTEiimMscu7EXji/Dw==", + "dev": true, + "requires": { + "memory-fs": "0.4.1", + "mime": "2.4.0", + "range-parser": "1.0.3", + "webpack-log": "2.0.0" + } + }, + "webpack-log": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", + "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", + "dev": true, + "requires": { + "ansi-colors": "3.2.4", + "uuid": "3.3.2" + } + }, "yargs": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.0.0.tgz", - "integrity": "sha512-Rjp+lMYQOWtgqojx1dEWorjCofi1YN7AoFvYV7b1gx/7dAAeuI4kN5SZiEvr0ZmsZTOpDRcCqrpI10L31tFkBw==", + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.2.tgz", + "integrity": "sha512-e7SkEx6N6SIZ5c5H22RTZae61qtn3PYUE8JYbBFlK9sYmh3DMQ6E5ygtaG/2BW0JZi4WGgTR2IV5ChqlqrDGVQ==", "dev": true, "requires": { "cliui": "4.1.0", - "decamelize": "1.2.0", - "find-up": "2.1.0", + "decamelize": "2.0.0", + "find-up": "3.0.0", "get-caller-file": "1.0.2", - "os-locale": "2.1.0", + "os-locale": "3.1.0", "require-directory": "2.1.1", "require-main-filename": "1.0.1", "set-blocking": "2.0.0", "string-width": "2.1.1", "which-module": "2.0.0", "y18n": "3.2.1", - "yargs-parser": "9.0.2" + "yargs-parser": "10.1.0" + } + }, + "yargs-parser": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", + "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", + "dev": true, + "requires": { + "camelcase": "4.1.0" } } } @@ -12850,7 +13126,7 @@ "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=", "dev": true, "requires": { - "http-parser-js": "0.4.13", + "http-parser-js": "0.5.0", "websocket-extensions": "0.1.3" } }, @@ -13007,6 +13283,12 @@ "integrity": "sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI=", "dev": true }, + "xregexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.0.0.tgz", + "integrity": "sha512-PHyM+sQouu7xspQQwELlGwwd05mXUFqwFYfqPO0cC7x4fxyHnnuetmQr6CjJiafIDoH4MogHb9dOoJzR/Y4rFg==", + "dev": true + }, "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", diff --git a/package.json b/package.json index 4b9f170d0..a5c03fc2b 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "istanbul": "^0.4.5", "js-beautify": "^1.5.10", "json5": "^1.0.1", - "less": "^3.0.4", + "less": "^3.9.0", "less-loader": "^4.1.0", "lodash": "^4.17.10", "mini-css-extract-plugin": "^0.4.1", @@ -79,7 +79,7 @@ "stylelint": "^9.2.1", "stylelint-declaration-use-variable": "^1.6.1", "stylelint-order": "^0.8.1", - "ts-loader": "^4.4.1", + "ts-loader": "^4.5.0", "tslint": "^5.10.0", "typescript": "^2.9.2", "uglify-es": "^3.3.9", @@ -89,7 +89,7 @@ "webpack": "^4.12.0", "webpack-cli": "^3.0.4", "webpack-dev-middleware": "^3.1.3", - "webpack-dev-server": "^3.1.4", + "webpack-dev-server": "^3.2.1", "worker-loader": "^2.0.0" }, "engines": { diff --git a/src/BitNode/BitNode.ts b/src/BitNode/BitNode.ts index 778cb5098..8acbe9e5c 100644 --- a/src/BitNode/BitNode.ts +++ b/src/BitNode/BitNode.ts @@ -364,6 +364,7 @@ export function initBitNodeMultipliers(p: IPlayer) { BitNodeMultipliers.ServerStartingMoney = 0.1; BitNodeMultipliers.ServerMaxMoney = 0.1; BitNodeMultipliers.ServerStartingSecurity = 2.5; + BitNodeMultipliers.CorporationValuation = 0.5; break; case 10: // Digital Carbon BitNodeMultipliers.HackingLevelMultiplier = 0.2; From 92f7d12c0e958a9d17f7ce8a23d1ea5622ac7064 Mon Sep 17 00:00:00 2001 From: Olivier Gagnon Date: Fri, 29 Mar 2019 12:26:25 -0400 Subject: [PATCH 09/17] free output is now aligned and shows percent used --- src/Terminal.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Terminal.js b/src/Terminal.js index e41bb5125..87f15c181 100644 --- a/src/Terminal.js +++ b/src/Terminal.js @@ -1640,9 +1640,15 @@ let Terminal = { postError("Incorrect usage of free command. Usage: free"); return; } - post("Total: " + numeralWrapper.format(Player.getCurrentServer().maxRam, '0.00') + " GB"); - post("Used: " + numeralWrapper.format(Player.getCurrentServer().ramUsed, '0.00') + " GB"); - post("Available: " + numeralWrapper.format(Player.getCurrentServer().maxRam - Player.getCurrentServer().ramUsed, '0.00') + " GB"); + const ram = numeralWrapper.format(Player.getCurrentServer().maxRam, '0.00'); + const used = numeralWrapper.format(Player.getCurrentServer().ramUsed, '0.00'); + const avail = numeralWrapper.format(Player.getCurrentServer().maxRam - Player.getCurrentServer().ramUsed, '0.00'); + const maxLength = Math.max(ram.length, Math.max(used.length, avail.length)); + const usedPercent = numeralWrapper.format(Player.getCurrentServer().ramUsed/Player.getCurrentServer().maxRam*100, '0.00'); + + post(`Total: ${" ".repeat(maxLength-ram.length)}${ram} GB`); + post(`Used: ${" ".repeat(maxLength-used.length)}${used} GB (${usedPercent}%)`); + post(`Available: ${" ".repeat(maxLength-avail.length)}${avail} GB`); }, executeKillCommand: function(commandArray) { From b646c155217de606b2e0dfd628f8e126509fa14d Mon Sep 17 00:00:00 2001 From: Olivier Gagnon Date: Fri, 29 Mar 2019 12:32:11 -0400 Subject: [PATCH 10/17] It is now possible to join bladeburners in BN7 without having SF6-1 --- src/Location.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Location.js b/src/Location.js index 0e791d01f..f168d2eeb 100644 --- a/src/Location.js +++ b/src/Location.js @@ -654,7 +654,7 @@ function displayLocationContent() { networkEngineerJob.style.display = "block"; securityJob.style.display = "block"; agentJob.style.display = "block"; - if (Player.bitNodeN === 6 || hasBladeburnerSF === true) { + if (Player.bitNodeN === 6 ||Player.bitNodeN === 7 || hasBladeburnerSF === true) { if (Player.bitNodeN === 8) {break;} if (Player.bladeburner instanceof Bladeburner) { //Note: Can't infiltrate NSA when part of bladeburner From cb66ad9628b0d7c305805ba42f80d8cb31a4a3f5 Mon Sep 17 00:00:00 2001 From: Olivier Gagnon Date: Fri, 29 Mar 2019 12:10:22 -0400 Subject: [PATCH 11/17] fli1ght now displays the correct number of augs --- src/Terminal.js | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/Terminal.js b/src/Terminal.js index 87f15c181..afe0bca97 100644 --- a/src/Terminal.js +++ b/src/Terminal.js @@ -2,6 +2,7 @@ import {substituteAliases, printAliases, parseAliasDeclaration, removeAlias, GlobalAliases, Aliases} from "./Alias"; +import { BitNodeMultipliers } from "./BitNode/BitNodeMultipliers"; import {CodingContract, CodingContractResult, CodingContractRewardType} from "./CodingContracts"; import {CONSTANTS} from "./Constants"; @@ -2144,7 +2145,8 @@ let Terminal = { post("DeepscanV2.exe lets you run 'scan-analyze' with a depth up to 10."); }; programHandlers[Programs.Flight.name] = () => { - const fulfilled = Player.augmentations.length >= 30 && + const numAugReq = Math.round(BitNodeMultipliers.DaedalusAugsRequirement*30) + const fulfilled = Player.augmentations.length >= numAugReq && Player.money.gt(1e11) && ((Player.hacking_skill >= 2500)|| (Player.strength >= 1500 && @@ -2152,17 +2154,17 @@ let Terminal = { Player.dexterity >= 1500 && Player.agility >= 1500)); if(!fulfilled) { - post("Augmentations: " + Player.augmentations.length + " / 30"); + post(`Augmentations: ${Player.augmentations.length} / ${numAugReq}`); - post("Money: " + numeralWrapper.format(Player.money.toNumber(), '($0.000a)') + " / " + numeralWrapper.format(1e11, '($0.000a)')); + post(`Money: ${numeralWrapper.format(Player.money.toNumber(), '($0.000a)')} / numeralWrapper.format(1e11, '($0.000a)')`); post("One path below must be fulfilled..."); post("----------HACKING PATH----------"); - post("Hacking skill: " + Player.hacking_skill + " / 2500"); + post(`Hacking skill: ${Player.hacking_skill} / 2500`); post("----------COMBAT PATH----------"); - post("Strength: " + Player.strength + " / 1500"); - post("Defense: " + Player.defense + " / 1500"); - post("Dexterity: " + Player.dexterity + " / 1500"); - post("Agility: " + Player.agility + " / 1500"); + post(`Strength: ${Player.strength} / 1500`); + post(`Defense: ${Player.defense} / 1500`); + post(`Dexterity: ${Player.dexterity} / 1500`); + post(`Agility: ${Player.agility} / 1500`); return; } From e63ad767013762f78053e60c93b17122ef685fc4 Mon Sep 17 00:00:00 2001 From: Olivier Gagnon Date: Fri, 29 Mar 2019 12:11:01 -0400 Subject: [PATCH 12/17] typo --- src/Terminal.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Terminal.js b/src/Terminal.js index afe0bca97..c00bc76f5 100644 --- a/src/Terminal.js +++ b/src/Terminal.js @@ -2156,7 +2156,7 @@ let Terminal = { if(!fulfilled) { post(`Augmentations: ${Player.augmentations.length} / ${numAugReq}`); - post(`Money: ${numeralWrapper.format(Player.money.toNumber(), '($0.000a)')} / numeralWrapper.format(1e11, '($0.000a)')`); + post(`Money: ${numeralWrapper.format(Player.money.toNumber(), '($0.000a)')} / ${numeralWrapper.format(1e11, '($0.000a)')}`); post("One path below must be fulfilled..."); post("----------HACKING PATH----------"); post(`Hacking skill: ${Player.hacking_skill} / 2500`); From 18a3f061b4c3271520b90888d83a5b48a771b027 Mon Sep 17 00:00:00 2001 From: danielyxie Date: Fri, 29 Mar 2019 16:14:32 -0700 Subject: [PATCH 13/17] Rebalanced new Hacknet Node mechanics. Adjusted Hacknet API so that it'll work with hacknet Servers. Fixed Corporation bug with Issuing new Shares --- src/BitNode/BitNode.ts | 32 +++--- src/Constants.ts | 1 + .../ui/CorporationUIEventHandler.js | 1 + src/Hacking/README.md | 1 + src/Hacking/netscriptCanHack.ts | 53 +++++++++ src/Hacknet/HacknetHelpers.jsx | 20 +++- src/Hacknet/HacknetServer.ts | 7 +- src/Hacknet/HashManager.ts | 16 ++- src/Hacknet/data/HashUpgradesMetadata.ts | 32 +++--- src/Hacknet/ui/HashUpgradePopup.jsx | 31 +++--- src/NetscriptFunctions.js | 101 ++++++++++++------ src/Player.js | 2 + src/Terminal.js | 17 +-- src/types.ts | 9 ++ 14 files changed, 225 insertions(+), 98 deletions(-) create mode 100644 src/Hacking/README.md create mode 100644 src/Hacking/netscriptCanHack.ts diff --git a/src/BitNode/BitNode.ts b/src/BitNode/BitNode.ts index 8acbe9e5c..5ea5e01f1 100644 --- a/src/BitNode/BitNode.ts +++ b/src/BitNode/BitNode.ts @@ -350,21 +350,23 @@ export function initBitNodeMultipliers(p: IPlayer) { BitNodeMultipliers.CodingContractMoney = 0; break; case 9: // Hacktocracy - BitNodeMultipliers.HackingLevelMultiplier = 0.4; - BitNodeMultipliers.StrengthLevelMultiplier = 0.45; - BitNodeMultipliers.DefenseLevelMultiplier = 0.45; - BitNodeMultipliers.DexterityLevelMultiplier = 0.45; - BitNodeMultipliers.AgilityLevelMultiplier = 0.45; - BitNodeMultipliers.CharismaLevelMultiplier = 0.45; - BitNodeMultipliers.PurchasedServerLimit = 0; - BitNodeMultipliers.HomeComputerRamCost = 5; - BitNodeMultipliers.CrimeMoney = 0.5; - BitNodeMultipliers.ScriptHackMoney = 0.1; - BitNodeMultipliers.HackExpGain = 0.1; - BitNodeMultipliers.ServerStartingMoney = 0.1; - BitNodeMultipliers.ServerMaxMoney = 0.1; - BitNodeMultipliers.ServerStartingSecurity = 2.5; - BitNodeMultipliers.CorporationValuation = 0.5; + BitNodeMultipliers.HackingLevelMultiplier = 0.4; + BitNodeMultipliers.StrengthLevelMultiplier = 0.45; + BitNodeMultipliers.DefenseLevelMultiplier = 0.45; + BitNodeMultipliers.DexterityLevelMultiplier = 0.45; + BitNodeMultipliers.AgilityLevelMultiplier = 0.45; + BitNodeMultipliers.CharismaLevelMultiplier = 0.45; + BitNodeMultipliers.PurchasedServerLimit = 0; + BitNodeMultipliers.HomeComputerRamCost = 5; + BitNodeMultipliers.CrimeMoney = 0.5; + BitNodeMultipliers.ScriptHackMoney = 0.1; + BitNodeMultipliers.HackExpGain = 0.1; + BitNodeMultipliers.ServerStartingMoney = 0.1; + BitNodeMultipliers.ServerMaxMoney = 0.1; + BitNodeMultipliers.ServerStartingSecurity = 2.5; + BitNodeMultipliers.CorporationValuation = 0.5; + BitNodeMultipliers.FourSigmaMarketDataCost = 5; + BitNodeMultipliers.FourSigmaMarketDataApiCost = 4; break; case 10: // Digital Carbon BitNodeMultipliers.HackingLevelMultiplier = 0.2; diff --git a/src/Constants.ts b/src/Constants.ts index ae1d9c96f..9ab2c8244 100644 --- a/src/Constants.ts +++ b/src/Constants.ts @@ -285,6 +285,7 @@ export let CONSTANTS: IMap = { * Corporation Changes: ** 'Demand' value of products decreases more slowly ** Bug Fix: Fixed a Corporation issue that broke the Market-TA2 Research + ** Bug Fix: Issuing New Shares now works properly * Bug Fix: Money Statistics tracker was incorrectly recording profits when selling stocks manually * Bug Fix: Fixed an issue with the job requirement tooltip for security jobs diff --git a/src/Corporation/ui/CorporationUIEventHandler.js b/src/Corporation/ui/CorporationUIEventHandler.js index 46dfa16b3..8738966d3 100644 --- a/src/Corporation/ui/CorporationUIEventHandler.js +++ b/src/Corporation/ui/CorporationUIEventHandler.js @@ -31,6 +31,7 @@ import { numeralWrapper } from "../../ui/numeralFormat"; import { dialogBoxCreate } from "../../../utils/DialogBox"; +import { getRandomInt } from "../../../utils/helpers/getRandomInt"; import { KEY } from "../../../utils/helpers/keyCodes"; import { clearSelector } from "../../../utils/uiHelpers/clearSelector"; diff --git a/src/Hacking/README.md b/src/Hacking/README.md new file mode 100644 index 000000000..86be3f14e --- /dev/null +++ b/src/Hacking/README.md @@ -0,0 +1 @@ +Implementation of underlying Hacking mechanics diff --git a/src/Hacking/netscriptCanHack.ts b/src/Hacking/netscriptCanHack.ts new file mode 100644 index 000000000..875fd22f5 --- /dev/null +++ b/src/Hacking/netscriptCanHack.ts @@ -0,0 +1,53 @@ +/** + * Functions used to determine whether the target can be hacked (or grown/weakened). + * Meant to be used for Netscript implementation + * + * The returned status object's message should be used for logging in Netscript + */ +import { IReturnStatus } from "../types"; + +import { HacknetServer } from "../Hacknet/HacknetServer"; +import { IPlayer } from "../PersonObjects/IPlayer"; +import { Server } from "../Server/Server"; + +function baseCheck(server: Server | HacknetServer, fnName: string): IReturnStatus { + if (server instanceof HacknetServer) { + return { + res: false, + msg: `Cannot ${fnName} ${server.hostname} server because it is a Hacknet Node` + } + } + + if (server.hasAdminRights === false) { + return { + res: false, + msg: `Cannot ${fnName} ${server.hostname} server because you do not have root access`, + } + } + + return { res: true } +} + +export function netscriptCanHack(server: Server | HacknetServer, p: IPlayer): IReturnStatus { + const initialCheck = baseCheck(server, "hack"); + if (!initialCheck.res) { return initialCheck; } + + let s = server; + + if (s.requiredHackingSkill > p.hacking_skill) { + return { + res: false, + msg: `Cannot hack ${server.hostname} server because your hacking skill is not high enough`, + } + } + + return { res: true } +} + +export function netscriptCanGrow(server: Server | HacknetServer): IReturnStatus { + return baseCheck(server, "grow"); +} + +export function netscriptCanWeaken(server: Server | HacknetServer): IReturnStatus { + return baseCheck(server, "weaken"); +} diff --git a/src/Hacknet/HacknetHelpers.jsx b/src/Hacknet/HacknetHelpers.jsx index 50d1e5ccd..9a24e3afc 100644 --- a/src/Hacknet/HacknetHelpers.jsx +++ b/src/Hacknet/HacknetHelpers.jsx @@ -54,7 +54,6 @@ export function purchaseHacknet() { return; } } - /* END INTERACTIVE TUTORIAL */ if (hasHacknetServers()) { @@ -396,11 +395,21 @@ export function purchaseHashUpgrade(upgName, upgTarget) { break; } case "Exchange for Bladeburner Rank": { - // This will throw if player doesn't have a corporation + // This will throw if player isnt in Bladeburner try { - for (const division of Player.corporation.divisions) { - division.sciResearch.qty += upg.value; - } + Player.bladeburner.changeRank(upg.value); + } catch(e) { + Player.hashManager.refundUpgrade(upgName); + return false; + } + break; + } + case "Exchange for Bladeburner SP": { + // This will throw if player isn't in Bladeburner + try { + // As long as we don't change `Bladeburner.totalSkillPoints`, this + // shouldn't affect anything else + Player.bladeburner.skillPoints += upg.value; } catch(e) { Player.hashManager.refundUpgrade(upgName); return false; @@ -413,6 +422,7 @@ export function purchaseHashUpgrade(upgName, upgTarget) { } default: console.warn(`Unrecognized upgrade name ${upgName}. Upgrade has no effect`) + Player.hashManager.refundUpgrade(upgName); return false; } diff --git a/src/Hacknet/HacknetServer.ts b/src/Hacknet/HacknetServer.ts index af86618d9..0a353f617 100644 --- a/src/Hacknet/HacknetServer.ts +++ b/src/Hacknet/HacknetServer.ts @@ -327,16 +327,17 @@ export class HacknetServer extends BaseServer implements IHacknetNode { updateHashRate(p: IPlayer): void { const baseGain = HacknetServerHashesPerLevel * this.level; - const coreMultiplier = Math.pow(1.1, this.cores - 1); + const ramMultiplier = Math.pow(1.07, Math.log2(this.maxRam)); + const coreMultiplier = 1 + (this.cores - 1) / 5; const ramRatio = (1 - this.ramUsed / this.maxRam); - const hashRate = baseGain * coreMultiplier * ramRatio; + const hashRate = baseGain * ramMultiplier * coreMultiplier * ramRatio; this.hashRate = hashRate * p.hacknet_node_money_mult * BitNodeMultipliers.HacknetNodeMoney; if (isNaN(this.hashRate)) { this.hashRate = 0; - dialogBoxCreate(`Error calculating Hacknet Server hash production. This is a bug. Please report to game dev`, false); + console.error(`Error calculating Hacknet Server hash production. This is a bug. Please report to game dev`, false); } } diff --git a/src/Hacknet/HashManager.ts b/src/Hacknet/HashManager.ts index 1f01e7c24..4f6e94413 100644 --- a/src/Hacknet/HashManager.ts +++ b/src/Hacknet/HashManager.ts @@ -84,9 +84,14 @@ export class HashManager { return upg.getCost(currLevel); } - storeHashes(numHashes: number): void { - this.hashes += numHashes; - this.hashes = Math.min(this.hashes, this.capacity); + prestige(p: IPlayer): void { + for (const name in HashUpgrades) { + this.upgrades[name] = 0; + } + this.hashes = 0; + if (p != null) { + this.updateCapacity(p); + } } /** @@ -106,6 +111,11 @@ export class HashManager { this.hashes += cost; } + storeHashes(numHashes: number): void { + this.hashes += numHashes; + this.hashes = Math.min(this.hashes, this.capacity); + } + updateCapacity(p: IPlayer): void { if (p.hacknetNodes.length <= 0) { this.capacity = 0; diff --git a/src/Hacknet/data/HashUpgradesMetadata.ts b/src/Hacknet/data/HashUpgradesMetadata.ts index d1904ec35..1ced91216 100644 --- a/src/Hacknet/data/HashUpgradesMetadata.ts +++ b/src/Hacknet/data/HashUpgradesMetadata.ts @@ -3,7 +3,7 @@ import { IConstructorParams } from "../HashUpgrade"; export const HashUpgradesMetadata: IConstructorParams[] = [ { - costPerLevel: 2, + costPerLevel: 1, desc: "Sell hashes for $1m", name: "Sell for Money", value: 1e6, @@ -15,36 +15,36 @@ export const HashUpgradesMetadata: IConstructorParams[] = [ value: 1e9, }, { - costPerLevel: 100, - desc: "Use hashes to decrease the minimum security of a single server by 5%. " + + costPerLevel: 50, + desc: "Use hashes to decrease the minimum security of a single server by 2%. " + "Note that a server's minimum security cannot go below 1.", hasTargetServer: true, name: "Reduce Minimum Security", - value: 0.95, + value: 0.98, }, { - costPerLevel: 100, - desc: "Use hashes to increase the maximum amount of money on a single server by 5%", + costPerLevel: 50, + desc: "Use hashes to increase the maximum amount of money on a single server by 2%", hasTargetServer: true, name: "Increase Maximum Money", - value: 1.05, + value: 1.02, }, { - costPerLevel: 100, - desc: "Use hashes to improve the experience earned when studying at a university. " + + costPerLevel: 50, + desc: "Use hashes to improve the experience earned when studying at a university by 20%. " + "This effect persists until you install Augmentations", name: "Improve Studying", value: 20, // Improves studying by value% }, { - costPerLevel: 100, - desc: "Use hashes to improve the experience earned when training at the gym. This effect " + + costPerLevel: 50, + desc: "Use hashes to improve the experience earned when training at the gym by 20%. This effect " + "persists until you install Augmentations", name: "Improve Gym Training", value: 20, // Improves training by value% }, { - costPerLevel: 250, + costPerLevel: 200, desc: "Exchange hashes for 1k Scientific Research in all of your Corporation's Industries", name: "Exchange for Corporation Research", value: 1000, @@ -56,7 +56,13 @@ export const HashUpgradesMetadata: IConstructorParams[] = [ value: 100, }, { - costPerLevel: 200, + costPerLevel: 250, + desc: "Exchanges hashes for 10 Bladeburner Skill Points", + name: "Exchange for Bladeburner SP", + value: 10, + }, + { + costPerLevel: 150, desc: "Generate a random Coding Contract on your home computer", name: "Generate Coding Contract", value: 1, diff --git a/src/Hacknet/ui/HashUpgradePopup.jsx b/src/Hacknet/ui/HashUpgradePopup.jsx index 720f73a51..5f1591577 100644 --- a/src/Hacknet/ui/HashUpgradePopup.jsx +++ b/src/Hacknet/ui/HashUpgradePopup.jsx @@ -3,21 +3,22 @@ */ import React from "react"; -import { purchaseHashUpgrade } from "../HacknetHelpers"; -import { HashManager } from "../HashManager"; -import { HashUpgrades } from "../HashUpgrades"; +import { purchaseHashUpgrade } from "../HacknetHelpers"; +import { HashManager } from "../HashManager"; +import { HashUpgrades } from "../HashUpgrades"; -import { Player } from "../../Player"; -import { AllServers } from "../../Server/AllServers"; -import { Server } from "../../Server/Server"; +import { Player } from "../../Player"; +import { AllServers } from "../../Server/AllServers"; +import { Server } from "../../Server/Server"; -import { numeralWrapper } from "../../ui/numeralFormat"; +import { numeralWrapper } from "../../ui/numeralFormat"; -import { removePopup } from "../../ui/React/createPopup"; +import { removePopup } from "../../ui/React/createPopup"; +import { PopupCloseButton } from "../../ui/React/PopupCloseButton"; import { ServerDropdown, - ServerType } from "../../ui/React/ServerDropdown" + ServerType } from "../../ui/React/ServerDropdown" -import { dialogBoxCreate } from "../../../utils/DialogBox"; +import { dialogBoxCreate } from "../../../utils/DialogBox"; class HashUpgrade extends React.Component { constructor(props) { @@ -85,8 +86,6 @@ export class HashUpgradePopup extends React.Component { constructor(props) { super(props); - this.closePopup = this.closePopup.bind(this); - this.state = { totalHashes: Player.hashManager.hashes, } @@ -100,10 +99,6 @@ export class HashUpgradePopup extends React.Component { clearInterval(this.interval); } - closePopup() { - removePopup(this.props.popupId); - } - tick() { this.setState({ totalHashes: Player.hashManager.hashes, @@ -125,9 +120,7 @@ export class HashUpgradePopup extends React.Component { return (
    - +

    Spend your hashes on a variety of different upgrades

    Hashes: {numeralWrapper.formatBigNumber(this.state.totalHashes)}

    {upgradeElems} diff --git a/src/NetscriptFunctions.js b/src/NetscriptFunctions.js index fa9dbaef1..b6d5fa3da 100644 --- a/src/NetscriptFunctions.js +++ b/src/NetscriptFunctions.js @@ -29,7 +29,12 @@ import { Factions, import { joinFaction, purchaseAugmentation } from "./Faction/FactionHelpers"; import { FactionWorkType } from "./Faction/FactionWorkTypeEnum"; +import { netscriptCanGrow, + netscriptCanHack, + netscriptCanWeaken } from "./Hacking/netscriptCanHack"; import { getCostOfNextHacknetNode, + getCostOfNextHacknetServer, + hasHacknetServers, purchaseHacknet } from "./Hacknet/HacknetNode"; import {Locations} from "./Locations"; import { Message } from "./Message/Message"; @@ -194,11 +199,11 @@ function initSingularitySFFlags() { } function NetscriptFunctions(workerScript) { - var updateDynamicRam = function(fnName, ramCost) { + const updateDynamicRam = function(fnName, ramCost) { if (workerScript.dynamicLoadedFns[fnName]) {return;} workerScript.dynamicLoadedFns[fnName] = true; - const threads = workerScript.scriptRef.threads; + let threads = workerScript.scriptRef.threads; if (typeof threads !== 'number') { console.warn(`WorkerScript detected NaN for threadcount for ${workerScript.name} on ${workerScript.serverIp}`); threads = 1; @@ -215,7 +220,7 @@ function NetscriptFunctions(workerScript) { } }; - var updateStaticRam = function(fnName, ramCost) { + const updateStaticRam = function(fnName, ramCost) { if (workerScript.loadedFns[fnName]) { return 0; } else { @@ -230,7 +235,7 @@ function NetscriptFunctions(workerScript) { * @param {string} Hostname or IP of the server * @returns {Server} The specified Server */ - var safeGetServer = function(ip, callingFnName="") { + const safeGetServer = function(ip, callingFnName="") { var server = getServer(ip); if (server == null) { throw makeRuntimeRejectMsg(workerScript, `Invalid IP or hostname passed into ${callingFnName}() function`); @@ -239,17 +244,27 @@ function NetscriptFunctions(workerScript) { } // Utility function to get Hacknet Node object - var getHacknetNode = function(i) { + const getHacknetNode = function(i) { if (isNaN(i)) { throw makeRuntimeRejectMsg(workerScript, "Invalid index specified for Hacknet Node: " + i); } if (i < 0 || i >= Player.hacknetNodes.length) { throw makeRuntimeRejectMsg(workerScript, "Index specified for Hacknet Node is out-of-bounds: " + i); } - return Player.hacknetNodes[i]; + + if (hasHacknetServers()) { + const hserver = AllServers[Player.hacknetNodes[i]]; + if (hserver == null) { + throw makeRuntimeRejectMsg(workerScript, `Could not get Hacknet Server for index ${i}. This is probably a bug, please report to game dev`); + } + + return hserver; + } else { + return Player.hacknetNodes[i]; + } }; - var getCodingContract = function(fn, ip) { + const getCodingContract = function(fn, ip) { var server = safeGetServer(ip, "getCodingContract"); return server.getContract(fn); } @@ -263,43 +278,64 @@ function NetscriptFunctions(workerScript) { return purchaseHacknet(); }, getPurchaseNodeCost : function() { - return getCostOfNextHacknetNode(); + if (hasHacknetServers()) { + return getCostOfNextHacknetServer(); + } else { + return getCostOfNextHacknetNode(); + } }, getNodeStats : function(i) { - var node = getHacknetNode(i); - return { + const node = getHacknetNode(i); + const hasUpgraded = hasHacknetServers(); + const res = { name: node.name, level: node.level, - ram: node.ram, + ram: hasUpgraded ? node.maxRam : node.ram, cores: node.cores, - production: node.moneyGainRatePerSecond, + production: hasUpgraded ? node.hashRate : node.moneyGainRatePerSecond, timeOnline: node.onlineTimeSeconds, - totalProduction: node.totalMoneyGenerated, + totalProduction: hasUpgraded ? node.totalHashesGenerated : node.totalMoneyGenerated, }; + + if (hasUpgraded) { + res.cache = node.cache; + } + + return res; }, upgradeLevel : function(i, n) { - var node = getHacknetNode(i); + const node = getHacknetNode(i); return node.purchaseLevelUpgrade(n, Player); }, upgradeRam : function(i, n) { - var node = getHacknetNode(i); + const node = getHacknetNode(i); return node.purchaseRamUpgrade(n, Player); }, upgradeCore : function(i, n) { - var node = getHacknetNode(i); + const node = getHacknetNode(i); return node.purchaseCoreUpgrade(n, Player); }, + upgradeCache : function(i, n) { + if (!hasHacknetServers()) { return false; } + const node = getHacknetNode(i); + return node.purchaseCacheUpgrade(n, Player); + }, getLevelUpgradeCost : function(i, n) { - var node = getHacknetNode(i); + const node = getHacknetNode(i); return node.calculateLevelUpgradeCost(n, Player); }, getRamUpgradeCost : function(i, n) { - var node = getHacknetNode(i); + const node = getHacknetNode(i); return node.calculateRamUpgradeCost(n, Player); }, getCoreUpgradeCost : function(i, n) { - var node = getHacknetNode(i); + const node = getHacknetNode(i); return node.calculateCoreUpgradeCost(n, Player); + }, + getCacheUpgradeCost : function(i, n) { + if (!hasHacknetServers()) { return Infinity; } + const node = getHacknetNode(i); + return node.calculateCacheUpgradeCost(n); } }, sprintf : sprintf, @@ -351,19 +387,16 @@ function NetscriptFunctions(workerScript) { var hackingTime = calculateHackingTime(server); //This is in seconds //No root access or skill level too low - if (server.hasAdminRights == false) { - workerScript.scriptRef.log("Cannot hack this server (" + server.hostname + ") because user does not have root access"); - throw makeRuntimeRejectMsg(workerScript, "Cannot hack this server (" + server.hostname + ") because user does not have root access"); - } - - if (server.requiredHackingSkill > Player.hacking_skill) { - workerScript.scriptRef.log("Cannot hack this server (" + server.hostname + ") because user's hacking skill is not high enough"); - throw makeRuntimeRejectMsg(workerScript, "Cannot hack this server (" + server.hostname + ") because user's hacking skill is not high enough"); + const canHack = netscriptCanHack(server, Player); + if (!canHack.res) { + workerScript.scriptRef.log(`ERROR: ${canHack.msg}`); + throw makeRuntimeRejectMsg(workerScript, canHack.msg); } if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.hack == null) { workerScript.scriptRef.log("Attempting to hack " + ip + " in " + hackingTime.toFixed(3) + " seconds (t=" + threads + ")"); } + return netscriptDelay(hackingTime * 1000, workerScript).then(function() { if (workerScript.env.stopFlag) {return Promise.reject(workerScript);} var hackChance = calculateHackingChance(server); @@ -482,9 +515,10 @@ function NetscriptFunctions(workerScript) { } //No root access or skill level too low - if (server.hasAdminRights == false) { - workerScript.scriptRef.log("Cannot grow this server (" + server.hostname + ") because user does not have root access"); - throw makeRuntimeRejectMsg(workerScript, "Cannot grow this server (" + server.hostname + ") because user does not have root access"); + const canHack = netscriptCanGrow(server); + if (!canHack.res) { + workerScript.scriptRef.log(`ERROR: ${canHack.msg}`); + throw makeRuntimeRejectMsg(workerScript, canHack.msg); } var growTime = calculateGrowTime(server); @@ -543,9 +577,10 @@ function NetscriptFunctions(workerScript) { } //No root access or skill level too low - if (server.hasAdminRights == false) { - workerScript.scriptRef.log("Cannot weaken this server (" + server.hostname + ") because user does not have root access"); - throw makeRuntimeRejectMsg(workerScript, "Cannot weaken this server (" + server.hostname + ") because user does not have root access"); + const canHack = netscriptCanWeaken(server); + if (!canHack.res) { + workerScript.scriptRef.log(`ERROR: ${canHack.msg}`); + throw makeRuntimeRejectMsg(workerScript, canHack.msg); } var weakenTime = calculateWeakenTime(server); diff --git a/src/Player.js b/src/Player.js index a42e021fc..6ad8978d2 100644 --- a/src/Player.js +++ b/src/Player.js @@ -331,6 +331,7 @@ PlayerObject.prototype.prestigeAugmentation = function() { this.moneySourceA.reset(); this.hacknetNodes.length = 0; + this.hashManager.prestige(this); //Re-calculate skills and reset HP this.updateSkillLevels(); @@ -420,6 +421,7 @@ PlayerObject.prototype.prestigeSourceFile = function() { this.lastUpdate = new Date().getTime(); this.hacknetNodes.length = 0; + this.hashManager.prestige(this); //Gang this.gang = null; diff --git a/src/Terminal.js b/src/Terminal.js index e41bb5125..f68c6aaa0 100644 --- a/src/Terminal.js +++ b/src/Terminal.js @@ -1246,23 +1246,26 @@ let Terminal = { case "free": Terminal.executeFreeCommand(commandArray); break; - case "hack": - if (commandArray.length !== 1) { + case "hack": { + if (commandArray.length !== 1) { postError("Incorrect usage of hack command. Usage: hack"); return; } //Hack the current PC (usually for money) //You can't hack your home pc or servers you purchased - if (Player.getCurrentServer().purchasedByPlayer) { + if (s.purchasedByPlayer) { postError("Cannot hack your own machines! You are currently connected to your home PC or one of your purchased servers"); - } else if (Player.getCurrentServer().hasAdminRights == false ) { + } else if (s.hasAdminRights == false ) { postError("You do not have admin rights for this machine! Cannot hack"); - } else if (Player.getCurrentServer().requiredHackingSkill > Player.hacking_skill) { + } else if (s.requiredHackingSkill > Player.hacking_skill) { postError("Your hacking skill is not high enough to attempt hacking this machine. Try analyzing the machine to determine the required hacking skill"); - } else { + } else if (s instanceof HacknetServer) { + postError("Cannot hack this type of Server") + } else { Terminal.startHack(); } break; + } case "help": if (commandArray.length !== 1 && commandArray.length !== 2) { postError("Incorrect usage of help command. Usage: help"); @@ -1894,7 +1897,7 @@ let Terminal = { //var dashes = Array(d * 2 + 1).join("-"); var c = "NO"; if (s.hasAdminRights) {c = "YES";} - post(`${dashes}Root Access: ${c} ${!isHacknet ? ", Required hacking skill: " + s.requiredHackingSkill : ""}`); + post(`${dashes}Root Access: ${c}${!isHacknet ? ", Required hacking skill: " + s.requiredHackingSkill : ""}`); if (!isHacknet) { post(dashes + "Number of open ports required to NUKE: " + s.numOpenPortsRequired); } post(dashes + "RAM: " + s.maxRam); post(" "); diff --git a/src/types.ts b/src/types.ts index 1c762fc44..ec1581932 100644 --- a/src/types.ts +++ b/src/types.ts @@ -35,3 +35,12 @@ export interface ISelfLoading { */ load(saveState: string): void; } + +/** + * Status object for functions that return a boolean indicating success/failure + * and an optional message + */ +export interface IReturnStatus { + res: boolean; + msg?: string; +} From 51d927462699c65b98eb4dc9a04be7e3c701541b Mon Sep 17 00:00:00 2001 From: danielyxie Date: Fri, 29 Mar 2019 20:01:34 -0700 Subject: [PATCH 14/17] Added effects for Source-File 9 --- src/BitNode/BitNode.ts | 22 ++++++++++-- src/Hacknet/HacknetHelpers.jsx | 37 ++++++++++--------- src/NetscriptFunctions.js | 9 +++-- src/Player.js | 7 ++-- src/Prestige.js | 40 ++++++++++++--------- src/ScriptEditor/AceNetscriptMode.js | 4 +-- src/ScriptEditor/CodeMirrorNetscriptMode.js | 2 ++ src/SourceFile.js | 30 ++++++++++------ 8 files changed, 97 insertions(+), 54 deletions(-) diff --git a/src/BitNode/BitNode.ts b/src/BitNode/BitNode.ts index 5ea5e01f1..e90ed9157 100644 --- a/src/BitNode/BitNode.ts +++ b/src/BitNode/BitNode.ts @@ -176,7 +176,21 @@ export function initBitNodes() { BitNodes["BitNode9"] = new BitNode(9, "Hacktocracy", "Hacknet Unleashed", "When Fulcrum Technologies released their open-source Linux distro Chapeau, it quickly " + "became the OS of choice for the underground hacking community. Chapeau became especially notorious for " + - "powering the Hacknet, "); + "powering the Hacknet, a global, decentralized network used for nefarious purposes. Fulcrum quickly " + + "abandoned the project and dissociated themselves from it.

    " + + "This BitNode unlocks the Hacknet Server, an upgraded version of the Hacknet Node. Hacknet Servers generate " + + "hashes, which can be spent on a variety of different upgrades.

    " + + "In this BitNode:

    " + + "Your stats are significantly decreased
    " + + "You cannnot purchase additional servers
    " + + "Hacking is significantly less profitable

    " + + "Destroying this BitNode will give you Source-File 9, or if you already have this Source-File it will " + + "upgrade its level up to a maximum of 3. This Source-File grants the following benefits:

    " + + "Level 1: Permanently unlocks the Hacknet Server in other BitNodes
    " + + "Level 2: You start with 128GB of RAM on your home computer when entering a new BitNode
    " + + "Level 3: Grants a highly-upgraded Hacknet Server when entering a new BitNode

    " + + "(Note that the Level 3 effect of this Source-File only applies when entering a new BitNode, NOT " + + "when installing Augmentations)"); BitNodes["BitNode10"] = new BitNode(10, "Digital Carbon", "Your body is not who you are", "In 2084, VitaLife unveiled to the world the Persona Core, a technology that allowed people " + "to digitize their consciousness. Their consciousness could then be transferred into Synthoids " + @@ -186,7 +200,7 @@ export function initBitNodes() { "1. Re-sleeve: Purchase and transfer your consciousness into a new body
    " + "2. Duplicate Sleeves: Duplicate your consciousness into Synthoids, allowing you to perform different tasks synchronously

    " + "In this BitNode:

    " + - "Your stats are significantly decreased.
    " + + "Your stats are significantly decreased
    " + "All methods of gaining money are half as profitable (except Stock Market)
    " + "Purchased servers are more expensive, have less max RAM, and a lower maximum limit
    " + "Augmentations are 5x as expensive and require twice as much reputation

    " + @@ -360,13 +374,15 @@ export function initBitNodeMultipliers(p: IPlayer) { BitNodeMultipliers.HomeComputerRamCost = 5; BitNodeMultipliers.CrimeMoney = 0.5; BitNodeMultipliers.ScriptHackMoney = 0.1; - BitNodeMultipliers.HackExpGain = 0.1; + BitNodeMultipliers.HackExpGain = 0.05; BitNodeMultipliers.ServerStartingMoney = 0.1; BitNodeMultipliers.ServerMaxMoney = 0.1; BitNodeMultipliers.ServerStartingSecurity = 2.5; BitNodeMultipliers.CorporationValuation = 0.5; BitNodeMultipliers.FourSigmaMarketDataCost = 5; BitNodeMultipliers.FourSigmaMarketDataApiCost = 4; + BitNodeMultipliers.BladeburnerRank = 0.9; + BitNodeMultipliers.BladeburnerSkillCost = 1.2; break; case 10: // Digital Carbon BitNodeMultipliers.HackingLevelMultiplier = 0.2; diff --git a/src/Hacknet/HacknetHelpers.jsx b/src/Hacknet/HacknetHelpers.jsx index 9a24e3afc..29f85a8a1 100644 --- a/src/Hacknet/HacknetHelpers.jsx +++ b/src/Hacknet/HacknetHelpers.jsx @@ -45,6 +45,25 @@ export function hasHacknetServers() { return (Player.bitNodeN === 9 || SourceFileFlags[9] > 0); } +export function createHacknetServer() { + const numOwned = Player.hacknetNodes.length; + const name = `hacknet-node-${numOwned}`; + const server = new HacknetServer({ + adminRights: true, + hostname: name, + player: Player, + }); + Player.hacknetNodes.push(server.ip); + + // Configure the HacknetServer to actually act as a Server + AddToAllServers(server); + const homeComputer = Player.getHomeComputer(); + homeComputer.serversOnNetwork.push(server.ip); + server.serversOnNetwork.push(homeComputer.ip); + + return server; +} + export function purchaseHacknet() { /* INTERACTIVE TUTORIAL */ if (ITutorial.isRunning) { @@ -63,24 +82,8 @@ export function purchaseHacknet() { } if (!Player.canAfford(cost)) { return -1; } - - // Auto generate a hostname for this Server - const numOwned = Player.hacknetNodes.length; - const name = `hacknet-node-${numOwned}`; - const server = new HacknetServer({ - adminRights: true, - hostname: name, - player: Player, - }); - Player.loseMoney(cost); - Player.hacknetNodes.push(server.ip); - - // Configure the HacknetServer to actually act as a Server - AddToAllServers(server); - const homeComputer = Player.getHomeComputer(); - homeComputer.serversOnNetwork.push(server.ip); - server.serversOnNetwork.push(homeComputer.ip); + const server = createHacknetServer(); return numOwned; } else { diff --git a/src/NetscriptFunctions.js b/src/NetscriptFunctions.js index b6d5fa3da..afed96696 100644 --- a/src/NetscriptFunctions.js +++ b/src/NetscriptFunctions.js @@ -32,10 +32,11 @@ import { FactionWorkType } from "./Faction/FactionWorkT import { netscriptCanGrow, netscriptCanHack, netscriptCanWeaken } from "./Hacking/netscriptCanHack"; + import { getCostOfNextHacknetNode, getCostOfNextHacknetServer, hasHacknetServers, - purchaseHacknet } from "./Hacknet/HacknetNode"; + purchaseHacknet } from "./Hacknet/HacknetHelpers"; import {Locations} from "./Locations"; import { Message } from "./Message/Message"; import { Messages } from "./Message/MessageHelpers"; @@ -318,7 +319,11 @@ function NetscriptFunctions(workerScript) { upgradeCache : function(i, n) { if (!hasHacknetServers()) { return false; } const node = getHacknetNode(i); - return node.purchaseCacheUpgrade(n, Player); + const res = node.purchaseCacheUpgrade(n, Player); + if (res) { + Player.hashManager.updateCapacity(Player); + } + return res; }, getLevelUpgradeCost : function(i, n) { const node = getHacknetNode(i); diff --git a/src/Player.js b/src/Player.js index 6ad8978d2..96920e193 100644 --- a/src/Player.js +++ b/src/Player.js @@ -420,20 +420,21 @@ PlayerObject.prototype.prestigeSourceFile = function() { this.lastUpdate = new Date().getTime(); + // Hacknet Nodes this.hacknetNodes.length = 0; this.hashManager.prestige(this); - //Gang + // Gang this.gang = null; resetGangs(); - //Reset Stock market + // Reset Stock market this.hasWseAccount = false; this.hasTixApiAccess = false; this.has4SData = false; this.has4SDataTixApi = false; - //BitNode 3: Corporatocracy + // Corporation this.corporation = 0; // Statistics trackers diff --git a/src/Prestige.js b/src/Prestige.js index c764c5a37..4ee7cb9ad 100755 --- a/src/Prestige.js +++ b/src/Prestige.js @@ -14,6 +14,7 @@ import { Faction } from "./Faction/Faction"; import { Factions, initFactions } from "./Faction/Factions"; import { joinFaction } from "./Faction/FactionHelpers"; +import { createHacknetServer } from "./Hacknet/HacknetHelpers"; import {deleteGangDisplayContent} from "./Gang"; import {Locations} from "./Location"; import { Message } from "./Message/Message"; @@ -30,7 +31,8 @@ import { AllServers, prestigeAllServers } from "./Server/AllServers"; import { Server } from "./Server/Server" import { prestigeHomeComputer } from "./Server/ServerHelpers"; -import { updateSourceFileFlags } from "./SourceFile/SourceFileFlags"; +import { SourceFileFlags, + updateSourceFileFlags } from "./SourceFile/SourceFileFlags"; import { SpecialServerIps, SpecialServerIpsMap, prestigeSpecialServerIps, @@ -201,49 +203,45 @@ function prestigeSourceFile() { //Re-create foreign servers initForeignServers(Player.getHomeComputer()); - var srcFile1Owned = false; - for (var i = 0; i < Player.sourceFiles.length; ++i) { - if (Player.sourceFiles[i].n == 1) { - srcFile1Owned = true; - } - } - if (srcFile1Owned) { + if (SourceFileFlags[9] >= 2) { + homeComp.setMaxRam(128); + } else if (SourceFileFlags[1] > 0) { homeComp.setMaxRam(32); } else { homeComp.setMaxRam(8); } homeComp.cpuCores = 1; - //Reset favor for Companies + // Reset favor for Companies for (var member in Companies) { if (Companies.hasOwnProperty(member)) { Companies[member].favor = 0; } } - //Reset favor for factions + // Reset favor for factions for (var member in Factions) { if (Factions.hasOwnProperty(member)) { Factions[member].favor = 0; } } - //Stop a Terminal action if there is one + // Stop a Terminal action if there is one if (Engine._actionInProgress) { Engine._actionInProgress = false; Terminal.finishAction(true); } - //Delete all Augmentations + // Delete all Augmentations for (var name in Augmentations) { if (Augmentations.hasOwnProperty(name)) { delete Augmentations[name]; } } - //Re-initialize things - This will update any changes - initFactions(); //Factions must be initialized before augmentations - initAugmentations(); //Calls reapplyAllAugmentations() and resets Player multipliers + // Re-initialize things - This will update any changes + initFactions(); // Factions must be initialized before augmentations + initAugmentations(); // Calls reapplyAllAugmentations() and resets Player multipliers Player.reapplyAllSourceFiles(); initCompanies(); @@ -325,7 +323,7 @@ function prestigeSourceFile() { dialogBoxCreate("Visit VitaLife in New Tokyo if you'd like to purchase a new sleeve!"); } - //Reset Stock market, gang, and corporation + // Reset Stock market, gang, and corporation if (Player.hasWseAccount) { initStockMarket(); initSymbolToStockMap(); @@ -341,6 +339,16 @@ function prestigeSourceFile() { Player.corporation = null; resetIndustryResearchTrees(); Player.bladeburner = null; + // Source-File 9 (level 3) effect + if (SourceFileFlags[9] >= 3) { + const hserver = createHacknetServer(); + hserver.level = 100; + hserver.cores = 10; + hserver.cache = 5; + hserver.updateHashRate(Player); + hserver.updateHashCapacity(); + Player.hashManager.updateCapacity(Player); + } // Refresh Main Menu (the 'World' menu, specifically) document.getElementById("world-menu-header").click(); diff --git a/src/ScriptEditor/AceNetscriptMode.js b/src/ScriptEditor/AceNetscriptMode.js index 15873e07c..9061f45f1 100644 --- a/src/ScriptEditor/AceNetscriptMode.js +++ b/src/ScriptEditor/AceNetscriptMode.js @@ -101,8 +101,8 @@ let NetscriptFunctions = // Hacknet Node API "hacknet|numNodes|purchaseNode|getPurchaseNodeCost|getNodeStats|" + - "upgradeLevel|upgradeRam|upgradeCore|getLevelUpgradeCost|" + - "getRamUpgradeCost|getCoreUpgradeCost|" + + "upgradeLevel|upgradeRam|upgradeCore|upgradeCache|getLevelUpgradeCost|" + + "getRamUpgradeCost|getCoreUpgradeCost|getCacheUpgradeCost|" + // Gang API "gang|" + diff --git a/src/ScriptEditor/CodeMirrorNetscriptMode.js b/src/ScriptEditor/CodeMirrorNetscriptMode.js index fed212ac8..a240edf1e 100644 --- a/src/ScriptEditor/CodeMirrorNetscriptMode.js +++ b/src/ScriptEditor/CodeMirrorNetscriptMode.js @@ -177,9 +177,11 @@ CodeMirror.defineMode("netscript", function(config, parserConfig) { "upgradeLevel": atom, "upgradeRam": atom, "upgradeCore": atom, + "upgradeCache": atom, "getLevelUpgradeCost": atom, "getRamUpgradeCost": atom, "getCoreUpgradeCost": atom, + "getCacheUpgradeCost": atom, // Netscript Gang API "gang": atom, diff --git a/src/SourceFile.js b/src/SourceFile.js index 63a9f0a02..168087800 100644 --- a/src/SourceFile.js +++ b/src/SourceFile.js @@ -62,7 +62,12 @@ function initSourceFiles() { "Level 3: Ability to use limit/stop orders in other BitNodes

    " + "This Source-File also increases your hacking growth multipliers by: " + "
    Level 1: 12%
    Level 2: 18%
    Level 3: 21%"); - SourceFiles["SourceFile9"] = new SourceFile(9); + SourceFiles["SourceFile9"] = new SourceFile(9, "This Source-File grants the following benefits:

    " + + "Level 1: Permanently unlocks the Hacknet Server in other BitNodes
    " + + "Level 2: You start with 128GB of RAM on your home computer when entering a new BitNode
    " + + "Level 3: Grants a highly-upgraded Hacknet Server when entering a new BitNode

    " + + "(Note that the Level 3 effect of this Source-File only applies when entering a new BitNode, NOT " + + "when installing Augmentations)"); SourceFiles["SourceFile10"] = new SourceFile(10, "This Source-File unlocks Sleeve technology in other BitNodes. Each level of this " + "Source-File also grants you a Duplicate Sleeve"); SourceFiles["SourceFile11"] = new SourceFile(11, "This Source-File makes it so that company favor increases BOTH the player's salary and reputation gain rate " + @@ -119,7 +124,7 @@ function applySourceFile(srcFile) { Player.hacknet_node_level_cost_mult *= decMult; Player.work_money_mult *= incMult; break; - case 2: //Rise of the Underworld + case 2: // Rise of the Underworld var mult = 0; for (var i = 0; i < srcFile.lvl; ++i) { mult += (24 / (Math.pow(2, i))); @@ -129,7 +134,7 @@ function applySourceFile(srcFile) { Player.crime_success_mult *= incMult; Player.charisma_mult *= incMult; break; - case 3: //Corporatocracy + case 3: // Corporatocracy var mult = 0; for (var i = 0; i < srcFile.lvl; ++i) { mult += (8 / (Math.pow(2, i))); @@ -138,10 +143,10 @@ function applySourceFile(srcFile) { Player.charisma_mult *= incMult; Player.work_money_mult *= incMult; break; - case 4: //The Singularity - //No effects, just gives access to Singularity functions + case 4: // The Singularity + // No effects, just gives access to Singularity functions break; - case 5: //Artificial Intelligence + case 5: // Artificial Intelligence var mult = 0; for (var i = 0; i < srcFile.lvl; ++i) { mult += (8 / (Math.pow(2, i))); @@ -154,7 +159,7 @@ function applySourceFile(srcFile) { Player.hacking_mult *= incMult; Player.hacking_exp_mult *= incMult; break; - case 6: //Bladeburner + case 6: // Bladeburner var mult = 0; for (var i = 0; i < srcFile.lvl; ++i) { mult += (8 / (Math.pow(2, i))); @@ -169,7 +174,7 @@ function applySourceFile(srcFile) { Player.dexterity_mult *= incMult; Player.agility_mult *= incMult; break; - case 7: //Bladeburner 2079 + case 7: // Bladeburner 2079 var mult = 0; for (var i = 0; i < srcFile.lvl; ++i) { mult += (8 / (Math.pow(2, i))); @@ -180,7 +185,7 @@ function applySourceFile(srcFile) { Player.bladeburner_analysis_mult *= incMult; Player.bladeburner_success_chance_mult *= incMult; break; - case 8: //Ghost of Wall Street + case 8: // Ghost of Wall Street var mult = 0; for (var i = 0; i < srcFile.lvl; ++i) { mult += (12 / (Math.pow(2, i))); @@ -188,10 +193,13 @@ function applySourceFile(srcFile) { var incMult = 1 + (mult / 100); Player.hacking_grow_mult *= incMult; break; + case 9: // Hacktocracy + // This has non-multiplier effects + break; case 10: // Digital Carbon // No effects, just grants sleeves break; - case 11: //The Big Crash + case 11: // The Big Crash var mult = 0; for (var i = 0; i < srcFile.lvl; ++i) { mult += (32 / (Math.pow(2, i))); @@ -200,7 +208,7 @@ function applySourceFile(srcFile) { Player.work_money_mult *= incMult; Player.company_rep_mult *= incMult; break; - case 12: //The Recursion + case 12: // The Recursion var inc = Math.pow(1.01, srcFile.lvl); var dec = Math.pow(0.99, srcFile.lvl); From b6b6d8e9fab979df2c09bda7e4a58aa14106e6ae Mon Sep 17 00:00:00 2001 From: danielyxie Date: Sat, 30 Mar 2019 17:39:37 -0700 Subject: [PATCH 15/17] Fixed bug with purchasing Hacknet Servers not updating hash capacity when done through Netscript --- src/Hacknet/HacknetHelpers.jsx | 3 ++- src/Hacknet/ui/Root.jsx | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Hacknet/HacknetHelpers.jsx b/src/Hacknet/HacknetHelpers.jsx index 29f85a8a1..9bfe33fcb 100644 --- a/src/Hacknet/HacknetHelpers.jsx +++ b/src/Hacknet/HacknetHelpers.jsx @@ -75,6 +75,7 @@ export function purchaseHacknet() { } /* END INTERACTIVE TUTORIAL */ + const numOwned = Player.hacknetNodes.length; if (hasHacknetServers()) { const cost = getCostOfNextHacknetServer(); if (isNaN(cost)) { @@ -84,6 +85,7 @@ export function purchaseHacknet() { if (!Player.canAfford(cost)) { return -1; } Player.loseMoney(cost); const server = createHacknetServer(); + Player.hashManager.updateCapacity(Player); return numOwned; } else { @@ -95,7 +97,6 @@ export function purchaseHacknet() { if (!Player.canAfford(cost)) { return -1; } // Auto generate a name for the Node - const numOwned = Player.hacknetNodes.length; const name = "hacknet-node-" + numOwned; const node = new HacknetNode(name); node.updateMoneyGainRate(Player); diff --git a/src/Hacknet/ui/Root.jsx b/src/Hacknet/ui/Root.jsx index 32a9a0694..7c21d400b 100644 --- a/src/Hacknet/ui/Root.jsx +++ b/src/Hacknet/ui/Root.jsx @@ -89,7 +89,6 @@ export class HacknetRoot extends React.Component { const purchaseOnClick = () => { if (purchaseHacknet() >= 0) { this.recalculateTotalProduction(); - Player.hashManager.updateCapacity(Player); } } From 804e4c23e31fb3cdc163068a5f97acec9cdf8546 Mon Sep 17 00:00:00 2001 From: danielyxie Date: Sat, 30 Mar 2019 19:53:57 -0700 Subject: [PATCH 16/17] Updated Hacknet Node API documentation for the BN-9 changes. netscript functions now properly fail for Hacknet Servers --- .../hacknetnodeapi/getCacheUpgradeCost.rst | 17 +++ .../netscript/hacknetnodeapi/getNodeStats.rst | 11 +- .../netscript/hacknetnodeapi/upgradeCache.rst | 19 +++ .../netscript/netscripthacknetnodeapi.rst | 61 ++------- src/NetscriptFunctions.js | 127 ++++++++---------- 5 files changed, 117 insertions(+), 118 deletions(-) create mode 100644 doc/source/netscript/hacknetnodeapi/getCacheUpgradeCost.rst create mode 100644 doc/source/netscript/hacknetnodeapi/upgradeCache.rst diff --git a/doc/source/netscript/hacknetnodeapi/getCacheUpgradeCost.rst b/doc/source/netscript/hacknetnodeapi/getCacheUpgradeCost.rst new file mode 100644 index 000000000..f59bec28b --- /dev/null +++ b/doc/source/netscript/hacknetnodeapi/getCacheUpgradeCost.rst @@ -0,0 +1,17 @@ +getCacheUpgradeCost() Netscript Function +======================================== + +.. warning:: This page contains spoilers for the game + +.. js:function:: getCacheUpgradeCost(i, n) + + :param number i: Index/Identifier of Hacknet Node. :ref:`See here for details ` + :param number n: Number of times to upgrade cache. Must be positive. Rounded to nearest integer + + .. note:: This function is only applicable for Hacknet Servers (the upgraded version of + a Hacknet Node). + + Returns the cost of upgrading the cache level of the specified Hacknet Server by *n*. + + If an invalid value for *n* is provided, then this function returns 0. If the + specified Hacknet Server is already at the max cache level, then Infinity is returned. diff --git a/doc/source/netscript/hacknetnodeapi/getNodeStats.rst b/doc/source/netscript/hacknetnodeapi/getNodeStats.rst index 74b7de5ad..e538edc40 100644 --- a/doc/source/netscript/hacknetnodeapi/getNodeStats.rst +++ b/doc/source/netscript/hacknetnodeapi/getNodeStats.rst @@ -1,6 +1,8 @@ getNodeStats() Netscript Function ================================= +.. warning:: This page contains spoilers for the game + .. js:function:: getNodeStats(i) :param number i: Index/Identifier of Hacknet Node. :ref:`See here for details ` @@ -12,7 +14,12 @@ getNodeStats() Netscript Function level: Node's level, ram: Node's RAM, cores: Node's number of cores, - production: Node's money earned per second, + cache: Cache level. Only applicable for Hacknet Servers + production: Node's production per second timeOnline: Number of seconds since Node has been purchased, - totalProduction: Total number of money Node has produced + totalProduction: Total amount that the Node has produced } + + .. note:: Note that for Hacknet Nodes, production refers to the amount of money the node generates. + For Hacknet Servers (the upgraded version of Hacknet Nodes), production refers to the amount + of hashes the node generates. diff --git a/doc/source/netscript/hacknetnodeapi/upgradeCache.rst b/doc/source/netscript/hacknetnodeapi/upgradeCache.rst new file mode 100644 index 000000000..8825d9ace --- /dev/null +++ b/doc/source/netscript/hacknetnodeapi/upgradeCache.rst @@ -0,0 +1,19 @@ +upgradeCache() Netscript Function +================================= + +.. warning:: This page contains spoilers for the game + +.. js:function:: upgradeCache(i, n) + + :param number i: Index/Identifier of Hacknet Node. :ref:`See here for details ` + :param number n: Number of cache levels to purchase. Must be positive. Rounded to nearest integer + + .. note:: This function is only applicable for Hacknet Servers (the upgraded version of + a Hacknet Node). + + Tries to upgrade the specified Hacknet Server's cache *n* times. + + Returns true if it successfully upgrades the Server's cache *n* times, or if + it purchases some positive amount and the Server reaches its max cache level. + + Returns false otherwise. diff --git a/doc/source/netscript/netscripthacknetnodeapi.rst b/doc/source/netscript/netscripthacknetnodeapi.rst index fde650836..1c1353d81 100644 --- a/doc/source/netscript/netscripthacknetnodeapi.rst +++ b/doc/source/netscript/netscripthacknetnodeapi.rst @@ -31,9 +31,11 @@ In :ref:`netscriptjs`:: upgradeLevel() upgradeRam() upgradeCore() + upgradeCache() getLevelUpgradeCost() getRamUpgradeCost() getCoreUpgradeCost() + getCacheUpgradeCost() .. _netscript_hacknetnodeapi_referencingahacknetnode: @@ -68,23 +70,25 @@ The following is an example of one way a script can be used to automate the purchasing and upgrading of Hacknet Nodes. This script attempts to purchase Hacknet Nodes until the player has a total of 8. Then -it gradually upgrades those Node's to a minimum of level 140, 64 GB RAM, and 8 cores:: +it gradually upgrades those Node's to a minimum of level 140, 64 GB RAM, and 8 cores + +.. code:: javascript function myMoney() { - return getServerMoneyAvailable("home");() - } - }() + return getServerMoneyAvailable("home"); + } + disableLog("getServerMoneyAvailable"); disableLog("sleep"); - cnt = 8; + var cnt = 8; while(hacknet.numNodes() < cnt) { res = hacknet.purchaseNode(); print("Purchased hacknet Node with index " + res); }; - for (i = 0; i < cnt; i++) { + for (var i = 0; i < cnt; i++) { while (hacknet.getNodeStats(i).level <= 80) { var cost = hacknet.getLevelUpgradeCost(i, 10); while (myMoney() < cost) { @@ -95,9 +99,9 @@ it gradually upgrades those Node's to a minimum of level 140, 64 GB RAM, and 8 c }; }; - print("All nodes upgrade to level 80"); + print("All nodes upgraded to level 80"); - for (i = 0; i < cnt; i++) { + for (var i = 0; i < cnt; i++) { while (hacknet.getNodeStats(i).ram < 16) { var cost = hacknet.getRamUpgradeCost(i, 2); while (myMoney() < cost) { @@ -108,43 +112,4 @@ it gradually upgrades those Node's to a minimum of level 140, 64 GB RAM, and 8 c }; }; - print("All nodes upgrade to 16GB RAM"); - - for (i = 0; i < cnt; i++) { - while (hacknet.getNodeStats(i).level <= 140) { - var cost = hacknet.getLevelUpgradeCost(i, 5); - while (myMoney() < cost) { - print("Need $" + cost + " . Have $" + myMoney()); - sleep(3000); - } - res = hacknet.upgradeLevel(i, 5); - }; - }; - - print("All nodes upgrade to level 140"); - - for (i = 0; i < cnt; i++) { - while (hacknet.getNodeStats(i).ram < 64) { - var cost = hacknet.getRamUpgradeCost(i, 2); - while (myMoney() < cost) { - print("Need $" + cost + " . Have $" + myMoney()); - sleep(3000); - } - res = hacknet.upgradeRam(i, 2); - }; - }; - - print("All nodes upgrade to 64GB RAM (MAX)"); - - for (i = 0; i < cnt; i++) { - while (hacknetnodes.getNodeStatsi(i).cores < 8) { - var cost = hacknet.getCoreUpgradeCost(7); - while (myMoney() < cost) { - print("Need $" + cost + " . Have $" + myMoney()); - sleep(3000); - } - res = hacknet.upgradeCore(i, 7); - }; - }; - - print("All nodes upgrade to 8 cores"); + print("All nodes upgraded to 16GB RAM"); diff --git a/src/NetscriptFunctions.js b/src/NetscriptFunctions.js index afed96696..76b6dedfa 100644 --- a/src/NetscriptFunctions.js +++ b/src/NetscriptFunctions.js @@ -37,6 +37,7 @@ import { getCostOfNextHacknetNode, getCostOfNextHacknetServer, hasHacknetServers, purchaseHacknet } from "./Hacknet/HacknetHelpers"; +import { HacknetServer } from "./Hacknet/HacknetServer"; import {Locations} from "./Locations"; import { Message } from "./Message/Message"; import { Messages } from "./Message/MessageHelpers"; @@ -234,16 +235,34 @@ function NetscriptFunctions(workerScript) { * Gets the Server for a specific hostname/ip, throwing an error * if the server doesn't exist. * @param {string} Hostname or IP of the server + * @param {string} callingFnName - Name of calling function. For logging purposes * @returns {Server} The specified Server */ const safeGetServer = function(ip, callingFnName="") { var server = getServer(ip); if (server == null) { + workerScript.log(`ERROR: Invalid IP or hostname passed into ${callingFnName}()`); throw makeRuntimeRejectMsg(workerScript, `Invalid IP or hostname passed into ${callingFnName}() function`); } return server; } + /** + * Used to fail a function if the function's target is a Hacknet Server. + * This is used for functions that should run on normal Servers, but not Hacknet Servers + * @param {Server} server - Target server + * @param {string} callingFn - Name of calling function. For logging purposes + * @returns {boolean} True if the server is a Hacknet Server, false otherwise + */ + const failOnHacknetServer = function(server, callingFn="") { + if (server instanceof HacknetServer) { + workerScript.log(`ERROR: ${callingFn}() failed because it does not work on Hacknet Servers`); + return true; + } else { + return false; + } + } + // Utility function to get Hacknet Node object const getHacknetNode = function(i) { if (isNaN(i)) { @@ -1341,25 +1360,22 @@ function NetscriptFunctions(workerScript) { let copy = Object.assign({}, BitNodeMultipliers); return copy; }, - getServerMoneyAvailable : function(ip){ + getServerMoneyAvailable : function(ip) { if (workerScript.checkingRam) { return updateStaticRam("getServerMoneyAvailable", CONSTANTS.ScriptGetServerRamCost); } updateDynamicRam("getServerMoneyAvailable", CONSTANTS.ScriptGetServerRamCost); - var server = getServer(ip); - if (server == null) { - workerScript.scriptRef.log("getServerMoneyAvailable() failed. Invalid IP or hostname passed in: " + ip); - throw makeRuntimeRejectMsg(workerScript, "getServerMoneyAvailable() failed. Invalid IP or hostname passed in: " + ip); - } + const server = safeGetServer(ip, "getServerMoneyAvailable"); + if (failOnHacknetServer(server, "getServerMoneyAvailable")) { return 0; } if (server.hostname == "home") { - //Return player's money - if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.getServerMoneyAvailable == null) { - workerScript.scriptRef.log("getServerMoneyAvailable('home') returned player's money: $" + formatNumber(Player.money.toNumber(), 2)); + // Return player's money + if (workerScript.shouldLog("getServerMoneyAvailable")) { + workerScript.log("getServerMoneyAvailable('home') returned player's money: $" + formatNumber(Player.money.toNumber(), 2)); } return Player.money.toNumber(); } - if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.getServerMoneyAvailable == null) { - workerScript.scriptRef.log("getServerMoneyAvailable() returned " + formatNumber(server.moneyAvailable, 2) + " for " + server.hostname); + if (workerScript.shouldLog("getServerMoneyAvailable")) { + workerScript.log("getServerMoneyAvailable() returned " + formatNumber(server.moneyAvailable, 2) + " for " + server.hostname); } return server.moneyAvailable; }, @@ -1368,13 +1384,10 @@ function NetscriptFunctions(workerScript) { return updateStaticRam("getServerSecurityLevel", CONSTANTS.ScriptGetServerRamCost); } updateDynamicRam("getServerSecurityLevel", CONSTANTS.ScriptGetServerRamCost); - var server = getServer(ip); - if (server == null) { - workerScript.scriptRef.log("getServerSecurityLevel() failed. Invalid IP or hostname passed in: " + ip); - throw makeRuntimeRejectMsg(workerScript, "getServerSecurityLevel() failed. Invalid IP or hostname passed in: " + ip); - } - if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.getServerSecurityLevel == null) { - workerScript.scriptRef.log("getServerSecurityLevel() returned " + formatNumber(server.hackDifficulty, 3) + " for " + server.hostname); + const server = safeGetServer(ip, "getServerSecurityLevel"); + if (failOnHacknetServer(server, "getServerSecurityLevel")) { return 1; } + if (workerScript.shouldLog("getServerSecurityLevel")) { + workerScript.log("getServerSecurityLevel() returned " + formatNumber(server.hackDifficulty, 3) + " for " + server.hostname); } return server.hackDifficulty; }, @@ -1383,13 +1396,10 @@ function NetscriptFunctions(workerScript) { return updateStaticRam("getServerBaseSecurityLevel", CONSTANTS.ScriptGetServerRamCost); } updateDynamicRam("getServerBaseSecurityLevel", CONSTANTS.ScriptGetServerRamCost); - var server = getServer(ip); - if (server == null) { - workerScript.scriptRef.log("getServerBaseSecurityLevel() failed. Invalid IP or hostname passed in: " + ip); - throw makeRuntimeRejectMsg(workerScript, "getServerBaseSecurityLevel() failed. Invalid IP or hostname passed in: " + ip); - } - if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.getServerBaseSecurityLevel == null) { - workerScript.scriptRef.log("getServerBaseSecurityLevel() returned " + formatNumber(server.baseDifficulty, 3) + " for " + server.hostname); + const server = safeGetServer(ip, "getServerBaseSecurityLevel"); + if (failOnHacknetServer(server, "getServerBaseSecurityLevel")) { return 1; } + if (workerScript.shouldLog("getServerBaseSecurityLevel")) { + workerScript.log("getServerBaseSecurityLevel() returned " + formatNumber(server.baseDifficulty, 3) + " for " + server.hostname); } return server.baseDifficulty; }, @@ -1398,13 +1408,10 @@ function NetscriptFunctions(workerScript) { return updateStaticRam("getServerMinSecurityLevel", CONSTANTS.ScriptGetServerRamCost); } updateDynamicRam("getServerMinSecurityLevel", CONSTANTS.ScriptGetServerRamCost); - var server = getServer(ip); - if (server == null) { - workerScript.scriptRef.log("getServerMinSecurityLevel() failed. Invalid IP or hostname passed in: " + ip); - throw makeRuntimeRejectMsg(workerScript, "getServerMinSecurityLevel() failed. Invalid IP or hostname passed in: " + ip); - } - if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.getServerMinSecurityLevel == null) { - workerScript.scriptRef.log("getServerMinSecurityLevel() returned " + formatNumber(server.minDifficulty, 3) + " for " + server.hostname); + const server = safeGetServer(ip, "getServerMinSecurityLevel"); + if (failOnHacknetServer(server, "getServerMinSecurityLevel")) { return 1; } + if (workerScript.shouldLog("getServerMinSecurityLevel")) { + workerScript.log("getServerMinSecurityLevel() returned " + formatNumber(server.minDifficulty, 3) + " for " + server.hostname); } return server.minDifficulty; }, @@ -1413,13 +1420,10 @@ function NetscriptFunctions(workerScript) { return updateStaticRam("getServerRequiredHackingLevel", CONSTANTS.ScriptGetServerRamCost); } updateDynamicRam("getServerRequiredHackingLevel", CONSTANTS.ScriptGetServerRamCost); - var server = getServer(ip); - if (server == null) { - workerScript.scriptRef.log("getServerRequiredHackingLevel() failed. Invalid IP or hostname passed in: " + ip); - throw makeRuntimeRejectMsg(workerScript, "getServerRequiredHackingLevel() failed. Invalid IP or hostname passed in: " + ip); - } - if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.getServerRequiredHackingLevel == null) { - workerScript.scriptRef.log("getServerRequiredHackingLevel returned " + formatNumber(server.requiredHackingSkill, 0) + " for " + server.hostname); + const server = safeGetServer(ip, "getServerRequiredHackingLevel"); + if (failOnHacknetServer(server, "getServerRequiredHackingLevel")) { return 1; } + if (workerScript.shouldLog("getServerRequiredHackingLevel")) { + workerScript.log("getServerRequiredHackingLevel returned " + formatNumber(server.requiredHackingSkill, 0) + " for " + server.hostname); } return server.requiredHackingSkill; }, @@ -1428,13 +1432,10 @@ function NetscriptFunctions(workerScript) { return updateStaticRam("getServerMaxMoney", CONSTANTS.ScriptGetServerRamCost); } updateDynamicRam("getServerMaxMoney", CONSTANTS.ScriptGetServerRamCost); - var server = getServer(ip); - if (server == null) { - workerScript.scriptRef.log("getServerMaxMoney() failed. Invalid IP or hostname passed in: " + ip); - throw makeRuntimeRejectMsg(workerScript, "getServerMaxMoney() failed. Invalid IP or hostname passed in: " + ip); - } - if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.getServerMaxMoney == null) { - workerScript.scriptRef.log("getServerMaxMoney() returned " + formatNumber(server.moneyMax, 0) + " for " + server.hostname); + const server = safeGetServer(ip, "getServerMaxMoney"); + if (failOnHacknetServer(server, "getServerMaxMoney")) { return 0; } + if (workerScript.shouldLog("getServerMaxMoney")) { + workerScript.log("getServerMaxMoney() returned " + formatNumber(server.moneyMax, 0) + " for " + server.hostname); } return server.moneyMax; }, @@ -1443,13 +1444,10 @@ function NetscriptFunctions(workerScript) { return updateStaticRam("getServerGrowth", CONSTANTS.ScriptGetServerRamCost); } updateDynamicRam("getServerGrowth", CONSTANTS.ScriptGetServerRamCost); - var server = getServer(ip); - if (server == null) { - workerScript.scriptRef.log("getServerGrowth() failed. Invalid IP or hostname passed in: " + ip); - throw makeRuntimeRejectMsg(workerScript, "getServerGrowth() failed. Invalid IP or hostname passed in: " + ip); - } - if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.getServerGrowth == null) { - workerScript.scriptRef.log("getServerGrowth() returned " + formatNumber(server.serverGrowth, 0) + " for " + server.hostname); + const server = safeGetServer(ip, "getServerGrowth"); + if (failOnHacknetServer(server, "getServerGrowth")) { return 1; } + if (workerScript.shouldLog("getServerGrowth")) { + workerScript.log("getServerGrowth() returned " + formatNumber(server.serverGrowth, 0) + " for " + server.hostname); } return server.serverGrowth; }, @@ -1458,13 +1456,10 @@ function NetscriptFunctions(workerScript) { return updateStaticRam("getServerNumPortsRequired", CONSTANTS.ScriptGetServerRamCost); } updateDynamicRam("getServerNumPortsRequired", CONSTANTS.ScriptGetServerRamCost); - var server = getServer(ip); - if (server == null) { - workerScript.scriptRef.log("getServerNumPortsRequired() failed. Invalid IP or hostname passed in: " + ip); - throw makeRuntimeRejectMsg(workerScript, "getServerNumPortsRequired() failed. Invalid IP or hostname passed in: " + ip); - } - if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.getServerNumPortsRequired == null) { - workerScript.scriptRef.log("getServerNumPortsRequired() returned " + formatNumber(server.numOpenPortsRequired, 0) + " for " + server.hostname); + const server = safeGetServer(ip, "getServerNumPortsRequired"); + if (failOnHacknetServer(server, "getServerNumPortsRequired")) { return 5; } + if (workerScript.shouldLog("getServerNumPortsRequired")) { + workerScript.log("getServerNumPortsRequired() returned " + formatNumber(server.numOpenPortsRequired, 0) + " for " + server.hostname); } return server.numOpenPortsRequired; }, @@ -1473,13 +1468,9 @@ function NetscriptFunctions(workerScript) { return updateStaticRam("getServerRam", CONSTANTS.ScriptGetServerRamCost); } updateDynamicRam("getServerRam", CONSTANTS.ScriptGetServerRamCost); - var server = getServer(ip); - if (server == null) { - workerScript.scriptRef.log("getServerRam() failed. Invalid IP or hostname passed in: " + ip); - throw makeRuntimeRejectMsg(workerScript, "getServerRam() failed. Invalid IP or hostname passed in: " + ip); - } - if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.getServerRam == null) { - workerScript.scriptRef.log("getServerRam() returned [" + formatNumber(server.maxRam, 2) + "GB, " + formatNumber(server.ramUsed, 2) + "GB]"); + const server = safeGetServer(ip, "getServerRam"); + if (workerScript.shouldLog("getServerRam")) { + workerScript.log("getServerRam() returned [" + formatNumber(server.maxRam, 2) + "GB, " + formatNumber(server.ramUsed, 2) + "GB]"); } return [server.maxRam, server.ramUsed]; }, @@ -4771,7 +4762,7 @@ function NetscriptFunctions(workerScript) { answer = String(answer); } - const serv = safeGetServer(ip, "codingcontract.attempt()"); + const serv = safeGetServer(ip, "codingcontract.attempt"); if (contract.isSolution(answer)) { const reward = Player.gainCodingContractReward(contract.reward, contract.getDifficulty()); workerScript.log(`Successfully completed Coding Contract ${fn}. Reward: ${reward}`); From 36499ae9f2ddb2bfd07be4a2ef88bd9496245ffb Mon Sep 17 00:00:00 2001 From: danielyxie Date: Wed, 3 Apr 2019 16:58:15 -0700 Subject: [PATCH 17/17] Fixed bug where sleeves's exp didnt properly reset on prestige. Updated versions to v0.46.0. Added production build --- dist/engine.bundle.js | 2 +- dist/engine.css | 125 ++++++++++++++------------- dist/vendor.bundle.js | 130 ++++++++++++++--------------- doc/source/changelog.rst | 18 ++++ doc/source/conf.py | 4 +- index.html | 30 +------ src/Constants.ts | 2 +- src/PersonObjects/Sleeve/Sleeve.ts | 6 ++ 8 files changed, 159 insertions(+), 158 deletions(-) diff --git a/dist/engine.bundle.js b/dist/engine.bundle.js index 409ff5b4d..8bc8866c1 100644 --- a/dist/engine.bundle.js +++ b/dist/engine.bundle.js @@ -1,2 +1,2 @@ -!function(e){function t(t){for(var a,o,s=t[0],l=t[1],c=t[2],p=0,m=[];p=100?this.sleeves[e].synchronize(this):this.sleeves[e].shockRecovery(this));this.isWorking=!1,this.currentWorkFactionName="",this.currentWorkFactionDescription="",this.createProgramName="",this.className="",this.crimeType="",this.workHackExpGainRate=0,this.workStrExpGainRate=0,this.workDefExpGainRate=0,this.workDexExpGainRate=0,this.workAgiExpGainRate=0,this.workChaExpGainRate=0,this.workRepGainRate=0,this.workMoneyGainRate=0,this.workHackExpGained=0,this.workStrExpGained=0,this.workDefExpGained=0,this.workDexExpGained=0,this.workAgiExpGained=0,this.workChaExpGained=0,this.workRepGained=0,this.workMoneyGained=0,this.timeWorked=0,this.lastUpdate=(new Date).getTime(),this.playtimeSinceLastAug=0,this.scriptProdSinceLastAug=0,this.moneySourceA.reset(),this.hacknetNodes.length=0,this.updateSkillLevels(),this.hp=this.max_hp},K.prototype.prestigeSourceFile=function(){var e=this.getHomeComputer();this.currentServer=e.ip,this.homeComputer=e.ip,this.numPeopleKilled=0,this.karma=0,this.hacking_skill=1,this.strength=1,this.defense=1,this.dexterity=1,this.agility=1,this.charisma=1,this.hacking_exp=0,this.strength_exp=0,this.defense_exp=0,this.dexterity_exp=0,this.agility_exp=0,this.charisma_exp=0,this.money=new L.a(1e3),this.city=S.Locations.Sector12,this.location="",this.companyName="",this.jobs={},this.purchasedServers=[],this.factions=[],this.factionInvitations=[],this.queuedAugmentations=[],this.augmentations=[],this.resleeves=[],this.sleeves.length=I.SourceFileFlags[10]+this.sleevesFromCovenant;for(let e=0;e0?this.intelligence=Math.floor(this.calculateSkill(this.intelligence_exp)):this.intelligence=0;var e=this.hp/this.max_hp;this.max_hp=Math.floor(10+this.defense/10),$.hp=Math.round(this.max_hp*e)},K.prototype.resetMultipliers=function(){this.hacking_chance_mult=1,this.hacking_speed_mult=1,this.hacking_money_mult=1,this.hacking_grow_mult=1,this.hacking_mult=1,this.strength_mult=1,this.defense_mult=1,this.dexterity_mult=1,this.agility_mult=1,this.charisma_mult=1,this.hacking_exp_mult=1,this.strength_exp_mult=1,this.defense_exp_mult=1,this.dexterity_exp_mult=1,this.agility_exp_mult=1,this.charisma_exp_mult=1,this.company_rep_mult=1,this.faction_rep_mult=1,this.crime_money_mult=1,this.crime_success_mult=1,this.hacknet_node_money_mult=1,this.hacknet_node_purchase_cost_mult=1,this.hacknet_node_ram_cost_mult=1,this.hacknet_node_core_cost_mult=1,this.hacknet_node_level_cost_mult=1,this.work_money_mult=1,this.bladeburner_max_stamina_mult=1,this.bladeburner_stamina_gain_mult=1,this.bladeburner_analysis_mult=1,this.bladeburner_success_chance_mult=1},K.prototype.hasProgram=function(e){var t=$.getHomeComputer();if(null==t)return!1;for(var n=0;n0)&&(this.intelligence_exp+=e)},K.prototype.queryStatFromString=function(e){const t=e.toLowerCase();return t.includes("hack")?$.hacking_skill:t.includes("str")?$.strength:t.includes("def")?$.defense:t.includes("dex")?$.dexterity:t.includes("agi")?$.agility:t.includes("cha")?$.charisma:t.includes("int")?$.intelligence:void 0},K.prototype.resetWorkStatus=function(){this.workHackExpGainRate=0,this.workStrExpGainRate=0,this.workDefExpGainRate=0,this.workDexExpGainRate=0,this.workAgiExpGainRate=0,this.workChaExpGainRate=0,this.workRepGainRate=0,this.workMoneyGainRate=0,this.workMoneyLossRate=0,this.workHackExpGained=0,this.workStrExpGained=0,this.workDefExpGained=0,this.workDexExpGained=0,this.workAgiExpGained=0,this.workChaExpGained=0,this.workRepGained=0,this.workMoneyGained=0,this.timeWorked=0,this.timeWorkedCreateProgram=0,this.currentWorkFactionName="",this.currentWorkFactionDescription="",this.createProgramName="",this.className="",document.getElementById("work-in-progress-text").innerHTML=""},K.prototype.processWorkEarnings=function(e=1){const t=this.workHackExpGainRate*e,n=this.workStrExpGainRate*e,a=this.workDefExpGainRate*e,i=this.workDexExpGainRate*e,r=this.workAgiExpGainRate*e,o=this.workChaExpGainRate*e,s=(this.workMoneyGainRate-this.workMoneyLossRate)*e;this.gainHackingExp(t),this.gainStrengthExp(n),this.gainDefenseExp(a),this.gainDexterityExp(i),this.gainAgilityExp(r),this.gainCharismaExp(o),this.gainMoney(s),this.recordMoneySource(s,"work"),this.workHackExpGained+=t,this.workStrExpGained+=n,this.workDefExpGained+=a,this.workDexExpGained+=i,this.workAgiExpGained+=r,this.workChaExpGained+=o,this.workRepGained+=this.workRepGainRate*e,this.workMoneyGained+=this.workMoneyGainRate*e,this.workMoneyGained-=this.workMoneyLossRate*e},K.prototype.startWork=function(e){this.resetWorkStatus(),this.isWorking=!0,this.companyName=e,this.workType=_.CONSTANTS.WorkTypeCompany,this.workHackExpGainRate=this.getWorkHackExpGain(),this.workStrExpGainRate=this.getWorkStrExpGain(),this.workDefExpGainRate=this.getWorkDefExpGain(),this.workDexExpGainRate=this.getWorkDexExpGain(),this.workAgiExpGainRate=this.getWorkAgiExpGain(),this.workChaExpGainRate=this.getWorkChaExpGain(),this.workRepGainRate=this.getWorkRepGain(),this.workMoneyGainRate=this.getWorkMoneyGain(),this.timeNeededToCompleteWork=_.CONSTANTS.MillisecondsPer8Hours;var t=Object(j.clearEventListeners)("work-in-progress-cancel-button");t.innerHTML="Cancel Work",t.addEventListener("click",function(){return $.finishWork(!0),!1}),E.Engine.loadWorkInProgressContent()},K.prototype.work=function(e){var t=!1;if(this.timeWorked+E.Engine._idleSpeed*e>=_.CONSTANTS.MillisecondsPer8Hours&&(t=!0,e=Math.round((_.CONSTANTS.MillisecondsPer8Hours-this.timeWorked)/E.Engine._idleSpeed)),this.timeWorked+=E.Engine._idleSpeed*e,this.workRepGainRate=this.getWorkRepGain(),this.processWorkEarnings(e),t||this.timeWorked>=_.CONSTANTS.MillisecondsPer8Hours)return this.finishWork(!1);var n=p.Companies[this.companyName],a="0";null!=n&&n instanceof u.Company?a=n.playerReputation:console.error(`Could not find Company: ${this.companyName}`);const i=this.jobs[this.companyName];document.getElementById("work-in-progress-text").innerHTML="You are currently working as a "+i+" at "+this.companyName+" (Current Company Reputation: "+D.numeralWrapper.format(a,"0,0")+")

    You have been working for "+Object(H.convertTimeMsToTimeElapsedString)(this.timeWorked)+"

    You have earned:

    $"+D.numeralWrapper.format(this.workMoneyGained,"0,0.00")+" ($"+D.numeralWrapper.format(this.workMoneyGainRate*G,"0,0.00")+" / sec)

    "+D.numeralWrapper.format(this.workRepGained,"0,0.0000")+" ("+D.numeralWrapper.format(this.workRepGainRate*G,"0,0.0000")+" / sec) reputation for this company

    "+D.numeralWrapper.format(this.workHackExpGained,"0,0.0000")+" ("+D.numeralWrapper.format(this.workHackExpGainRate*G,"0,0.0000")+" / sec) hacking exp

    "+D.numeralWrapper.format(this.workStrExpGained,"0,0.0000")+" ("+D.numeralWrapper.format(this.workStrExpGainRate*G,"0,0.0000")+" / sec) strength exp
    "+D.numeralWrapper.format(this.workDefExpGained,"0,0.0000")+" ("+D.numeralWrapper.format(this.workDefExpGainRate*G,"0,0.0000")+" / sec) defense exp
    "+D.numeralWrapper.format(this.workDexExpGained,"0,0.0000")+" ("+D.numeralWrapper.format(this.workDexExpGainRate*G,"0,0.0000")+" / sec) dexterity exp
    "+D.numeralWrapper.format(this.workAgiExpGained,"0,0.0000")+" ("+D.numeralWrapper.format(this.workAgiExpGainRate*G,"0,0.0000")+" / sec) agility exp

    "+D.numeralWrapper.format(this.workChaExpGained,"0,0.0000")+" ("+D.numeralWrapper.format(this.workChaExpGainRate*G,"0,0.0000")+" / sec) charisma exp

    You will automatically finish after working for 8 hours. You can cancel earlier if you wish, but you will only gain half of the reputation you've earned so far."},K.prototype.finishWork=function(e,t=!1){e&&(this.workRepGained/=2),p.Companies[this.companyName].playerReputation+=this.workRepGained,this.updateSkillLevels();var n="You earned a total of:
    $"+D.numeralWrapper.format(this.workMoneyGained,"0,0.00")+"
    "+D.numeralWrapper.format(this.workRepGained,"0,0.0000")+" reputation for the company
    "+D.numeralWrapper.format(this.workHackExpGained,"0,0.0000")+" hacking exp
    "+D.numeralWrapper.format(this.workStrExpGained,"0,0.0000")+" strength exp
    "+D.numeralWrapper.format(this.workDefExpGained,"0,0.0000")+" defense exp
    "+D.numeralWrapper.format(this.workDexExpGained,"0,0.0000")+" dexterity exp
    "+D.numeralWrapper.format(this.workAgiExpGained,"0,0.0000")+" agility exp
    "+D.numeralWrapper.format(this.workChaExpGained,"0,0.0000")+" charisma exp
    ";if(n=e?"You worked a short shift of "+Object(H.convertTimeMsToTimeElapsedString)(this.timeWorked)+"

    Since you cancelled your work early, you only gained half of the reputation you earned.

    "+n:"You worked a full shift of 8 hours!

    "+n,t||Object(W.dialogBoxCreate)(n),document.getElementById("mainmenu-container").style.visibility="visible",this.isWorking=!1,E.Engine.loadLocationContent(),t){var a="You worked a short shift of "+Object(H.convertTimeMsToTimeElapsedString)(this.timeWorked)+" and earned $"+D.numeralWrapper.format(this.workMoneyGained,"0,0.00")+", "+D.numeralWrapper.format(this.workRepGained,"0,0.0000")+" reputation, "+D.numeralWrapper.format(this.workHackExpGained,"0,0.0000")+" hacking exp, "+D.numeralWrapper.format(this.workStrExpGained,"0,0.0000")+" strength exp, "+D.numeralWrapper.format(this.workDefExpGained,"0,0.0000")+" defense exp, "+D.numeralWrapper.format(this.workDexExpGained,"0,0.0000")+" dexterity exp, "+D.numeralWrapper.format(this.workAgiExpGained,"0,0.0000")+" agility exp, and "+D.numeralWrapper.format(this.workChaExpGained,"0,0.0000")+" charisma exp.";return this.resetWorkStatus(),a}this.resetWorkStatus()},K.prototype.startWorkPartTime=function(e){this.resetWorkStatus(),this.isWorking=!0,this.companyName=e,this.workType=_.CONSTANTS.WorkTypeCompanyPartTime,this.workHackExpGainRate=this.getWorkHackExpGain(),this.workStrExpGainRate=this.getWorkStrExpGain(),this.workDefExpGainRate=this.getWorkDefExpGain(),this.workDexExpGainRate=this.getWorkDexExpGain(),this.workAgiExpGainRate=this.getWorkAgiExpGain(),this.workChaExpGainRate=this.getWorkChaExpGain(),this.workRepGainRate=this.getWorkRepGain(),this.workMoneyGainRate=this.getWorkMoneyGain(),this.timeNeededToCompleteWork=_.CONSTANTS.MillisecondsPer8Hours;var t=Object(j.clearEventListeners)("work-in-progress-cancel-button");t.innerHTML="Stop Working",t.addEventListener("click",function(){return $.finishWorkPartTime(),!1}),E.Engine.loadWorkInProgressContent()},K.prototype.workPartTime=function(e){var t=!1;if(this.timeWorked+E.Engine._idleSpeed*e>=_.CONSTANTS.MillisecondsPer8Hours&&(t=!0,e=Math.round((_.CONSTANTS.MillisecondsPer8Hours-this.timeWorked)/E.Engine._idleSpeed)),this.timeWorked+=E.Engine._idleSpeed*e,this.workRepGainRate=this.getWorkRepGain(),this.processWorkEarnings(e),t||this.timeWorked>=_.CONSTANTS.MillisecondsPer8Hours)return this.finishWorkPartTime();var n=p.Companies[this.companyName],a="0";null!=n&&n instanceof u.Company?a=n.playerReputation:console.log("ERROR: Could not find Company: "+this.companyName);const i=this.jobs[this.companyName];document.getElementById("work-in-progress-text").innerHTML="You are currently working as a "+i+" at "+this.companyName+" (Current Company Reputation: "+D.numeralWrapper.format(a,"0,0")+")

    You have been working for "+Object(H.convertTimeMsToTimeElapsedString)(this.timeWorked)+"

    You have earned:

    $"+D.numeralWrapper.format(this.workMoneyGained,"0,0.00")+" ($"+D.numeralWrapper.format(this.workMoneyGainRate*G,"0,0.00")+" / sec)

    "+D.numeralWrapper.format(this.workRepGained,"0,0.0000")+" ("+D.numeralWrapper.format(this.workRepGainRate*G,"0,0.0000")+" / sec) reputation for this company

    "+D.numeralWrapper.format(this.workHackExpGained,"0,0.0000")+" ("+D.numeralWrapper.format(this.workHackExpGainRate*G,"0,0.0000")+" / sec) hacking exp

    "+D.numeralWrapper.format(this.workStrExpGained,"0,0.0000")+" ("+D.numeralWrapper.format(this.workStrExpGainRate*G,"0,0.0000")+" / sec) strength exp
    "+D.numeralWrapper.format(this.workDefExpGained,"0,0.0000")+" ("+D.numeralWrapper.format(this.workDefExpGainRate*G,"0,0.0000")+" / sec) defense exp
    "+D.numeralWrapper.format(this.workDexExpGained,"0,0.0000")+" ("+D.numeralWrapper.format(this.workDexExpGainRate*G,"0,0.0000")+" / sec) dexterity exp
    "+D.numeralWrapper.format(this.workAgiExpGained,"0,0.0000")+" ("+D.numeralWrapper.format(this.workAgiExpGainRate*G,"0,0.0000")+" / sec) agility exp

    "+D.numeralWrapper.format(this.workChaExpGained,"0,0.0000")+" ("+D.numeralWrapper.format(this.workChaExpGainRate*G,"0,0.0000")+" / sec) charisma exp

    You will automatically finish after working for 8 hours. You can cancel earlier if you wish,
    and there will be no penalty because this is a part-time job."},K.prototype.finishWorkPartTime=function(e=!1){p.Companies[this.companyName].playerReputation+=this.workRepGained,this.updateSkillLevels();var t="You earned a total of:
    $"+D.numeralWrapper.format(this.workMoneyGained,"0,0.00")+"
    "+D.numeralWrapper.format(this.workRepGained,"0,0.0000")+" reputation for the company
    "+D.numeralWrapper.format(this.workHackExpGained,"0,0.0000")+" hacking exp
    "+D.numeralWrapper.format(this.workStrExpGained,"0,0.0000")+" strength exp
    "+D.numeralWrapper.format(this.workDefExpGained,"0,0.0000")+" defense exp
    "+D.numeralWrapper.format(this.workDexExpGained,"0,0.0000")+" dexterity exp
    "+D.numeralWrapper.format(this.workAgiExpGained,"0,0.0000")+" agility exp
    "+D.numeralWrapper.format(this.workChaExpGained,"0,0.0000")+" charisma exp
    ";if(t="You worked for "+Object(H.convertTimeMsToTimeElapsedString)(this.timeWorked)+"

    "+t,e||Object(W.dialogBoxCreate)(t),document.getElementById("mainmenu-container").style.visibility="visible",this.isWorking=!1,E.Engine.loadLocationContent(),e){var n="You worked for "+Object(H.convertTimeMsToTimeElapsedString)(this.timeWorked)+" and earned a total of $"+D.numeralWrapper.format(this.workMoneyGained,"0,0.00")+", "+D.numeralWrapper.format(this.workRepGained,"0,0.0000")+" reputation, "+D.numeralWrapper.format(this.workHackExpGained,"0,0.0000")+" hacking exp, "+D.numeralWrapper.format(this.workStrExpGained,"0,0.0000")+" strength exp, "+D.numeralWrapper.format(this.workDefExpGained,"0,0.0000")+" defense exp, "+D.numeralWrapper.format(this.workDexExpGained,"0,0.0000")+" dexterity exp, "+D.numeralWrapper.format(this.workAgiExpGained,"0,0.0000")+" agility exp, and "+D.numeralWrapper.format(this.workChaExpGained,"0,0.0000")+" charisma exp";return this.resetWorkStatus(),n}this.resetWorkStatus()},K.prototype.startFactionWork=function(e){var t=1+e.favor/100;isNaN(t)&&(t=1),this.workRepGainRate*=t,this.workRepGainRate*=s.BitNodeMultipliers.FactionWorkRepGain,this.isWorking=!0,this.workType=_.CONSTANTS.WorkTypeFaction,this.currentWorkFactionName=e.name,this.timeNeededToCompleteWork=_.CONSTANTS.MillisecondsPer20Hours;var n=Object(j.clearEventListeners)("work-in-progress-cancel-button");n.innerHTML="Stop Faction Work",n.addEventListener("click",function(){return $.finishFactionWork(!0),!1}),E.Engine.loadWorkInProgressContent()},K.prototype.startFactionHackWork=function(e){this.resetWorkStatus(),this.workHackExpGainRate=.15*this.hacking_exp_mult*s.BitNodeMultipliers.FactionWorkExpGain,this.workRepGainRate=this.workRepGainRate=(this.hacking_skill+this.intelligence)/_.CONSTANTS.MaxSkillLevel*this.faction_rep_mult,this.factionWorkType=_.CONSTANTS.FactionWorkHacking,this.currentWorkFactionDescription="carrying out hacking contracts",this.startFactionWork(e)},K.prototype.startFactionFieldWork=function(e){this.resetWorkStatus(),this.workHackExpGainRate=.1*this.hacking_exp_mult*s.BitNodeMultipliers.FactionWorkExpGain,this.workStrExpGainRate=.1*this.strength_exp_mult*s.BitNodeMultipliers.FactionWorkExpGain,this.workDefExpGainRate=.1*this.defense_exp_mult*s.BitNodeMultipliers.FactionWorkExpGain,this.workDexExpGainRate=.1*this.dexterity_exp_mult*s.BitNodeMultipliers.FactionWorkExpGain,this.workAgiExpGainRate=.1*this.agility_exp_mult*s.BitNodeMultipliers.FactionWorkExpGain,this.workChaExpGainRate=.1*this.charisma_exp_mult*s.BitNodeMultipliers.FactionWorkExpGain,this.workRepGainRate=this.getFactionFieldWorkRepGain(),this.factionWorkType=_.CONSTANTS.FactionWorkField,this.currentWorkFactionDescription="carrying out field missions",this.startFactionWork(e)},K.prototype.startFactionSecurityWork=function(e){this.resetWorkStatus(),this.workHackExpGainRate=.05*this.hacking_exp_mult*s.BitNodeMultipliers.FactionWorkExpGain,this.workStrExpGainRate=.15*this.strength_exp_mult*s.BitNodeMultipliers.FactionWorkExpGain,this.workDefExpGainRate=.15*this.defense_exp_mult*s.BitNodeMultipliers.FactionWorkExpGain,this.workDexExpGainRate=.15*this.dexterity_exp_mult*s.BitNodeMultipliers.FactionWorkExpGain,this.workAgiExpGainRate=.15*this.agility_exp_mult*s.BitNodeMultipliers.FactionWorkExpGain,this.workChaExpGainRate=0*this.charisma_exp_mult*s.BitNodeMultipliers.FactionWorkExpGain,this.workRepGainRate=this.getFactionSecurityWorkRepGain(),this.factionWorkType=_.CONSTANTS.FactionWorkSecurity,this.currentWorkFactionDescription="performing security detail",this.startFactionWork(e)},K.prototype.workForFaction=function(e){var t=C.Factions[this.currentWorkFactionName];switch(this.factionWorkType){case _.CONSTANTS.FactionWorkHacking:this.workRepGainRate=(this.hacking_skill+this.intelligence)/_.CONSTANTS.MaxSkillLevel*this.faction_rep_mult;break;case _.CONSTANTS.FactionWorkField:this.workRepGainRate=this.getFactionFieldWorkRepGain();break;case _.CONSTANTS.FactionWorkSecurity:this.workRepGainRate=this.getFactionSecurityWorkRepGain()}var n=1+t.favor/100;isNaN(n)&&(n=1),this.workRepGainRate*=n,this.workRepGainRate*=s.BitNodeMultipliers.FactionWorkRepGain;var a=!1;if(this.timeWorked+E.Engine._idleSpeed*e>=_.CONSTANTS.MillisecondsPer20Hours&&(a=!0,e=Math.round((_.CONSTANTS.MillisecondsPer20Hours-this.timeWorked)/E.Engine._idleSpeed)),this.timeWorked+=E.Engine._idleSpeed*e,this.processWorkEarnings(e),a||this.timeWorked>=_.CONSTANTS.MillisecondsPer20Hours)return this.finishFactionWork(!1);document.getElementById("work-in-progress-text").innerHTML="You are currently "+this.currentWorkFactionDescription+" for your faction "+t.name+" (Current Faction Reputation: "+D.numeralWrapper.format(t.playerReputation,"0,0")+").
    You have been doing this for "+Object(H.convertTimeMsToTimeElapsedString)(this.timeWorked)+"

    You have earned:

    $"+D.numeralWrapper.format(this.workMoneyGained,"0,0.00")+" ("+D.numeralWrapper.format(this.workMoneyGainRate*G,"0,0.00")+" / sec)

    "+D.numeralWrapper.format(this.workRepGained,"0,0.0000")+" ("+D.numeralWrapper.format(this.workRepGainRate*G,"0,0.0000")+" / sec) reputation for this faction

    "+D.numeralWrapper.format(this.workHackExpGained,"0,0.0000")+" ("+D.numeralWrapper.format(this.workHackExpGainRate*G,"0,0.0000")+" / sec) hacking exp

    "+D.numeralWrapper.format(this.workStrExpGained,"0,0.0000")+" ("+D.numeralWrapper.format(this.workStrExpGainRate*G,"0,0.0000")+" / sec) strength exp
    "+D.numeralWrapper.format(this.workDefExpGained,"0,0.0000")+" ("+D.numeralWrapper.format(this.workDefExpGainRate*G,"0,0.0000")+" / sec) defense exp
    "+D.numeralWrapper.format(this.workDexExpGained,"0,0.0000")+" ("+D.numeralWrapper.format(this.workDexExpGainRate*G,"0,0.0000")+" / sec) dexterity exp
    "+D.numeralWrapper.format(this.workAgiExpGained,"0,0.0000")+" ("+D.numeralWrapper.format(this.workAgiExpGainRate*G,"0,0.0000")+" / sec) agility exp

    "+D.numeralWrapper.format(this.workChaExpGained,"0,0.0000")+" ("+D.numeralWrapper.format(this.workChaExpGainRate*G,"0,0.0000")+" / sec) charisma exp

    You will automatically finish after working for 20 hours. You can cancel earlier if you wish.
    There is no penalty for cancelling earlier."},K.prototype.finishFactionWork=function(e,t=!1){var n=C.Factions[this.currentWorkFactionName];n.playerReputation+=this.workRepGained,this.updateSkillLevels();var a="You worked for your faction "+n.name+" for a total of "+Object(H.convertTimeMsToTimeElapsedString)(this.timeWorked)+"

    You earned a total of:
    $"+D.numeralWrapper.format(this.workMoneyGained,"0,0.00")+"
    "+D.numeralWrapper.format(this.workRepGained,"0,0.0000")+" reputation for the faction
    "+D.numeralWrapper.format(this.workHackExpGained,"0,0.0000")+" hacking exp
    "+D.numeralWrapper.format(this.workStrExpGained,"0,0.0000")+" strength exp
    "+D.numeralWrapper.format(this.workDefExpGained,"0,0.0000")+" defense exp
    "+D.numeralWrapper.format(this.workDexExpGained,"0,0.0000")+" dexterity exp
    "+D.numeralWrapper.format(this.workAgiExpGained,"0,0.0000")+" agility exp
    "+D.numeralWrapper.format(this.workChaExpGained,"0,0.0000")+" charisma exp
    ";if(t||Object(W.dialogBoxCreate)(a),document.getElementById("mainmenu-container").style.visibility="visible",this.isWorking=!1,E.Engine.loadFactionContent(),Object(T.a)(n.name),t){var i="You worked for your faction "+n.name+" for a total of "+Object(H.convertTimeMsToTimeElapsedString)(this.timeWorked)+". You earned "+D.numeralWrapper.format(this.workRepGained,"0,0.0000")+" rep, "+D.numeralWrapper.format(this.workHackExpGained,"0,0.0000")+" hacking exp, "+D.numeralWrapper.format(this.workStrExpGained,"0,0.0000")+" str exp, "+D.numeralWrapper.format(this.workDefExpGained,"0,0.0000")+" def exp, "+D.numeralWrapper.format(this.workDexExpGained,"0,0.0000")+" dex exp, "+D.numeralWrapper.format(this.workAgiExpGained,"0,0.0000")+" agi exp, and "+D.numeralWrapper.format(this.workChaExpGained,"0,0.0000")+" cha exp.";return this.resetWorkStatus(),i}this.resetWorkStatus()},K.prototype.getWorkMoneyGain=function(){let e=1;const t=p.Companies[this.companyName];M.d&&(e=1+t.favor/100);const n=this.jobs[this.companyName],a=d.CompanyPositions[n];return null==a?(console.error(`Could not find CompanyPosition object for ${n}. Work salary will be 0`),0):a.baseSalary*t.salaryMultiplier*this.work_money_mult*s.BitNodeMultipliers.CompanyWorkMoney*e},K.prototype.getWorkHackExpGain=function(){const e=p.Companies[this.companyName],t=this.jobs[this.companyName],n=d.CompanyPositions[t];return null==e||null==n?(console.error([`Could not find Company object for ${this.companyName}`,`or CompanyPosition object for ${t}.`,"Work hack exp gain will be 0"].join(" ")),0):n.hackingExpGain*e.expMultiplier*this.hacking_exp_mult*s.BitNodeMultipliers.CompanyWorkExpGain},K.prototype.getWorkStrExpGain=function(){const e=p.Companies[this.companyName],t=this.jobs[this.companyName],n=d.CompanyPositions[t];return null==e||null==n?(console.error([`Could not find Company object for ${this.companyName}`,`or CompanyPosition object for ${t}.`,"Work str exp gain will be 0"].join(" ")),0):n.strengthExpGain*e.expMultiplier*this.strength_exp_mult*s.BitNodeMultipliers.CompanyWorkExpGain},K.prototype.getWorkDefExpGain=function(){const e=p.Companies[this.companyName],t=this.jobs[this.companyName],n=d.CompanyPositions[t];return null==e||null==n?(console.error([`Could not find Company object for ${this.companyName}`,`or CompanyPosition object for ${t}.`,"Work def exp gain will be 0"].join(" ")),0):n.defenseExpGain*e.expMultiplier*this.defense_exp_mult*s.BitNodeMultipliers.CompanyWorkExpGain},K.prototype.getWorkDexExpGain=function(){const e=p.Companies[this.companyName],t=this.jobs[this.companyName],n=d.CompanyPositions[t];return null==e||null==n?(console.error([`Could not find Company object for ${this.companyName}`,`or CompanyPosition object for ${t}.`,"Work dex exp gain will be 0"].join(" ")),0):n.dexterityExpGain*e.expMultiplier*this.dexterity_exp_mult*s.BitNodeMultipliers.CompanyWorkExpGain},K.prototype.getWorkAgiExpGain=function(){const e=p.Companies[this.companyName],t=this.jobs[this.companyName],n=d.CompanyPositions[t];return null==e||null==n?(console.error([`Could not find Company object for ${this.companyName}`,`or CompanyPosition object for ${t}.`,"Work agi exp gain will be 0"].join(" ")),0):n.agilityExpGain*e.expMultiplier*this.agility_exp_mult*s.BitNodeMultipliers.CompanyWorkExpGain},K.prototype.getWorkChaExpGain=function(){const e=p.Companies[this.companyName],t=this.jobs[this.companyName],n=d.CompanyPositions[t];return null==e||null==n?(console.error([`Could not find Company object for ${this.companyName}`,`or CompanyPosition object for ${t}.`,"Work cha exp gain will be 0"].join(" ")),0):n.charismaExpGain*e.expMultiplier*this.charisma_exp_mult*s.BitNodeMultipliers.CompanyWorkExpGain},K.prototype.getWorkRepGain=function(){const e=p.Companies[this.companyName],t=this.jobs[this.companyName],n=d.CompanyPositions[t];if(null==e||null==n)return console.error([`Could not find Company object for ${this.companyName}`,`or CompanyPosition object for ${t}.`,"Work rep gain will be 0"].join(" ")),0;var a=n.calculateJobPerformance(this.hacking_skill,this.strength,this.defense,this.dexterity,this.agility,this.charisma);a+=this.intelligence/_.CONSTANTS.MaxSkillLevel;var i=1+e.favor/100;return isNaN(i)&&(i=1),a*this.company_rep_mult*i},K.prototype.getFactionSecurityWorkRepGain=function(){return.9*(this.hacking_skill/_.CONSTANTS.MaxSkillLevel+this.strength/_.CONSTANTS.MaxSkillLevel+this.defense/_.CONSTANTS.MaxSkillLevel+this.dexterity/_.CONSTANTS.MaxSkillLevel+this.agility/_.CONSTANTS.MaxSkillLevel)/4.5*this.faction_rep_mult},K.prototype.getFactionFieldWorkRepGain=function(){return.9*(this.hacking_skill/_.CONSTANTS.MaxSkillLevel+this.strength/_.CONSTANTS.MaxSkillLevel+this.defense/_.CONSTANTS.MaxSkillLevel+this.dexterity/_.CONSTANTS.MaxSkillLevel+this.agility/_.CONSTANTS.MaxSkillLevel+this.charisma/_.CONSTANTS.MaxSkillLevel+this.intelligence/_.CONSTANTS.MaxSkillLevel)/5.5*this.faction_rep_mult},K.prototype.startCreateProgramWork=function(e,t,n){this.resetWorkStatus(),this.isWorking=!0,this.workType=_.CONSTANTS.WorkTypeCreateProgram,this.createProgramReqLvl=n,this.timeNeededToCompleteWork=t;for(var a=0;a=100)break;this.timeWorkedCreateProgram=o/100*this.timeNeededToCompleteWork,this.getHomeComputer().programs.splice(a,1)}}this.createProgramName=e;var s=Object(j.clearEventListeners)("work-in-progress-cancel-button");s.innerHTML="Cancel work on creating program",s.addEventListener("click",function(){return $.finishCreateProgramWork(!0),!1}),E.Engine.loadWorkInProgressContent()},K.prototype.createProgramWork=function(e){var t=this.createProgramReqLvl,n=this.hacking_skill/t;n=1+(n-1)/5,this.timeWorked+=E.Engine._idleSpeed*e,this.timeWorkedCreateProgram+=E.Engine._idleSpeed*e*n;var a=this.createProgramName;this.timeWorkedCreateProgram>=this.timeNeededToCompleteWork&&this.finishCreateProgramWork(!1),document.getElementById("work-in-progress-text").innerHTML="You are currently working on coding "+a+".

    You have been working for "+Object(H.convertTimeMsToTimeElapsedString)(this.timeWorked)+"

    The program is "+(this.timeWorkedCreateProgram/this.timeNeededToCompleteWork*100).toFixed(2)+"% complete.
    If you cancel, your work will be saved and you can come back to complete the program later."},K.prototype.finishCreateProgramWork=function(e,t=!1){var n=this.createProgramName;if(!1===e)Object(W.dialogBoxCreate)("You've finished creating "+n+"!
    The new program can be found on your home computer."),this.getHomeComputer().programs.push(n);else{var a=n+"-"+(Math.floor(this.timeWorkedCreateProgram/this.timeNeededToCompleteWork*1e4)/100).toString()+"%-INC";this.getHomeComputer().programs.push(a)}e||this.gainIntelligenceExp(this.createProgramReqLvl/_.CONSTANTS.IntelligenceProgramBaseExpGain),document.getElementById("mainmenu-container").style.visibility="visible",this.isWorking=!1,E.Engine.loadTerminalContent(),this.resetWorkStatus()},K.prototype.startClass=function(e,t,n){this.resetWorkStatus(),this.isWorking=!0,this.workType=_.CONSTANTS.WorkTypeStudyClass,this.className=n;var a=1e3/E.Engine._idleSpeed,i=0,r=0,o=0,l=0,c=0,u=0,p=0;switch(n){case _.CONSTANTS.ClassStudyComputerScience:r=.5*t/a;break;case _.CONSTANTS.ClassDataStructures:i=_.CONSTANTS.ClassDataStructuresBaseCost*e/a,r=1*t/a;break;case _.CONSTANTS.ClassNetworks:i=_.CONSTANTS.ClassNetworksBaseCost*e/a,r=2*t/a;break;case _.CONSTANTS.ClassAlgorithms:i=_.CONSTANTS.ClassAlgorithmsBaseCost*e/a,r=4*t/a;break;case _.CONSTANTS.ClassManagement:i=_.CONSTANTS.ClassManagementBaseCost*e/a,p=2*t/a;break;case _.CONSTANTS.ClassLeadership:i=_.CONSTANTS.ClassLeadershipBaseCost*e/a,p=4*t/a;break;case _.CONSTANTS.ClassGymStrength:i=_.CONSTANTS.ClassGymBaseCost*e/a,o=1*t/a;break;case _.CONSTANTS.ClassGymDefense:i=_.CONSTANTS.ClassGymBaseCost*e/a,l=1*t/a;break;case _.CONSTANTS.ClassGymDexterity:i=_.CONSTANTS.ClassGymBaseCost*e/a,c=1*t/a;break;case _.CONSTANTS.ClassGymAgility:i=_.CONSTANTS.ClassGymBaseCost*e/a,u=1*t/a;break;default:throw new Error("ERR: Invalid/unrecognized class name")}this.workMoneyLossRate=i,this.workHackExpGainRate=r*this.hacking_exp_mult*s.BitNodeMultipliers.ClassGymExpGain,this.workStrExpGainRate=o*this.strength_exp_mult*s.BitNodeMultipliers.ClassGymExpGain,this.workDefExpGainRate=l*this.defense_exp_mult*s.BitNodeMultipliers.ClassGymExpGain,this.workDexExpGainRate=c*this.dexterity_exp_mult*s.BitNodeMultipliers.ClassGymExpGain,this.workAgiExpGainRate=u*this.agility_exp_mult*s.BitNodeMultipliers.ClassGymExpGain,this.workChaExpGainRate=p*this.charisma_exp_mult*s.BitNodeMultipliers.ClassGymExpGain;var m=Object(j.clearEventListeners)("work-in-progress-cancel-button");n==_.CONSTANTS.ClassGymStrength||n==_.CONSTANTS.ClassGymDefense||n==_.CONSTANTS.ClassGymDexterity||n==_.CONSTANTS.ClassGymAgility?m.innerHTML="Stop training at gym":m.innerHTML="Stop taking course",m.addEventListener("click",function(){return $.finishClass(),!1}),E.Engine.loadWorkInProgressContent()},K.prototype.takeClass=function(e){this.timeWorked+=E.Engine._idleSpeed*e;var t=this.className;this.processWorkEarnings(e),document.getElementById("work-in-progress-text").innerHTML="You have been "+t+" for "+Object(H.convertTimeMsToTimeElapsedString)(this.timeWorked)+"

    This has cost you:
    $"+D.numeralWrapper.format(this.workMoneyGained,"0,0.00")+" ($"+D.numeralWrapper.format(this.workMoneyLossRate*G,"0,0.00")+" / sec)

    You have gained:
    "+D.numeralWrapper.format(this.workHackExpGained,"0,0.0000")+" ("+D.numeralWrapper.format(this.workHackExpGainRate*G,"0,0.0000")+" / sec) hacking exp
    "+D.numeralWrapper.format(this.workStrExpGained,"0,0.0000")+" ("+D.numeralWrapper.format(this.workStrExpGainRate*G,"0,0.0000")+" / sec) strength exp
    "+D.numeralWrapper.format(this.workDefExpGained,"0,0.0000")+" ("+D.numeralWrapper.format(this.workDefExpGainRate*G,"0,0.0000")+" / sec) defense exp
    "+D.numeralWrapper.format(this.workDexExpGained,"0,0.0000")+" ("+D.numeralWrapper.format(this.workDexExpGainRate*G,"0,0.0000")+" / sec) dexterity exp
    "+D.numeralWrapper.format(this.workAgiExpGained,"0,0.0000")+" ("+D.numeralWrapper.format(this.workAgiExpGainRate*G,"0,0.0000")+" / sec) agility exp
    "+D.numeralWrapper.format(this.workChaExpGained,"0,0.0000")+" ("+D.numeralWrapper.format(this.workChaExpGainRate*G,"0,0.0000")+" / sec) charisma exp
    You may cancel at any time"},K.prototype.finishClass=function(e=!1){if(this.gainIntelligenceExp(_.CONSTANTS.IntelligenceClassBaseExpGain*Math.round(this.timeWorked/1e3)),this.workMoneyGained>0)throw new Error("ERR: Somehow gained money while taking class");this.updateSkillLevels();var t="After "+this.className+" for "+Object(H.convertTimeMsToTimeElapsedString)(this.timeWorked)+",
    you spent a total of $"+D.numeralWrapper.format(-1*this.workMoneyGained,"0,0.00")+".

    You earned a total of:
    "+D.numeralWrapper.format(this.workHackExpGained,"0,0.0000")+" hacking exp
    "+D.numeralWrapper.format(this.workStrExpGained,"0,0.0000")+" strength exp
    "+D.numeralWrapper.format(this.workDefExpGained,"0,0.0000")+" defense exp
    "+D.numeralWrapper.format(this.workDexExpGained,"0,0.0000")+" dexterity exp
    "+D.numeralWrapper.format(this.workAgiExpGained,"0,0.0000")+" agility exp
    "+D.numeralWrapper.format(this.workChaExpGained,"0,0.0000")+" charisma exp
    ";if(e||Object(W.dialogBoxCreate)(t),document.getElementById("mainmenu-container").style.visibility="visible",this.isWorking=!1,E.Engine.loadLocationContent(),e){var n="After "+this.className+" for "+Object(H.convertTimeMsToTimeElapsedString)(this.timeWorked)+", you spent a total of $"+D.numeralWrapper.format(-1*this.workMoneyGained,"0,0.00")+". You earned a total of: "+D.numeralWrapper.format(this.workHackExpGained,"0,0.0000")+" hacking exp, "+D.numeralWrapper.format(this.workStrExpGained,"0,0.0000")+" strength exp, "+D.numeralWrapper.format(this.workDefExpGained,"0,0.0000")+" defense exp, "+D.numeralWrapper.format(this.workDexExpGained,"0,0.0000")+" dexterity exp, "+D.numeralWrapper.format(this.workAgiExpGained,"0,0.0000")+" agility exp, and "+D.numeralWrapper.format(this.workChaExpGained,"0,0.0000")+" charisma exp";return this.resetWorkStatus(),n}this.resetWorkStatus()},K.prototype.startCrime=function(e,t,n,a,i,r,o,l,c,u=null){this.crimeType=e,this.resetWorkStatus(),this.isWorking=!0,this.workType=_.CONSTANTS.WorkTypeCrime,u&&u.workerscript&&(this.committingCrimeThruSingFn=!0,this.singFnCrimeWorkerScript=u.workerscript),this.workHackExpGained=t*this.hacking_exp_mult*s.BitNodeMultipliers.CrimeExpGain,this.workStrExpGained=n*this.strength_exp_mult*s.BitNodeMultipliers.CrimeExpGain,this.workDefExpGained=a*this.defense_exp_mult*s.BitNodeMultipliers.CrimeExpGain,this.workDexExpGained=i*this.dexterity_exp_mult*s.BitNodeMultipliers.CrimeExpGain,this.workAgiExpGained=r*this.agility_exp_mult*s.BitNodeMultipliers.CrimeExpGain,this.workChaExpGained=o*this.charisma_exp_mult*s.BitNodeMultipliers.CrimeExpGain,this.workMoneyGained=l*this.crime_money_mult*s.BitNodeMultipliers.CrimeMoney,this.timeNeededToCompleteWork=c;var p=Object(j.clearEventListeners)("work-in-progress-cancel-button");p.innerHTML="Cancel crime",p.addEventListener("click",function(){return $.finishCrime(!0),!1}),E.Engine.loadWorkInProgressContent()},K.prototype.commitCrime=function(e){if(this.timeWorked+=E.Engine._idleSpeed*e,this.timeWorked>=this.timeNeededToCompleteWork)this.finishCrime(!1);else{var t=Math.round(this.timeWorked/this.timeNeededToCompleteWork*100),n=Math.round(t/5);n<0&&(n=0),n>20&&(n=20);var a="["+Array(n+1).join("|")+Array(20-n+1).join(" ")+"]";document.getElementById("work-in-progress-text").innerHTML="You are attempting to "+this.crimeType+".
    Time remaining: "+Object(H.convertTimeMsToTimeElapsedString)(this.timeNeededToCompleteWork-this.timeWorked)+"
    "+a.replace(/ /g," ")}},K.prototype.finishCrime=function(e){if(!e){if(Object(b.determineCrimeSuccess)($,this.crimeType)){let e=null;for(const t in v.Crimes)if(v.Crimes[t].type==this.crimeType){e=v.Crimes[t];break}null==e&&(console.log(this.crimeType),Object(W.dialogBoxCreate)("ERR: Unrecognized crime type. This is probably a bug please contact the developer")),$.gainMoney(this.workMoneyGained),$.recordMoneySource(this.workMoneyGained,"crime"),this.karma-=e.karma,this.numPeopleKilled+=e.kills,e.intelligence_exp>0&&this.gainIntelligenceExp(e.intelligence_exp),this.workHackExpGained*=2,this.workStrExpGained*=2,this.workDefExpGained*=2,this.workDexExpGained*=2,this.workAgiExpGained*=2,this.workChaExpGained*=2,this.committingCrimeThruSingFn?null==this.singFnCrimeWorkerScript.disableLogs.ALL&&null==this.singFnCrimeWorkerScript.disableLogs.commitCrime&&this.singFnCrimeWorkerScript.scriptRef.log("Crime successful! Gained "+D.numeralWrapper.format(this.workMoneyGained,"$0.000a")+", "+D.numeralWrapper.format(this.workHackExpGained,"0,0.0000")+" hack exp, "+D.numeralWrapper.format(this.workStrExpGained,"0,0.0000")+" str exp, "+D.numeralWrapper.format(this.workDefExpGained,"0,0.0000")+" def exp, "+D.numeralWrapper.format(this.workDexExpGained,"0,0.0000")+" dex exp, "+D.numeralWrapper.format(this.workAgiExpGained,"0,0.0000")+" agi exp, "+D.numeralWrapper.format(this.workChaExpGained,"0,0.0000")+" cha exp."):Object(W.dialogBoxCreate)("Crime successful!

    You gained:
    $"+D.numeralWrapper.format(this.workMoneyGained,"0,0.00")+"
    "+D.numeralWrapper.format(this.workHackExpGained,"0,0.0000")+" hacking experience
    "+D.numeralWrapper.format(this.workStrExpGained,"0,0.0000")+" strength experience
    "+D.numeralWrapper.format(this.workDefExpGained,"0,0.0000")+" defense experience
    "+D.numeralWrapper.format(this.workDexExpGained,"0,0.0000")+" dexterity experience
    "+D.numeralWrapper.format(this.workAgiExpGained,"0,0.0000")+" agility experience
    "+D.numeralWrapper.format(this.workChaExpGained,"0,0.0000")+" charisma experience")}else this.workHackExpGained/=2,this.workStrExpGained/=2,this.workDefExpGained/=2,this.workDexExpGained/=2,this.workAgiExpGained/=2,this.workChaExpGained/=2,this.committingCrimeThruSingFn?null==this.singFnCrimeWorkerScript.disableLogs.ALL&&null==this.singFnCrimeWorkerScript.disableLogs.commitCrime&&this.singFnCrimeWorkerScript.scriptRef.log("Crime failed! Gained "+D.numeralWrapper.format(this.workHackExpGained,"0,0.0000")+" hack exp, "+D.numeralWrapper.format(this.workStrExpGained,"0,0.0000")+" str exp, "+D.numeralWrapper.format(this.workDefExpGained,"0,0.0000")+" def exp, "+D.numeralWrapper.format(this.workDexExpGained,"0,0.0000")+" dex exp, "+D.numeralWrapper.format(this.workAgiExpGained,"0,0.0000")+" agi exp, "+D.numeralWrapper.format(this.workChaExpGained,"0,0.0000")+" cha exp."):Object(W.dialogBoxCreate)("Crime failed!

    You gained:
    "+D.numeralWrapper.format(this.workHackExpGained,"0,0.0000")+" hacking experience
    "+D.numeralWrapper.format(this.workStrExpGained,"0,0.0000")+" strength experience
    "+D.numeralWrapper.format(this.workDefExpGained,"0,0.0000")+" defense experience
    "+D.numeralWrapper.format(this.workDexExpGained,"0,0.0000")+" dexterity experience
    "+D.numeralWrapper.format(this.workAgiExpGained,"0,0.0000")+" agility experience
    "+D.numeralWrapper.format(this.workChaExpGained,"0,0.0000")+" charisma experience");this.gainHackingExp(this.workHackExpGained),this.gainStrengthExp(this.workStrExpGained),this.gainDefenseExp(this.workDefExpGained),this.gainDexterityExp(this.workDexExpGained),this.gainAgilityExp(this.workAgiExpGained),this.gainCharismaExp(this.workChaExpGained)}this.committingCrimeThruSingFn=!1,this.singFnCrimeWorkerScript=null,document.getElementById("mainmenu-container").style.visibility="visible",this.isWorking=!1,this.resetWorkStatus(),E.Engine.loadLocationContent()},K.prototype.singularityStopWork=function(){if(!this.isWorking)return"";var e;switch(this.workType){case _.CONSTANTS.WorkTypeStudyClass:e=this.finishClass(!0);break;case _.CONSTANTS.WorkTypeCompany:e=this.finishWork(!0,!0);break;case _.CONSTANTS.WorkTypeCompanyPartTime:e=this.finishWorkPartTime(!0);break;case _.CONSTANTS.WorkTypeFaction:e=this.finishFactionWork(!0,!0);break;case _.CONSTANTS.WorkTypeCreateProgram:e=this.finishCreateProgramWork(!0,!0);break;case _.CONSTANTS.WorkTypeCrime:e=this.finishCrime(!0);break;default:return console.log("ERROR: Unrecognized work type"),""}return e},K.prototype.takeDamage=function(e){if("number"==typeof e)return this.hp-=e,this.hp<=0&&(this.hospitalize(),!0);console.warn(`Player.takeDamage() called without a numeric argument: ${e}`)},K.prototype.regenerateHp=function(e){"number"==typeof e?(this.hp+=e,this.hp>this.max_hp&&(this.hp=this.max_hp)):console.warn(`Player.regenerateHp() called without a numeric argument: ${e}`)},K.prototype.hospitalize=function(){!1===x.Settings.SuppressHospitalizationPopup&&Object(W.dialogBoxCreate)("You were in critical condition! You were taken to the hospital where luckily they were able to save your life. You were charged "+D.numeralWrapper.format(this.max_hp*_.CONSTANTS.HospitalCostPerHp,"$0.000a")),this.loseMoney(this.max_hp*_.CONSTANTS.HospitalCostPerHp),this.hp=this.max_hp},K.prototype.applyForJob=function(e,t=!1){let n=null;""!==this.companyName&&(n=p.Companies[this.companyName]);const a=this.jobs[this.companyName],i=p.Companies[this.location];if(!(i instanceof u.Company))return t?"ERROR: Invalid company name: "+this.location+". applyToCompany() failed":void console.error(`Could not find company that matches the location: ${this.location}. Player.applyToCompany() failed`);let r=e;if(!this.isQualified(i,r)){var o=Object(h.getJobRequirementText)(i,r);return!t&&void Object(W.dialogBoxCreate)("Unforunately, you do not qualify for this position
    "+o)}for(;;){let e=Object(m.getNextCompanyPosition)(r);if(null==e)break;if(!i.hasPosition(e))break;if(!this.isQualified(i,e))break;r=e}if(null==n||n.name!=i.name||r.name!=a){if(this.companyName=i.name,this.jobs[i.name]=r.name,document.getElementById("world-menu-header").click(),document.getElementById("world-menu-header").click(),t)return!0;Object(W.dialogBoxCreate)("Congratulations! You were offered a new job at "+this.companyName+" as a "+r.name+"!"),E.Engine.loadLocationContent()}else{var s=Object(m.getNextCompanyPosition)(r);if(null==s){if(t)return!1;Object(W.dialogBoxCreate)("You are already at the highest position for your field! No promotion available")}else if(i.hasPosition(s)){if(t)return!1;o=Object(h.getJobRequirementText)(i,s);Object(W.dialogBoxCreate)("Unfortunately, you do not qualify for a promotion
    "+o)}else{if(t)return!1;Object(W.dialogBoxCreate)("You are already at the highest position for your field! No promotion available")}}},K.prototype.getNextCompanyPosition=function(e,t){var n=null;if(""!==this.companyName&&(n=p.Companies[this.companyName]),null==n||n.name!=e.name)return t;const a=this.jobs[this.companyName],i=d.CompanyPositions[a];return i.isSoftwareJob()&&t.isSoftwareJob()||i.isITJob()&&t.isITJob()||i.isBusinessJob()&&t.isBusinessJob()||i.isSecurityEngineerJob()&&t.isSecurityEngineerJob()||i.isNetworkEngineerJob()&&t.isNetworkEngineerJob()||i.isSecurityJob()&&t.isSecurityJob()||i.isAgentJob()&&t.isAgentJob()||i.isSoftwareConsultantJob()&&t.isSoftwareConsultantJob()||i.isBusinessConsultantJob()&&t.isBusinessConsultantJob()||i.isPartTimeJob()&&t.isPartTimeJob()?Object(m.getNextCompanyPosition)(i):t},K.prototype.applyForSoftwareJob=function(e=!1){return this.applyForJob(d.CompanyPositions[g.SoftwareCompanyPositions[0]],e)},K.prototype.applyForSoftwareConsultantJob=function(e=!1){return this.applyForJob(d.CompanyPositions[g.SoftwareConsultantCompanyPositions[0]],e)},K.prototype.applyForItJob=function(e=!1){return this.applyForJob(d.CompanyPositions[g.ITCompanyPositions[0]],e)},K.prototype.applyForSecurityEngineerJob=function(e=!1){var t=p.Companies[this.location];return this.isQualified(t,d.CompanyPositions[g.SecurityEngineerCompanyPositions[0]])?this.applyForJob(d.CompanyPositions[g.SecurityEngineerCompanyPositions[0]],e):!e&&void Object(W.dialogBoxCreate)("Unforunately, you do not qualify for this position")},K.prototype.applyForNetworkEngineerJob=function(e=!1){var t=p.Companies[this.location];return this.isQualified(t,d.CompanyPositions[g.NetworkEngineerCompanyPositions[0]])?this.applyForJob(d.CompanyPositions[g.NetworkEngineerCompanyPositions[0]],e):!e&&void Object(W.dialogBoxCreate)("Unforunately, you do not qualify for this position")},K.prototype.applyForBusinessJob=function(e=!1){return this.applyForJob(d.CompanyPositions[g.BusinessCompanyPositions[0]],e)},K.prototype.applyForBusinessConsultantJob=function(e=!1){return this.applyForJob(d.CompanyPositions[g.BusinessConsultantCompanyPositions[0]],e)},K.prototype.applyForSecurityJob=function(e=!1){return this.applyForJob(d.CompanyPositions[g.SecurityCompanyPositions[2]],e)},K.prototype.applyForAgentJob=function(e=!1){var t=p.Companies[this.location];return this.isQualified(t,d.CompanyPositions[g.AgentCompanyPositions[0]])?this.applyForJob(d.CompanyPositions[g.AgentCompanyPositions[0]],e):!e&&void Object(W.dialogBoxCreate)("Unforunately, you do not qualify for this position")},K.prototype.applyForEmployeeJob=function(e=!1){var t=p.Companies[this.location];if(this.isQualified(t,d.CompanyPositions[g.MiscCompanyPositions[1]])){if(this.companyName=t.name,this.jobs[t.name]=g.MiscCompanyPositions[1],document.getElementById("world-menu-header").click(),document.getElementById("world-menu-header").click(),e)return!0;Object(W.dialogBoxCreate)("Congratulations, you are now employed at "+this.companyName),E.Engine.loadLocationContent()}else{if(e)return!1;Object(W.dialogBoxCreate)("Unforunately, you do not qualify for this position")}},K.prototype.applyForPartTimeEmployeeJob=function(e=!1){var t=p.Companies[this.location];if(this.isQualified(t,d.CompanyPositions[g.PartTimeCompanyPositions[1]])){if(this.companyName=t.name,this.jobs[t.name]=g.PartTimeCompanyPositions[1],document.getElementById("world-menu-header").click(),document.getElementById("world-menu-header").click(),e)return!0;Object(W.dialogBoxCreate)("Congratulations, you are now employed part-time at "+this.companyName),E.Engine.loadLocationContent()}else{if(e)return!1;Object(W.dialogBoxCreate)("Unforunately, you do not qualify for this position")}},K.prototype.applyForWaiterJob=function(e=!1){var t=p.Companies[this.location];if(this.isQualified(t,d.CompanyPositions[g.MiscCompanyPositions[0]])){if(this.companyName=t.name,this.jobs[t.name]=g.MiscCompanyPositions[0],document.getElementById("world-menu-header").click(),document.getElementById("world-menu-header").click(),e)return!0;Object(W.dialogBoxCreate)("Congratulations, you are now employed as a waiter at "+this.companyName),E.Engine.loadLocationContent()}else{if(e)return!1;Object(W.dialogBoxCreate)("Unforunately, you do not qualify for this position")}},K.prototype.applyForPartTimeWaiterJob=function(e=!1){var t=p.Companies[this.location];if(this.isQualified(t,d.CompanyPositions[g.PartTimeCompanyPositions[0]])){if(this.companyName=t.name,this.jobs[t.name]=g.PartTimeCompanyPositions[0],document.getElementById("world-menu-header").click(),document.getElementById("world-menu-header").click(),e)return!0;Object(W.dialogBoxCreate)("Congratulations, you are now employed as a part-time waiter at "+this.companyName),E.Engine.loadLocationContent()}else{if(e)return!1;Object(W.dialogBoxCreate)("Unforunately, you do not qualify for this position")}},K.prototype.isQualified=function(e,t){var n=e.jobStatReqOffset,a=t.requiredHacking>0?t.requiredHacking+n:0,i=t.requiredStrength>0?t.requiredStrength+n:0,r=t.requiredDefense>0?t.requiredDefense+n:0,o=t.requiredDexterity>0?t.requiredDexterity+n:0,s=t.requiredDexterity>0?t.requiredDexterity+n:0,l=t.requiredCharisma>0?t.requiredCharisma+n:0;return this.hacking_skill>=a&&this.strength>=i&&this.defense>=r&&this.dexterity>=o&&this.agility>=s&&this.charisma>=l&&e.playerReputation>=t.requiredReputation},K.prototype.reapplyAllAugmentations=function(e=!0){console.log("Re-applying augmentations"),e&&this.resetMultipliers();for(let e=0;et}var r=C.Factions.Illuminati;!r.isBanned&&!r.isMember&&!r.alreadyInvited&&t>=30&&this.money.gte(15e10)&&this.hacking_skill>=1500&&this.strength>=1200&&this.defense>=1200&&this.dexterity>=1200&&this.agility>=1200&&e.push(r);var o=C.Factions.Daedalus;!o.isBanned&&!o.isMember&&!o.alreadyInvited&&t>=Math.round(30*s.BitNodeMultipliers.DaedalusAugsRequirement)&&this.money.gte(1e11)&&(this.hacking_skill>=2500||this.strength>=1500&&this.defense>=1500&&this.dexterity>=1500&&this.agility>=1500)&&e.push(o);var l=C.Factions["The Covenant"];!l.isBanned&&!l.isMember&&!l.alreadyInvited&&t>=20&&this.money.gte(75e9)&&this.hacking_skill>=850&&this.strength>=850&&this.defense>=850&&this.dexterity>=850&&this.agility>=850&&e.push(l);var c=C.Factions.ECorp;c.isBanned||c.isMember||c.alreadyInvited||!i(S.Locations.AevumECorp)||e.push(c);var u=C.Factions.MegaCorp;u.isBanned||u.isMember||u.alreadyInvited||!i(S.Locations.Sector12MegaCorp)||e.push(u);var m=C.Factions["Bachman & Associates"];m.isBanned||m.isMember||m.alreadyInvited||!i(S.Locations.AevumBachmanAndAssociates)||e.push(m);var h=C.Factions["Blade Industries"];h.isBanned||h.isMember||h.alreadyInvited||!i(S.Locations.Sector12BladeIndustries)||e.push(h);var d=C.Factions.NWO;d.isBanned||d.isMember||d.alreadyInvited||!i(S.Locations.VolhavenNWO)||e.push(d);var g=C.Factions["Clarke Incorporated"];g.isBanned||g.isMember||g.alreadyInvited||!i(S.Locations.AevumClarkeIncorporated)||e.push(g);var f=C.Factions["OmniTek Incorporated"];f.isBanned||f.isMember||f.alreadyInvited||!i(S.Locations.VolhavenOmniTekIncorporated)||e.push(f);var y=C.Factions["Four Sigma"];y.isBanned||y.isMember||y.alreadyInvited||!i(S.Locations.Sector12FourSigma)||e.push(y);var b=C.Factions["KuaiGong International"];b.isBanned||b.isMember||b.alreadyInvited||!i(S.Locations.ChongqingKuaiGongInternational)||e.push(b);var v=C.Factions["Fulcrum Secret Technologies"],E=A.AllServers[R.SpecialServerIps[R.SpecialServerNames.FulcrumSecretTechnologies]];null==E?console.log("ERROR: Could not find Fulcrum Secret Technologies Server"):v.isBanned||v.isMember||v.alreadyInvited||!E.manuallyHacked||!i(S.Locations.AevumFulcrumTechnologies,25e4)||e.push(v);var k=C.Factions.BitRunners,T=this.getHomeComputer(),O=A.AllServers[R.SpecialServerIps[R.SpecialServerNames.BitRunnersServer]];null==O?console.log("ERROR: Could not find BitRunners Server"):!k.isBanned&&!k.isMember&&O.manuallyHacked&&!k.alreadyInvited&&this.hacking_skill>=500&&T.maxRam>=128&&e.push(k);var M=C.Factions["The Black Hand"],P=A.AllServers[R.SpecialServerIps[R.SpecialServerNames.TheBlackHandServer]];null==P?console.log("ERROR: Could not find The Black Hand Server"):!M.isBanned&&!M.isMember&&P.manuallyHacked&&!M.alreadyInvited&&this.hacking_skill>=350&&T.maxRam>=64&&e.push(M);var w=C.Factions.NiteSec,x=A.AllServers[R.SpecialServerIps[R.SpecialServerNames.NiteSecServer]];null==x?console.log("ERROR: Could not find NiteSec Server"):!w.isBanned&&!w.isMember&&x.manuallyHacked&&!w.alreadyInvited&&this.hacking_skill>=200&&T.maxRam>=32&&e.push(w);var N=C.Factions.Chongqing;N.isBanned||N.isMember||N.alreadyInvited||!this.money.gte(2e7)||this.city!=S.Locations.Chongqing||e.push(N);var I=C.Factions["Sector-12"];I.isBanned||I.isMember||I.alreadyInvited||!this.money.gte(15e6)||this.city!=S.Locations.Sector12||e.push(I);var L=C.Factions["New Tokyo"];L.isBanned||L.isMember||L.alreadyInvited||!this.money.gte(2e7)||this.city!=S.Locations.NewTokyo||e.push(L);var D=C.Factions.Aevum;D.isBanned||D.isMember||D.alreadyInvited||!this.money.gte(4e7)||this.city!=S.Locations.Aevum||e.push(D);var B=C.Factions.Ishima;B.isBanned||B.isMember||B.alreadyInvited||!this.money.gte(3e7)||this.city!=S.Locations.Ishima||e.push(B);var W=C.Factions.Volhaven;W.isBanned||W.isMember||W.alreadyInvited||!this.money.gte(5e7)||this.city!=S.Locations.Volhaven||e.push(W);var j=C.Factions["Speakers for the Dead"];!j.isBanned&&!j.isMember&&!j.alreadyInvited&&this.hacking_skill>=100&&this.strength>=300&&this.defense>=300&&this.dexterity>=300&&this.agility>=300&&this.numPeopleKilled>=30&&this.karma<=-45&&!n.includes(S.Locations.Sector12CIA)&&!n.includes(S.Locations.Sector12NSA)&&e.push(j);var F=C.Factions["The Dark Army"];!F.isBanned&&!F.isMember&&!F.alreadyInvited&&this.hacking_skill>=300&&this.strength>=300&&this.defense>=300&&this.dexterity>=300&&this.agility>=300&&this.city==S.Locations.Chongqing&&this.numPeopleKilled>=5&&this.karma<=-45&&!n.includes(S.Locations.Sector12CIA)&&!n.includes(S.Locations.Sector12NSA)&&e.push(F);var U=C.Factions["The Syndicate"];!U.isBanned&&!U.isMember&&!U.alreadyInvited&&this.hacking_skill>=200&&this.strength>=200&&this.defense>=200&&this.dexterity>=200&&this.agility>=200&&(this.city==S.Locations.Aevum||this.city==S.Locations.Sector12)&&this.money.gte(1e7)&&this.karma<=-90&&!n.includes(S.Locations.Sector12CIA)&&!n.includes(S.Locations.Sector12NSA)&&e.push(U);var H=C.Factions.Silhouette;!H.isBanned&&!H.isMember&&!H.alreadyInvited&&(a.includes("Chief Technology Officer")||a.includes("Chief Financial Officer")||a.includes("Chief Executive Officer"))&&this.money.gte(15e6)&&this.karma<=-22&&e.push(H);var G=C.Factions.Tetrads;!G.isBanned&&!G.isMember&&!G.alreadyInvited&&(this.city==S.Locations.Chongqing||this.city==S.Locations.NewTokyo||this.city==S.Locations.Ishima)&&this.strength>=75&&this.defense>=75&&this.dexterity>=75&&this.agility>=75&&this.karma<=-18&&e.push(G);var K=C.Factions["Slum Snakes"];!K.isBanned&&!K.isMember&&!K.alreadyInvited&&this.strength>=30&&this.defense>=30&&this.dexterity>=30&&this.agility>=30&&this.karma<=-9&&this.money.gte(1e6)&&e.push(K);for(var q=C.Factions.Netburners,$=0,Y=0,z=0,V=0;V=80&&$>=8&&Y>=4&&z>=100&&e.push(q);var J=C.Factions["Tian Di Hui"];J.isBanned||J.isMember||J.alreadyInvited||!this.money.gte(1e6)||!(this.hacking_skill>=50)||this.city!=S.Locations.Chongqing&&this.city!=S.Locations.NewTokyo&&this.city!=S.Locations.Ishima||e.push(J);var X=C.Factions.CyberSec,Q=A.AllServers[R.SpecialServerIps[R.SpecialServerNames.CyberSecServer]];return null==Q?console.log("ERROR: Could not find CyberSec Server"):!X.isBanned&&!X.isMember&&Q.manuallyHacked&&!X.alreadyInvited&&this.hacking_skill>=50&&e.push(X),e},K.prototype.inGang=function(){return null!=this.gang&&void 0!=this.gang&&this.gang instanceof O.b},K.prototype.startGang=function(e,t){this.gang=new O.b(e,t)},K.prototype.hasCorporation=function(){return null!=this.corporation&&this.corporation instanceof f.c},K.prototype.inBladeburner=function(){return null!=this.bladeburner&&this.bladeburner instanceof l.a},K.prototype.setBitNodeNumber=function(e){this.bitNodeN=e},K.prototype.queueAugmentation=function(e){for(const t in this.queuedAugmentations)if(this.queuedAugmentations[t].name==e)return void console.log("tried to queue "+e+" twice, this may be a bug");for(const t in this.augmentations)if(this.augmentations[t].name==e)return void console.log("tried to queue "+e+" but we already have that aug");this.firstAugPurchased=!0,this.queuedAugmentations.push(new r.PlayerOwnedAugmentation(e))},K.prototype.gainCodingContractReward=function(e,t=1){if(null==e||null==e.type||null==e)return"No reward for this contract";switch(e.type){case c.CodingContractRewardType.FactionReputation:if(null==e.name||!(C.Factions[e.name]instanceof k.Faction))return e.type=c.CodingContractRewardType.FactionReputationAll,this.gainCodingContractReward(e);var n=_.CONSTANTS.CodingContractBaseFactionRepGain*t;return C.Factions[e.name].playerReputation+=n,`Gained ${n} faction reputation for ${e.name}`;case c.CodingContractRewardType.FactionReputationAll:const r=_.CONSTANTS.CodingContractBaseFactionRepGain*t,o=["Bladeburners"];var a=this.factions.slice();if(0==(a=a.filter(e=>!o.includes(e))).length)return e.type=c.CodingContractRewardType.Money,this.gainCodingContractReward(e,t);const l=Math.floor(r/a.length);for(const e of a)C.Factions[e]instanceof k.Faction&&(C.Factions[e].playerReputation+=l);return`Gained ${l} reputation for each of the following factions: ${a.toString()}`;case c.CodingContractRewardType.CompanyReputation:if(null==e.name||!(p.Companies[e.name]instanceof u.Company))return e.type=c.CodingContractRewardType.FactionReputationAll,this.gainCodingContractReward(e);n=_.CONSTANTS.CodingContractBaseCompanyRepGain*t;return p.Companies[e.name].playerReputation+=n,`Gained ${n} company reputation for ${e.name}`;case c.CodingContractRewardType.Money:default:var i=_.CONSTANTS.CodingContractBaseMoneyGain*t*s.BitNodeMultipliers.CodingContractMoney;return this.gainMoney(i),this.recordMoneySource(i,"codingcontract"),`Gained ${D.numeralWrapper.format(i,"$0.000a")}`}},K.prototype.toJSON=function(){return Object(U.Generic_toJSON)("PlayerObject",this)},K.fromJSON=function(e){return Object(U.Generic_fromJSON)(K,e.data)},U.Reviver.constructors.PlayerObject=K;let $=new K},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.CONSTANTS={Version:"0.45.1",MaxSkillLevel:975,MilliPerCycle:200,CorpFactionRepRequirement:2e5,BaseCostFor1GBOfRamHome:32e3,BaseCostFor1GBOfRamServer:55e3,BaseCostFor1GBOfRamHacknetNode:3e4,TravelCost:2e5,BaseCostForHacknetNode:1e3,BaseCostForHacknetNodeCore:5e5,HacknetNodeMoneyGainPerLevel:1.6,HacknetNodePurchaseNextMult:1.85,HacknetNodeUpgradeLevelMult:1.04,HacknetNodeUpgradeRamMult:1.28,HacknetNodeUpgradeCoreMult:1.48,HacknetNodeMaxLevel:200,HacknetNodeMaxRam:64,HacknetNodeMaxCores:16,BaseFavorToDonate:150,DonateMoneyToRepDivisor:1e6,FactionReputationToFavorBase:500,FactionReputationToFavorMult:1.02,CompanyReputationToFavorBase:500,CompanyReputationToFavorMult:1.02,NeuroFluxGovernorLevelMult:1.14,ScriptBaseRamCost:1.6,ScriptDomRamCost:25,ScriptWhileRamCost:0,ScriptForRamCost:0,ScriptIfRamCost:0,ScriptHackRamCost:.1,ScriptHackAnalyzeRamCost:1,ScriptGrowRamCost:.15,ScriptGrowthAnalyzeRamCost:1,ScriptWeakenRamCost:.15,ScriptScanRamCost:.2,ScriptPortProgramRamCost:.05,ScriptRunRamCost:1,ScriptExecRamCost:1.3,ScriptSpawnRamCost:2,ScriptScpRamCost:.6,ScriptKillRamCost:.5,ScriptHasRootAccessRamCost:.05,ScriptGetHostnameRamCost:.05,ScriptGetHackingLevelRamCost:.05,ScriptGetMultipliersRamCost:4,ScriptGetServerRamCost:.1,ScriptFileExistsRamCost:.1,ScriptIsRunningRamCost:.1,ScriptHacknetNodesRamCost:4,ScriptHNUpgLevelRamCost:.4,ScriptHNUpgRamRamCost:.6,ScriptHNUpgCoreRamCost:.8,ScriptGetStockRamCost:2,ScriptBuySellStockRamCost:2.5,ScriptGetPurchaseServerRamCost:.25,ScriptPurchaseServerRamCost:2.25,ScriptGetPurchasedServerLimit:.05,ScriptGetPurchasedServerMaxRam:.05,ScriptRoundRamCost:.05,ScriptReadWriteRamCost:1,ScriptArbScriptRamCost:1,ScriptGetScriptRamCost:.1,ScriptGetHackTimeRamCost:.05,ScriptGetFavorToDonate:.1,ScriptCodingContractBaseRamCost:10,ScriptSleeveBaseRamCost:4,ScriptSingularityFn1RamCost:1,ScriptSingularityFn2RamCost:2,ScriptSingularityFn3RamCost:3,ScriptSingularityFnRamMult:2,ScriptGangApiBaseRamCost:4,ScriptBladeburnerApiBaseRamCost:4,NumNetscriptPorts:20,HomeComputerMaxRam:1073741824,ServerBaseGrowthRate:1.03,ServerMaxGrowthRate:1.0035,ServerFortifyAmount:.002,ServerWeakenAmount:.05,PurchasedServerLimit:25,PurchasedServerMaxRam:1048576,AugmentationCostMultiplier:5,AugmentationRepMultiplier:2.5,MultipleAugMultiplier:1.9,TorRouterCost:2e5,InfiltrationBribeBaseAmount:1e5,InfiltrationMoneyValue:5e3,InfiltrationRepValue:1.4,WSEAccountCost:2e8,TIXAPICost:5e9,MarketData4SCost:1e9,MarketDataTixApi4SCost:25e9,StockMarketCommission:1e5,HospitalCostPerHp:1e5,IntelligenceCrimeWeight:.05,IntelligenceInfiltrationWeight:.1,IntelligenceCrimeBaseExpGain:.001,IntelligenceProgramBaseExpGain:500,IntelligenceTerminalHackBaseExpGain:200,IntelligenceSingFnBaseExpGain:.002,IntelligenceClassBaseExpGain:1e-6,IntelligenceHackingMissionBaseExpGain:.03,HackingMissionRepToDiffConversion:1e4,HackingMissionRepToRewardConversion:7,HackingMissionSpamTimeIncrease:25e3,HackingMissionTransferAttackIncrease:1.05,HackingMissionMiscDefenseIncrease:1.05,HackingMissionDifficultyToHacking:135,HackingMissionHowToPlay:"Hacking missions are a minigame that, if won, will reward you with faction reputation.

    In this game you control a set of Nodes and use them to try and defeat an enemy. Your Nodes are colored blue, while the enemy's are red. There are also other nodes on the map colored gray that initially belong to neither you nor the enemy. The goal of the game is to capture all of the enemy's Database nodes within the time limit. If you fail to do this, you will lose.

    Each Node has three stats: Attack, Defense, and HP. There are five different actions that a Node can take:

    Attack - Targets an enemy Node and lowers its HP. The effectiveness is determined by the owner's Attack, the Player's hacking level, and the enemy's defense.

    Scan - Targets an enemy Node and lowers its Defense. The effectiveness is determined by the owner's Attack, the Player's hacking level, and the enemy's defense.

    Weaken - Targets an enemy Node and lowers its Attack. The effectiveness is determined by the owner's Attack, the Player's hacking level, and the enemy's defense.

    Fortify - Raises the Node's Defense. The effectiveness is determined by your hacking level.

    Overflow - Raises the Node's Attack but lowers its Defense. The effectiveness is determined by your hacking level.

    Note that when determining the effectiveness of the above actions, the TOTAL Attack or Defense of the team is used, not just the Attack/Defense of the individual Node that is performing the action.

    To capture a Node, you must lower its HP down to 0.

    There are six different types of Nodes:

    CPU Core - These are your main Nodes that are used to perform actions. Capable of performing every action

    Firewall - Nodes with high defense. These Nodes can 'Fortify'

    Database - A special type of Node. The player's objective is to conquer all of the enemy's Database Nodes within the time limit. These Nodes cannot perform any actions

    Spam - Conquering one of these Nodes will slow the enemy's trace, giving the player additional time to complete the mission. These Nodes cannot perform any actions

    Transfer - Conquering one of these nodes will increase the Attack of all of your CPU Cores by a small fixed percentage. These Nodes are capable of performing every action except the 'Attack' action

    Shield - Nodes with high defense. These Nodes can 'Fortify'

    To assign an action to a Node, you must first select one of your Nodes. This can be done by simply clicking on it. Double-clicking a node will select all of your Nodes of the same type (e.g. select all CPU Core Nodes or all Transfer Nodes). Note that only Nodes that can perform actions (CPU Core, Transfer, Shield, Firewall) can be selected. Selected Nodes will be denoted with a white highlight. After selecting a Node or multiple Nodes, select its action using the Action Buttons near the top of the screen. Every action also has a corresponding keyboard shortcut.

    For certain actions such as attacking, scanning, and weakening, the Node performing the action must have a target. To target another node, simply click-and-drag from the 'source' Node to a target. A Node can only have one target, and you can target any Node that is adjacent to one of your Nodes (immediately above, below, or to the side. NOT diagonal). Furthermore, only CPU Cores and Transfer Nodes can target, since they are the only ones that can perform the related actions. To remove a target, you can simply click on the line that represents the connection between one of your Nodes and its target. Alternatively, you can select the 'source' Node and click the 'Drop Connection' button, or press 'd'.

    Other Notes:

    -Whenever a miscellenaous Node (not owned by the player or enemy) is conquered, the defense of all remaining miscellaneous Nodes that are not actively being targeted will increase by a fixed percentage.

    -Whenever a Node is conquered, its stats are significantly reduced

    -Miscellaneous Nodes slowly raise their defense over time

    -Nodes slowly regenerate health over time.",MillisecondsPer20Hours:72e6,GameCyclesPer20Hours:36e4,MillisecondsPer10Hours:36e6,GameCyclesPer10Hours:18e4,MillisecondsPer8Hours:288e5,GameCyclesPer8Hours:144e3,MillisecondsPer4Hours:144e5,GameCyclesPer4Hours:72e3,MillisecondsPer2Hours:72e5,GameCyclesPer2Hours:36e3,MillisecondsPerHour:36e5,GameCyclesPerHour:18e3,MillisecondsPerHalfHour:18e5,GameCyclesPerHalfHour:9e3,MillisecondsPerQuarterHour:9e5,GameCyclesPerQuarterHour:4500,MillisecondsPerFiveMinutes:3e5,GameCyclesPerFiveMinutes:1500,FactionWorkHacking:"Faction Hacking Work",FactionWorkField:"Faction Field Work",FactionWorkSecurity:"Faction Security Work",WorkTypeCompany:"Working for Company",WorkTypeCompanyPartTime:"Working for Company part-time",WorkTypeFaction:"Working for Faction",WorkTypeCreateProgram:"Working on Create a Program",WorkTypeStudyClass:"Studying or Taking a class at university",WorkTypeCrime:"Committing a crime",ClassStudyComputerScience:"studying Computer Science",ClassDataStructures:"taking a Data Structures course",ClassNetworks:"taking a Networks course",ClassAlgorithms:"taking an Algorithms course",ClassManagement:"taking a Management course",ClassLeadership:"taking a Leadership course",ClassGymStrength:"training your strength at a gym",ClassGymDefense:"training your defense at a gym",ClassGymDexterity:"training your dexterity at a gym",ClassGymAgility:"training your agility at a gym",ClassDataStructuresBaseCost:40,ClassNetworksBaseCost:80,ClassAlgorithmsBaseCost:320,ClassManagementBaseCost:160,ClassLeadershipBaseCost:320,ClassGymBaseCost:120,CrimeShoplift:"shoplift",CrimeRobStore:"rob a store",CrimeMug:"mug someone",CrimeLarceny:"commit larceny",CrimeDrugs:"deal drugs",CrimeBondForgery:"forge corporate bonds",CrimeTraffickArms:"traffick illegal arms",CrimeHomicide:"commit homicide",CrimeGrandTheftAuto:"commit grand theft auto",CrimeKidnap:"kidnap someone for ransom",CrimeAssassination:"assassinate a high-profile target",CrimeHeist:"pull off the ultimate heist",CodingContractBaseFactionRepGain:2500,CodingContractBaseCompanyRepGain:4e3,CodingContractBaseMoneyGain:75e6,TotalNumBitNodes:24,LatestUpdate:"\n v0.45.1\n * Added two new Corporation Researches\n * General UI improvements (by hydroflame and koriar)\n * Bug Fix: Sleeve Netscript API should no longer cause Dynamic RAM errors\n * Bug Fix: sleeve.getSleeveStats() should now work properly\n\n v0.45.0\n * Corporation changes:\n ** Decreased the time of a full market cycle from 15 seconds to 10 seconds.\n ** This means that each Corporation 'state' will now only take 2 seconds, rather than 3\n ** Increased initial salaries for newly-hired employees\n ** Increased the cost multiplier for upgrading office size (the cost will increase faster)\n ** The stats of your employees now has a slightly larger effect on production & sales\n ** Added several new Research upgrades\n ** Market-TA research now allows you to automatically set sale price at optimal values\n ** Market-TA research now works for Products (not just Materials)\n ** Reduced the amount of Scientific Research needed to unlock the Hi-Tech R&D Laboratory from 10k to 5k\n ** Energy Material requirement of the Software industry reduced from 1 to 0.5\n ** It is now slightly easier to increase the Software industry's production multiplier\n ** Industries now have a maximum number of allowed products, starting at 3. This can be increased through research.\n ** You can now see an approximation of how each material affects an industry's production multiplier by clicking the \"?\" help tip next to it\n ** Significantly changed the effects of the different employee positions. See updated descriptions\n ** Reduced the amount of money you gain from private investors\n ** Training employees is now 3x more effective\n ** Bug Fix: An industry's products are now properly separated between different cities\n * The QLink Augemntation is now significantly stronger, but also significantly more expensive (by hydroflame)\n * Added a Netscript API for Duplicate Sleeves (by hydroflame)\n * Modified the multipliers of BitNode-3 and BitNode-8 to make them slightly harder\n * After installing Augmentations, Duplicate Sleeves will now default to Synchronize if their Shock is 0\n * Bug Fix: Bladeburner's Hyperbolic Regeneration Chamber should no longer instantly refill all stamina\n * Bug Fix: growthAnalyze() function now properly accounts for BitNode multipliers\n * Bug Fix: The cost of purchasing Augmentations for Duplicate Sleeves no longer scales with how many Augs you've purchased for yourself\n "}},,function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const a=n(105);n(446),n(445),n(444),n(443),n(442),n(441),n(440),n(439),n(438),n(437),n(436),n(435),n(434),n(433);t.numeralWrapper=new class{constructor(){this.defaultLocale="en",this.defaultLocale="en"}updateLocale(e){return null!=a.locale(e)||(console.warn(`Invalid locale for numeral: ${e}`),a.locale(this.defaultLocale),!1)}format(e,t){return Math.abs(e)<1e-6&&(e=0),a(e).format(t)}formatBigNumber(e){return this.format(e,"0.000a")}formatMoney(e){return this.format(e,"$0.000a")}formatPercentage(e,t=2){const n="0."+"0".repeat(t)+"%";return this.format(e,n)}}},function(e,t,n){"use strict";function a(e,t={}){const n=document.createElement(e);return void 0!==t.id&&(n.id=t.id),void 0!==t.class&&(n.className=t.class),void 0!==t.innerHTML&&(n.innerHTML=t.innerHTML),void 0!==t.innerText&&(n.innerText=t.innerText),void 0!==t.tabIndex&&(n.tabIndex=t.tabIndex),function(e,t){void 0!==t.text&&(e.text=t.text),void 0!==t.href&&(e.href=t.href),void 0!==t.target&&(e.target=t.target)}(n,t),function(e,t){void 0!==t.name&&(e.name=t.name),void 0!==t.value&&(e.value=t.value),void 0!==t.type&&(e.type=t.type),void 0!==t.checked&&(e.checked=t.checked),void 0!==t.pattern&&(e.pattern=t.pattern),void 0!==t.maxLength&&(e.maxLength=t.maxLength),void 0!==t.placeholder&&(e.placeholder=t.placeholder),void 0!==t.max&&(e.max=t.max),void 0!==t.min&&(e.min=t.min),void 0!==t.step&&(e.step=t.step)}(n,t),function(e,t){void 0!==t.for&&(e.htmlFor=t.for)}(n,t),function(e,t){void 0!==t.clickListener&&e.addEventListener("click",t.clickListener),void 0!==t.inputListener&&e.addEventListener("input",t.inputListener),void 0!==t.changeListener&&e.addEventListener("change",t.changeListener),void 0!==t.onkeyup&&e.addEventListener("keyup",t.onkeyup),void 0!==t.onkeydown&&e.addEventListener("keydown",t.onkeydown),void 0!==t.onfocus&&e.addEventListener("focus",t.onfocus)}(n,t),function(e,t){void 0!==t.display&&(e.style.display=t.display),void 0!==t.visibility&&(e.style.visibility=t.visibility),void 0!==t.margin&&(e.style.margin=t.margin),void 0!==t.marginLeft&&(e.style.marginLeft=t.marginLeft),void 0!==t.marginTop&&(e.style.marginTop=t.marginTop),void 0!==t.padding&&(e.style.padding=t.padding),void 0!==t.color&&(e.style.color=t.color),void 0!==t.border&&(e.style.border=t.border),void 0!==t.float&&(e.style.cssFloat=t.float),void 0!==t.fontSize&&(e.style.fontSize=t.fontSize),void 0!==t.whiteSpace&&(e.style.whiteSpace=t.whiteSpace),void 0!==t.width&&(e.style.width=t.width),void 0!==t.backgroundColor&&(e.style.backgroundColor=t.backgroundColor),void 0!==t.position&&(e.style.position=t.position),void 0!==t.overflow&&(e.style.overflow=t.overflow)}(n,t),function(e,t){void 0!==t.tooltip&&""!==t.tooltip?(e.className+=" tooltip",e.appendChild(a("span",{class:"tooltiptext",innerHTML:t.tooltip}))):void 0!==t.tooltipleft?(e.className+=" tooltip",e.appendChild(a("span",{class:"tooltiptextleft",innerHTML:t.tooltipleft}))):void 0!==t.tooltipsmall?(e.className+=" tooltip",e.appendChild(a("span",{class:"tooltiptext smallfont",innerHTML:t.tooltipsmall}))):void 0!==t.tooltiplow&&(e.className+="tooltip",e.appendChild(a("span",{class:"tooltiptextlow",innerHTML:t.tooltiplow})))}(n,t),n}Object.defineProperty(t,"__esModule",{value:!0}),t.createElement=a},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.AugmentationNames={Targeting1:"Augmented Targeting I",Targeting2:"Augmented Targeting II",Targeting3:"Augmented Targeting III",SyntheticHeart:"Synthetic Heart",SynfibrilMuscle:"Synfibril Muscle",CombatRib1:"Combat Rib I",CombatRib2:"Combat Rib II",CombatRib3:"Combat Rib III",NanofiberWeave:"Nanofiber Weave",SubdermalArmor:"NEMEAN Subdermal Weave",WiredReflexes:"Wired Reflexes",GrapheneBoneLacings:"Graphene Bone Lacings",BionicSpine:"Bionic Spine",GrapheneBionicSpine:"Graphene Bionic Spine Upgrade",BionicLegs:"Bionic Legs",GrapheneBionicLegs:"Graphene Bionic Legs Upgrade",SpeechProcessor:"Speech Processor Implant",TITN41Injection:"TITN-41 Gene-Modification Injection",EnhancedSocialInteractionImplant:"Enhanced Social Interaction Implant",BitWire:"BitWire",ArtificialBioNeuralNetwork:"Artificial Bio-neural Network Implant",ArtificialSynapticPotentiation:"Artificial Synaptic Potentiation",EnhancedMyelinSheathing:"Enhanced Myelin Sheathing",SynapticEnhancement:"Synaptic Enhancement Implant",NeuralRetentionEnhancement:"Neural-Retention Enhancement",DataJack:"DataJack",ENM:"Embedded Netburner Module",ENMCore:"Embedded Netburner Module Core Implant",ENMCoreV2:"Embedded Netburner Module Core V2 Upgrade",ENMCoreV3:"Embedded Netburner Module Core V3 Upgrade",ENMAnalyzeEngine:"Embedded Netburner Module Analyze Engine",ENMDMA:"Embedded Netburner Module Direct Memory Access Upgrade",Neuralstimulator:"Neuralstimulator",NeuralAccelerator:"Neural Accelerator",CranialSignalProcessorsG1:"Cranial Signal Processors - Gen I",CranialSignalProcessorsG2:"Cranial Signal Processors - Gen II",CranialSignalProcessorsG3:"Cranial Signal Processors - Gen III",CranialSignalProcessorsG4:"Cranial Signal Processors - Gen IV",CranialSignalProcessorsG5:"Cranial Signal Processors - Gen V",NeuronalDensification:"Neuronal Densification",NuoptimalInjectorImplant:"Nuoptimal Nootropic Injector Implant",SpeechEnhancement:"Speech Enhancement",FocusWire:"FocusWire",PCDNI:"PC Direct-Neural Interface",PCDNIOptimizer:"PC Direct-Neural Interface Optimization Submodule",PCDNINeuralNetwork:"PC Direct-Neural Interface NeuroNet Injector",ADRPheromone1:"ADR-V1 Pheromone Gene",ADRPheromone2:"ADR-V2 Pheromone Gene",HacknetNodeCPUUpload:"Hacknet Node CPU Architecture Neural-Upload",HacknetNodeCacheUpload:"Hacknet Node Cache Architecture Neural-Upload",HacknetNodeNICUpload:"Hacknet Node NIC Architecture Neural-Upload",HacknetNodeKernelDNI:"Hacknet Node Kernel Direct-Neural Interface",HacknetNodeCoreDNI:"Hacknet Node Core Direct-Neural Interface",NeuroFluxGovernor:"NeuroFlux Governor",Neurotrainer1:"Neurotrainer I",Neurotrainer2:"Neurotrainer II",Neurotrainer3:"Neurotrainer III",Hypersight:"HyperSight Corneal Implant",LuminCloaking1:"LuminCloaking-V1 Skin Implant",LuminCloaking2:"LuminCloaking-V2 Skin Implant",HemoRecirculator:"HemoRecirculator",SmartSonar:"SmartSonar Implant",PowerRecirculator:"Power Recirculation Core",QLink:"QLink",TheRedPill:"The Red Pill",SPTN97:"SPTN-97 Gene Modification",HiveMind:"ECorp HVMind Implant",CordiARCReactor:"CordiARC Fusion Reactor",SmartJaw:"SmartJaw",Neotra:"Neotra",Xanipher:"Xanipher",nextSENS:"nextSENS Gene Modification",OmniTekInfoLoad:"OmniTek InfoLoad",PhotosyntheticCells:"Photosynthetic Cells",Neurolink:"BitRunners Neurolink",TheBlackHand:"The Black Hand",CRTX42AA:"CRTX42-AA Gene Modification",Neuregen:"Neuregen Gene Modification",CashRoot:"CashRoot Starter Kit",NutriGen:"NutriGen Implant",INFRARet:"INFRARET Enhancement",DermaForce:"DermaForce Particle Barrier",GrapheneBrachiBlades:"Graphene BranchiBlades Upgrade",GrapheneBionicArms:"Graphene Bionic Arms Upgrade",BrachiBlades:"BrachiBlades",BionicArms:"Bionic Arms",SNA:"Social Negotiation Assistant (S.N.A)",EsperEyewear:"EsperTech Bladeburner Eyewear",EMS4Recombination:"EMS-4 Recombination",OrionShoulder:"ORION-MKIV Shoulder",HyperionV1:"Hyperion Plasma Cannon V1",HyperionV2:"Hyperion Plasma Cannon V2",GolemSerum:"GOLEM Serum",VangelisVirus:"Vangelis Virus",VangelisVirus3:"Vangelis Virus 3.0",INTERLINKED:"I.N.T.E.R.L.I.N.K.E.D",BladeRunner:"Blade's Runners",BladeArmor:"BLADE-51b Tesla Armor",BladeArmorPowerCells:"BLADE-51b Tesla Armor: Power Cells Upgrade",BladeArmorEnergyShielding:"BLADE-51b Tesla Armor: Energy Shielding Upgrade",BladeArmorUnibeam:"BLADE-51b Tesla Armor: Unibeam Upgrade",BladeArmorOmnibeam:"BLADE-51b Tesla Armor: Omnibeam Upgrade",BladeArmorIPU:"BLADE-51b Tesla Armor: IPU Upgrade",BladesSimulacrum:"The Blade's Simulacrum"}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Locations={Aevum:"Aevum",Chongqing:"Chongqing",Ishima:"Ishima",NewTokyo:"New Tokyo",Sector12:"Sector-12",Volhaven:"Volhaven",AevumAeroCorp:"AeroCorp",AevumBachmanAndAssociates:"Bachman & Associates",AevumClarkeIncorporated:"Clarke Incorporated",AevumCrushFitnessGym:"Crush Fitness Gym",AevumECorp:"ECorp",AevumFulcrumTechnologies:"Fulcrum Technologies",AevumGalacticCybersystems:"Galactic Cybersystems",AevumNetLinkTechnologies:"NetLink Technologies",AevumPolice:"Aevum Police Headquarters",AevumRhoConstruction:"Rho Construction",AevumSlums:"Aevum Slums",AevumSnapFitnessGym:"Snap Fitness Gym",AevumSummitUniversity:"Summit University",AevumTravelAgency:"Aevum Travel Agency",AevumWatchdogSecurity:"Watchdog Security",ChongqingKuaiGongInternational:"KuaiGong International",ChongqingSlums:"Chongqing Slums",ChongqingSolarisSpaceSystems:"Solaris Space Systems",ChongqingTravelAgency:"Chongqing Travel Agency",Sector12AlphaEnterprises:"Alpha Enterprises",Sector12BladeIndustries:"Blade Industries",Sector12CIA:"Central Intelligence Agency",Sector12CarmichaelSecurity:"Carmichael Security",Sector12CityHall:"Sector-12 City Hall",Sector12DeltaOne:"DeltaOne",Sector12FoodNStuff:"FoodNStuff",Sector12FourSigma:"Four Sigma",Sector12IcarusMicrosystems:"Icarus Microsystems",Sector12IronGym:"Iron Gym",Sector12JoesGuns:"Joe's Guns",Sector12MegaCorp:"MegaCorp",Sector12NSA:"National Security Agency",Sector12PowerhouseGym:"Powerhouse Gym",Sector12RothmanUniversity:"Rothman University",Sector12Slums:"Sector-12 Slums",Sector12TravelAgency:"Sector-12 Travel Agency",Sector12UniversalEnergy:"Universal Energy",NewTokyoDefComm:"DefComm",NewTokyoGlobalPharmaceuticals:"Global Pharmaceuticals",NewTokyoNoodleBar:"Noodle Bar",NewTokyoSlums:"New Tokyo Slums",NewTokyoTravelAgency:"New Tokyo Travel Agency",NewTokyoVitaLife:"VitaLife",IshimaNovaMedical:"Nova Medical",IshimaOmegaSoftware:"Omega Software",IshimaSlums:"Ishima Slums",IshimaStormTechnologies:"Storm Technologies",IshimaTravelAgency:"Ishima Travel Agency",VolhavenCompuTek:"CompuTek",VolhavenHeliosLabs:"Helios Labs",VolhavenLexoCorp:"LexoCorp",VolhavenMilleniumFitnessGym:"Millenium Fitness Gym",VolhavenNWO:"NWO",VolhavenOmniTekIncorporated:"OmniTek Incorporated",VolhavenOmniaCybersystems:"Omnia Cybersystems",VolhavenSlums:"Volhaven Slums",VolhavenSysCoreSecurities:"SysCore Securities",VolhavenTravelAgency:"Volhaven Travel Agency",VolhavenZBInstituteOfTechnology:"ZB Institute of Technology",Hospital:"Hospital",WorldStockExchange:"World Stock Exchange"}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const a=n(44);function i(e){return e.every(a.isString)}t.replaceAt=function(e,t,n){return e.substr(0,t)+n+e.substr(t+n.length)},t.convertTimeMsToTimeElapsedString=function(e){const t=Math.floor(e/1e3),n=Math.floor(t/86400),a=t%86400,i=Math.floor(a/3600),r=a%3600,o=Math.floor(r/60);let s="";return n>0&&(s+=`${n} days `),i>0&&(s+=`${i} hours `),o>0&&(s+=`${o} minutes `),s+=`${r%60} seconds`},t.longestCommonStart=function(e){if(!i(e))return"";if(0===e.length)return"";const t=e.concat().sort(),n=t[0],a=t[t.length-1],r=n.length;let o=0;const s=(e,t)=>e.toUpperCase()===t.toUpperCase();for(;o=0;e--)if(1===n[e].nodeType)return!0;return!1},t.generateRandomString=function(e){let t="";const n="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";for(let a=0;a{t.delay=null,n()},e),t.delayResolve=n})}function g(e,t,n=null){var a="";null!=n&&(a=" (Line "+function(e,t){var n=t.scriptRef.codeCode();try{return((n=n.substring(0,e.start)).match(/\n/g)||[]).length+1}catch(e){return-1}}(n,e)+")");return"|"+e.serverIp+"|"+e.name+"|"+t+a}function _(e,t,n,i,s=1){if(null!=(m=Object(o.a)(t,n,e)))return i.scriptRef.log(t+" is already running on "+e.hostname),Promise.resolve(!1);for(var l=0;lh?(i.scriptRef.log("Cannot run script "+t+"(t="+s+") on "+e.hostname+" because there is not enough available RAM!"),Promise.resolve(!1)):(null==i.disableLogs.ALL&&null==i.disableLogs.exec&&null==i.disableLogs.run&&null==i.disableLogs.spawn&&i.scriptRef.log("Running script: "+t+" on "+e.hostname+" with "+s+" threads and args: "+Object(c.arrayToString)(n)+". May take a few seconds to start up..."),(m=new r.RunningScript(u,n)).threads=s,e.runningScripts.push(m),Object(a.c)(m,e),Promise.resolve(!0))}return i.scriptRef.log("Could not find script "+t+" on "+e.hostname),Promise.resolve(!1)}function f(e){if(!Object(p.isString)(e))return!1;let t=e.split("|");if(4!=t.length)return!1;var n=t[1];return!!Object(u.isValidIPAddress)(n)}},function(e,t,n){"use strict";n.r(t),function(e){n.d(t,"dialogBoxCreate",function(){return r}),n.d(t,"dialogBoxOpened",function(){return i});let a=[];e(document).click(function(t){i&&a.length>=1&&(e(t.target).closest(a[0]).length||(a[0].remove(),a.splice(0,1),0==a.length?i=!1:a[0].style.visibility="visible"))}),e(document).on("click",".dialog-box-close-button",function(e){i&&a.length>=1&&(a[0].remove(),a.splice(0,1),0==a.length?i=!1:a[0].style.visibility="visible")});var i=!1;function r(e,t=!1){var n=document.createElement("div");n.setAttribute("class","dialog-box-container");var r=document.createElement("div");r.setAttribute("class","dialog-box-content");var o,s=document.createElement("span");s.setAttribute("class","dialog-box-close-button"),s.innerHTML="×",t?(o=document.createElement("pre")).innerHTML=e:(o=document.createElement("p")).innerHTML=e.replace(/(?:\r\n|\r|\n)/g,"
    "),r.appendChild(s),r.appendChild(o),n.appendChild(r),document.body.appendChild(n),a.length>=1&&(n.style.visibility="hidden"),a.push(n),setTimeout(function(){i=!0},400)}}.call(this,n(79))},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const a=n(68);function i(e,t={}){const n=`color: ${null!=t.color?t.color:"var(--my-font-color)"}; background-color:var(--my-background-color);${void 0===t.id?" white-space:pre-wrap;":""}`,i=`${e}`;a.getElementById("terminal-input").insertAdjacentHTML("beforebegin",i),function(){const e=a.getElementById("terminal-container");e.scrollTop=e.scrollHeight}()}t.post=function(e){i(e)},t.postError=function(e){i(`ERROR: ${e}`,{color:"#ff2929"})},t.hackProgressBarPost=function(e){i(e,{id:"hack-progress-bar"})},t.hackProgressPost=function(e){i(e,{id:"hack-progress"})}},function(e,t,n){"use strict";n.r(t),function(e){n.d(t,"Engine",function(){return ue});var a=n(7),i=n(102),r=n(85),o=n(13),s=n(73),l=n(5),c=n(78),u=n(36),p=n(173),m=n(135),h=n(119),d=(n(38),n(18)),g=n(28),_=n(1),f=n(158),y=n(14),b=n(53),v=n(34),E=n(125),k=n(6),C=n(84),T=n(41),O=n(108),S=n(65),M=n(72),P=n(50),A=n(39),w=n(0),x=n(115),R=(n(30),n(130)),N=n(77),I=n(94),L=n(59),D=n(23),B=(n(74),n(19)),W=n(95),j=n(57),F=n(40),U=n(29),H=n(71),G=n(106),K=n(139),q=n(157),$=n(97),Y=n(172),z=n(12),V=n(3),J=n(171),X=n(170),Q=n(32),Z=n(9),ee=n(110),te=(n(15),n(33)),ne=(n(22),n(4)),ae=n(43),ie=n(156),re=n(31),oe=n(2),se=n.n(oe),le=n(113),ce=n.n(le);n(303),n(258),n(256),n(254),n(252),n(250),n(248),n(246),n(244),n(242),n(240),n(238),n(236),n(234),n(232),n(230),n(228),n(226),n(224),n(222),n(220),n(218),n(216),n(214),n(212);e(document).keydown(function(e){if(!0!==B.Settings.DisableHotkeys){try{if(Object(L.b)().isFocused())return}catch(e){}if(!(w.a.isWorking||N.b||M.c||m.a))if(84==e.keyCode&&e.altKey)e.preventDefault(),ue.loadTerminalContent();else if(e.keyCode===re.KEY.C&&e.altKey)e.preventDefault(),ue.loadCharacterContent();else if(e.keyCode===re.KEY.E&&e.altKey)e.preventDefault(),ue.loadScriptEditorContent();else if(e.keyCode===re.KEY.S&&e.altKey)e.preventDefault(),ue.loadActiveScriptsContent();else if(e.keyCode===re.KEY.H&&e.altKey)e.preventDefault(),ue.loadHacknetNodesContent();else if(e.keyCode===re.KEY.W&&e.altKey)e.preventDefault(),ue.loadWorldContent();else if(e.keyCode===re.KEY.J&&e.altKey)e.preventDefault(),ue.loadJobContent();else if(e.keyCode===re.KEY.R&&e.altKey)e.preventDefault(),ue.loadTravelContent();else if(e.keyCode===re.KEY.P&&e.altKey)e.preventDefault(),ue.loadCreateProgramContent();else if(e.keyCode===re.KEY.F&&e.altKey){if(z.routing.isOn(z.Page.Terminal)&&v.FconfSettings.ENABLE_BASH_HOTKEYS)return;e.preventDefault(),ue.loadFactionsContent()}else e.keyCode===re.KEY.A&&e.altKey?(e.preventDefault(),ue.loadAugmentationsContent()):e.keyCode===re.KEY.U&&e.altKey&&(e.preventDefault(),ue.loadTutorialContent());e.keyCode===re.KEY.O&&e.altKey&&(e.preventDefault(),Object(ee.b)())}});const ue={version:"",Debug:!0,Clickables:{saveMainMenuButton:null,deleteMainMenuButton:null},Display:{progress:null,statusText:null,hacking_skill:null,terminalContent:null,characterContent:null,scriptEditorContent:null,activeScriptsContent:null,hacknetNodesContent:null,worldContent:null,createProgramContent:null,factionsContent:null,factionContent:null,factionAugmentationsContent:null,augmentationsContent:null,tutorialContent:null,infiltrationContent:null,stockMarketContent:null,locationContent:null,workInProgressContent:null,redPillContent:null,cinematicTextContent:null,missionContent:null,characterInfo:null},_lastUpdate:(new Date).getTime(),_idleSpeed:200,loadTerminalContent:function(){ue.hideAllContent(),ue.Display.terminalContent.style.display="block",z.routing.navigateTo(z.Page.Terminal),Q.MainMenuLinks.Terminal.classList.add("active")},loadCharacterContent:function(){ue.hideAllContent(),ue.Display.characterContent.style.display="block",ue.updateCharacterInfo(),z.routing.navigateTo(z.Page.CharacterInfo),Q.MainMenuLinks.Stats.classList.add("active")},loadScriptEditorContent:function(e="",t=""){ue.hideAllContent(),ue.Display.scriptEditorContent.style.display="block";try{Object(L.b)().openScript(e,t)}catch(e){Object(ae.exceptionAlert)(e)}Object(L.e)(),z.routing.navigateTo(z.Page.ScriptEditor),Q.MainMenuLinks.ScriptEditor.classList.add("active")},loadActiveScriptsContent:function(){ue.hideAllContent(),ue.Display.activeScriptsContent.style.display="block",Object(r.c)(),z.routing.navigateTo(z.Page.ActiveScripts),Q.MainMenuLinks.ActiveScripts.classList.add("active")},loadHacknetNodesContent:function(){ue.hideAllContent(),ue.Display.hacknetNodesContent.style.display="block",Object(C.b)(),z.routing.navigateTo(z.Page.HacknetNodes),Q.MainMenuLinks.HacknetNodes.classList.add("active")},loadWorldContent:function(){ue.hideAllContent(),ue.Display.worldContent.style.display="block",ue.displayWorldInfo(),z.routing.navigateTo(z.Page.World),Q.MainMenuLinks.City.classList.add("active")},loadCreateProgramContent:function(){ue.hideAllContent(),ue.Display.createProgramContent.style.display="block",Object(R.a)(),z.routing.navigateTo(z.Page.CreateProgram),Q.MainMenuLinks.CreateProgram.classList.add("active")},loadFactionsContent:function(){ue.hideAllContent(),ue.Display.factionsContent.style.display="block",ue.displayFactionsInfo(),z.routing.navigateTo(z.Page.Factions),Q.MainMenuLinks.Factions.classList.add("active")},loadFactionContent:function(){ue.hideAllContent(),ue.Display.factionContent.style.display="block",z.routing.navigateTo(z.Page.Faction)},loadAugmentationsContent:function(){ue.hideAllContent(),ue.Display.augmentationsContent.style.display="block",Object(s.c)(ue.Display.augmentationsContent),z.routing.navigateTo(z.Page.Augmentations),Q.MainMenuLinks.Augmentations.classList.add("active")},loadTutorialContent:function(){ue.hideAllContent(),ue.Display.tutorialContent.style.display="block",z.routing.navigateTo(z.Page.Tutorial),Q.MainMenuLinks.Tutorial.classList.add("active")},loadDevMenuContent:function(){ue.hideAllContent(),Object(f.b)(),z.routing.navigateTo(z.Page.DevMenu),Q.MainMenuLinks.DevMenu.classList.add("active")},loadLocationContent:function(){ue.hideAllContent(),ue.Display.locationContent.style.display="block";try{Object(E.a)()}catch(e){Object(ae.exceptionAlert)(e),console.error(e)}z.routing.navigateTo(z.Page.Location)},loadTravelContent:function(){switch(w.a.city){case k.Locations.Aevum:w.a.location=k.Locations.AevumTravelAgency;break;case k.Locations.Chongqing:w.a.location=k.Locations.ChongqingTravelAgency;break;case k.Locations.Sector12:w.a.location=k.Locations.Sector12TravelAgency;break;case k.Locations.NewTokyo:w.a.location=k.Locations.NewTokyoTravelAgency;break;case k.Locations.Ishima:w.a.location=k.Locations.IshimaTravelAgency;break;case k.Locations.Volhaven:w.a.location=k.Locations.VolhavenTravelAgency;break;default:Object(Z.dialogBoxCreate)("ERROR: Invalid city. This is a bug please contact game dev")}ue.loadLocationContent()},loadJobContent:function(){""!=w.a.companyName?(w.a.location=w.a.companyName,ue.loadLocationContent()):Object(Z.dialogBoxCreate)("You do not currently have a job! You can visit various companies in the city and try to find a job.")},loadWorkInProgressContent:function(){ue.hideAllContent(),document.getElementById("mainmenu-container").style.visibility="hidden",ue.Display.workInProgressContent.style.display="block",z.routing.navigateTo(z.Page.WorkInProgress)},loadRedPillContent:function(){ue.hideAllContent(),document.getElementById("mainmenu-container").style.visibility="hidden",ue.Display.redPillContent.style.display="block",z.routing.navigateTo(z.Page.RedPill)},loadCinematicTextContent:function(){ue.hideAllContent(),document.getElementById("mainmenu-container").style.visibility="hidden",ue.Display.cinematicTextContent.style.display="block",z.routing.navigateTo(z.Page.CinematicText)},loadInfiltrationContent:function(){ue.hideAllContent(),ue.Display.infiltrationContent.style.display="block",z.routing.navigateTo(z.Page.Infiltration)},loadStockMarketContent:function(){ue.hideAllContent(),ue.Display.stockMarketContent.style.display="block",z.routing.navigateTo(z.Page.StockMarket),Object(U.g)()},loadGangContent:function(){ue.hideAllContent(),document.getElementById("gang-container")||w.a.inGang()?(w.a.gang.displayGangContent(w.a),z.routing.navigateTo(z.Page.Gang)):(ue.loadTerminalContent(),z.routing.navigateTo(z.Page.Terminal))},loadMissionContent:function(){ue.hideAllContent(),document.getElementById("mainmenu-container").style.visibility="hidden",document.getElementById("character-overview-wrapper").style.visibility="hidden",ue.Display.missionContent.style.display="block",z.routing.navigateTo(z.Page.Mission)},loadCorporationContent:function(){w.a.corporation instanceof g.c&&(ue.hideAllContent(),document.getElementById("character-overview-wrapper").style.visibility="hidden",z.routing.navigateTo(z.Page.Corporation),w.a.corporation.createUI())},loadBladeburnerContent:function(){if(w.a.bladeburner instanceof u.a)try{ue.hideAllContent(),z.routing.navigateTo(z.Page.Bladeburner),w.a.bladeburner.createContent()}catch(e){Object(ae.exceptionAlert)(e)}},loadSleevesContent:function(){try{ue.hideAllContent(),z.routing.navigateTo(z.Page.Sleeves),Object(K.createSleevesPage)(w.a)}catch(e){Object(ae.exceptionAlert)(e)}},loadResleevingContent:function(){try{ue.hideAllContent(),z.routing.navigateTo(z.Page.Resleeves),Object(q.createResleevesPage)(w.a)}catch(e){Object(ae.exceptionAlert)(e)}},hideAllContent:function(){ue.Display.terminalContent.style.display="none",ue.Display.characterContent.style.display="none",ue.Display.scriptEditorContent.style.display="none",ue.Display.activeScriptsContent.style.display="none",ue.Display.hacknetNodesContent.style.display="none",ue.Display.worldContent.style.display="none",ue.Display.createProgramContent.style.display="none",ue.Display.factionsContent.style.display="none",ue.Display.factionContent.style.display="none",ue.Display.factionAugmentationsContent.style.display="none",ue.Display.augmentationsContent.style.display="none",ue.Display.tutorialContent.style.display="none",ue.Display.locationContent.style.display="none",ue.Display.workInProgressContent.style.display="none",ue.Display.redPillContent.style.display="none",ue.Display.cinematicTextContent.style.display="none",ue.Display.infiltrationContent.style.display="none",ue.Display.stockMarketContent.style.display="none",ue.Display.missionContent.style.display="none",document.getElementById("gang-container")&&(document.getElementById("gang-container").style.display="none"),w.a.inGang()&&w.a.gang.clearUI(),w.a.corporation instanceof g.c&&w.a.corporation.clearUI(),w.a.bladeburner instanceof u.a&&w.a.bladeburner.clearContent(),Object(q.clearResleevesPage)(),Object(K.clearSleevesPage)(),ue.aevumLocationsList.style.display="none",ue.chongqingLocationsList.style.display="none",ue.sector12LocationsList.style.display="none",ue.newTokyoLocationsList.style.display="none",ue.ishimaLocationsList.style.display="none",ue.volhavenLocationsList.style.display="none",Q.MainMenuLinks.Terminal.classList.remove("active"),Q.MainMenuLinks.ScriptEditor.classList.remove("active"),Q.MainMenuLinks.ActiveScripts.classList.remove("active"),Q.MainMenuLinks.CreateProgram.classList.remove("active"),Q.MainMenuLinks.Stats.classList.remove("active"),Q.MainMenuLinks.Factions.classList.remove("active"),Q.MainMenuLinks.Augmentations.classList.remove("active"),Q.MainMenuLinks.HacknetNodes.classList.remove("active"),Q.MainMenuLinks.Sleeves.classList.remove("active"),Q.MainMenuLinks.City.classList.remove("active"),Q.MainMenuLinks.Travel.classList.remove("active"),Q.MainMenuLinks.Job.classList.remove("active"),Q.MainMenuLinks.StockMarket.classList.remove("active"),Q.MainMenuLinks.Bladeburner.classList.remove("active"),Q.MainMenuLinks.Corporation.classList.remove("active"),Q.MainMenuLinks.Gang.classList.remove("active"),Q.MainMenuLinks.Tutorial.classList.remove("active"),Q.MainMenuLinks.Options.classList.remove("active"),Q.MainMenuLinks.DevMenu.classList.remove("active"),Object(f.a)()},displayCharacterOverviewInfo:function(){ce.a.render(se.a.createElement(p.a,null),document.getElementById("character-overview-text"));const e=document.getElementById("character-overview-save-button");B.Settings.AutosaveInterval?e.classList.remove("flashing-button"):e.classList.add("flashing-button")},updateCharacterInfo:function(){Object(Y.displayCharacterInfo)(ue.Display.characterInfo,w.a)},aevumLocationsList:null,chongqingLocationsList:null,sector12LocationsList:null,newTokyoLocationsList:null,ishimaLocationsList:null,volhavenLocationsList:null,displayWorldInfo:function(){ue.aevumLocationsList.style.display="none",ue.chongqingLocationsList.style.display="none",ue.sector12LocationsList.style.display="none",ue.newTokyoLocationsList.style.display="none",ue.ishimaLocationsList.style.display="none",ue.volhavenLocationsList.style.display="none",document.getElementById("world-city-name").innerHTML=w.a.city;document.getElementById("world-city-desc");switch(w.a.city){case k.Locations.Aevum:ue.aevumLocationsList.style.display="inline";break;case k.Locations.Chongqing:ue.chongqingLocationsList.style.display="inline";break;case k.Locations.Sector12:ue.sector12LocationsList.style.display="inline",3!==w.a.bitNodeN&&!P.e||8===w.a.bitNodeN?document.getElementById("sector12-cityhall-li").style.display="none":document.getElementById("sector12-cityhall-li").style.display="block";break;case k.Locations.NewTokyo:ue.newTokyoLocationsList.style.display="inline";break;case k.Locations.Ishima:ue.ishimaLocationsList.style.display="inline";break;case k.Locations.Volhaven:ue.volhavenLocationsList.style.display="inline";break;default:console.log("Invalid city value in Player object!")}var e,t=document.getElementById("generic-locations-list");(t.style.display="inline",Object(te.removeChildrenFromElement)(t),(e=Object(ne.createElement)("li")).appendChild(Object(ne.createElement)("a",{innerText:"World Stock Exchange",class:"a-link-button",clickListener:()=>(w.a.location=k.Locations.WorldStockExchange,ue.loadStockMarketContent(),!1)})),t.appendChild(e),w.a.corporation instanceof g.c&&null==document.getElementById("location-corporation-button"))&&((e=Object(ne.createElement)("li")).appendChild(Object(ne.createElement)("a",{innerText:w.a.corporation.name,id:"location-corporation-button",class:"a-link-button",clickListener:()=>(ue.loadCorporationContent(),!1)})),t.appendChild(e));w.a.bladeburner instanceof u.a&&((e=Object(ne.createElement)("li")).appendChild(Object(ne.createElement)("a",{innerText:"Bladeburner Headquarters",class:"a-link-button",clickListener:()=>(ue.loadBladeburnerContent(),!1)})),t.appendChild(e))},displayFactionsInfo:function(){Object(te.removeChildrenFromElement)(ue.Display.factionsContent),ue.Display.factionsContent.appendChild(Object(ne.createElement)("h1",{innerText:"Factions"})),ue.Display.factionsContent.appendChild(Object(ne.createElement)("p",{innerText:"Lists all factions you have joined"}));var e=Object(ne.createElement)("ul");ue.Display.factionsContent.appendChild(Object(ne.createElement)("br"));for(var t=0;t(ue.loadFactionContent(),Object(b.a)(n),!1)})),e.appendChild(Object(ne.createElement)("br"))}();ue.Display.factionsContent.appendChild(e),ue.Display.factionsContent.appendChild(Object(ne.createElement)("br")),ue.Display.factionsContent.appendChild(Object(ne.createElement)("h1",{innerText:"Outstanding Faction Invitations"})),ue.Display.factionsContent.appendChild(Object(ne.createElement)("p",{width:"70%",innerText:"Lists factions you have been invited to, as well as factions you have previously rejected. You can accept these faction invitations at any time."}));var n=Object(ne.createElement)("ul");for(t=0;t{if(!t.isTrusted)return!1;Object(b.c)(y.Factions[e]);for(var n=0;n0&&(ue._lastUpdate=e-n,w.a.lastUpdate=e-n,ue.updateGame(t)),window.requestAnimationFrame(ue.idleTimer)},updateGame:function(e=1){var t=e*ue._idleSpeed;null==w.a.totalPlaytime&&(w.a.totalPlaytime=0),null==w.a.playtimeSinceLastAug&&(w.a.playtimeSinceLastAug=0),null==w.a.playtimeSinceLastBitnode&&(w.a.playtimeSinceLastBitnode=0),w.a.totalPlaytime+=t,w.a.playtimeSinceLastAug+=t,w.a.playtimeSinceLastBitnode+=t,!0===H.a.actionStarted&&(ue._totalActionTime=H.a.actionTime,ue._actionTimeLeft=H.a.actionTime,ue._actionInProgress=!0,ue._actionProgressBarCount=1,ue._actionProgressStr="[ ]",ue._actionTimeStr="Time left: ",H.a.actionStarted=!1),w.a.isWorking&&(w.a.workType==_.CONSTANTS.WorkTypeFaction?w.a.workForFaction(e):w.a.workType==_.CONSTANTS.WorkTypeCreateProgram?w.a.createProgramWork(e):w.a.workType==_.CONSTANTS.WorkTypeStudyClass?w.a.takeClass(e):w.a.workType==_.CONSTANTS.WorkTypeCrime?w.a.commitCrime(e):w.a.workType==_.CONSTANTS.WorkTypeCompanyPartTime?w.a.workPartTime(e):w.a.work(e)),w.a.hasWseAccount&&Object(U.m)(e),2==w.a.bitNodeN&&w.a.inGang()&&w.a.gang.process(e,w.a),M.c&&M.b&&M.b.process(e),w.a.corporation instanceof g.c&&w.a.corporation.storeCycles(e),w.a.bladeburner instanceof u.a&&w.a.bladeburner.storeCycles(e);for(let t=0;t0?(t.innerHTML=e,t.setAttribute("class","notification-on")):(t.innerHTML="",t.setAttribute("class","notification-off")),ue.Counters.createProgramNotifications=10}if(ue.Counters.checkFactionInvitations<=0){var n=w.a.checkForFactionInvitations();if(n.length>0){!1===w.a.firstFacInvRecvd&&(w.a.firstFacInvRecvd=!0,document.getElementById("factions-tab").style.display="list-item",document.getElementById("character-menu-header").click(),document.getElementById("character-menu-header").click());var a=n[Math.floor(Math.random()*n.length)];Object(b.b)(a)}ue.Counters.checkFactionInvitations=100}if(ue.Counters.passiveFactionGrowth<=0){var s=Math.floor(600-ue.Counters.passiveFactionGrowth);Object(b.d)(s),ue.Counters.passiveFactionGrowth=600}if(ue.Counters.messages<=0&&(Object(S.b)(),o.Augmentations[l.AugmentationNames.TheRedPill].owned?ue.Counters.messages=4500:ue.Counters.messages=150),ue.Counters.sCr<=0&&(w.a.hasWseAccount&&Object(U.q)(),ue.Counters.sCr=1500),ue.Counters.mechanicProcess<=0){if(w.a.corporation instanceof g.c&&w.a.corporation.process(),w.a.bladeburner instanceof u.a)try{w.a.bladeburner.process()}catch(e){Object(ae.exceptionAlert)("Exception caught in Bladeburner.process(): "+e)}ue.Counters.mechanicProcess=5}ue.Counters.contractGeneration<=0&&(Math.random()<=.25&&Object(h.b)(),ue.Counters.contractGeneration=3e3)},_totalActionTime:0,_actionTimeLeft:0,_actionTimeStr:"Time left: ",_actionProgressStr:"[ ]",_actionProgressBarCount:1,_actionInProgress:!1,updateHackProgress:function(e=1){var t=e*ue._idleSpeed;ue._actionTimeLeft-=t/1e3,ue._actionTimeLeft=Math.max(ue._actionTimeLeft,0);for(var n=Math.round(100*(1-ue._actionTimeLeft/ue._totalActionTime));2*ue._actionProgressBarCount<=n;)ue._actionProgressStr=Object(a.replaceAt)(ue._actionProgressStr,ue._actionProgressBarCount,"|"),ue._actionProgressBarCount+=1;ue._actionTimeStr="Time left: "+Math.max(0,Math.round(ue._actionTimeLeft)).toString()+"s",document.getElementById("hack-progress").innerHTML=ue._actionTimeStr,document.getElementById("hack-progress-bar").innerHTML=ue._actionProgressStr.replace(/ /g," "),n>=100&&(ue._actionInProgress=!1,H.a.finishAction())},closeMainMenuHeader:function(e){for(var t=0;t"+V.numeralWrapper.formatMoney(q)+" and your Hacknet Nodes generated "+V.numeralWrapper.formatMoney($)+"");var z=[t,n,i,o,m,h,x,R,N];w.a.firstFacInvRecvd?z.push(l):l.style.display="none",w.a.firstAugPurchased?z.push(p):p.style.display="none",""!==w.a.companyName?z.push(v):v.style.display="none",w.a.firstTimeTraveled?z.push(f):f.style.display="none",w.a.firstProgramAvailable?z.push(r):r.style.display="none",w.a.hasWseAccount?z.push(E):E.style.display="none",w.a.bladeburner instanceof u.a?z.push(k):k.style.display="none",w.a.corporation instanceof g.c?z.push(M):M.style.display="none",w.a.inGang()?z.push(A):A.style.display="none",ue.closeMainMenuHeader(z)}else{console.log("Initializing new game"),Object(c.initBitNodes)(),Object(c.initBitNodeMultipliers)(w.a),Object(W.c)(),Object(F.initSpecialServerIps)(),ue.setDisplayElements(),ue.start(),w.a.init(),Object(D.initForeignServers)(w.a.getHomeComputer()),Object(d.initCompanies)(),Object(y.initFactions)(),Object(s.d)(),Object(S.c)(),Object(U.i)(),Object(O.a)(),Object(P.g)(),document.getElementById("hacking-menu-header").classList.toggle("opened"),document.getElementById("character-menu-header").classList.toggle("opened"),document.getElementById("world-menu-header").classList.toggle("opened"),document.getElementById("help-menu-header").classList.toggle("opened"),l.style.display="none",p.style.display="none",v.style.display="none",E.style.display="none",f.style.display="none",r.style.display="none",k.style.display="none",M.style.display="none",A.style.display="none",N.style.display="none",ue.openMainMenuHeader([t,n,i,o,m,h,x,R]),Object(T.c)(),Object(ie.removeLoadingScreen)()}Object(J.a)(),Object(L.d)(),H.a.resetTerminalInput()},setDisplayElements:function(){if(ue.Display.terminalContent=document.getElementById("terminal-container"),z.routing.navigateTo(z.Page.Terminal),ue.Display.characterContent=document.getElementById("character-container"),ue.Display.characterContent.style.display="none",ue.Display.scriptEditorContent=document.getElementById("script-editor-container"),ue.Display.scriptEditorContent.style.display="none",ue.Display.activeScriptsContent=document.getElementById("active-scripts-container"),ue.Display.activeScriptsContent.style.display="none",ue.Display.hacknetNodesContent=document.getElementById("hacknet-nodes-container"),ue.Display.hacknetNodesContent.style.display="none",ue.Display.worldContent=document.getElementById("world-container"),ue.Display.worldContent.style.display="none",ue.Display.createProgramContent=document.getElementById("create-program-container"),ue.Display.createProgramContent.style.display="none",ue.Display.factionsContent=document.getElementById("factions-container"),ue.Display.factionsContent.style.display="none",ue.Display.factionContent=document.getElementById("faction-container"),ue.Display.factionContent.style.display="none",ue.Display.factionAugmentationsContent=document.getElementById("faction-augmentations-container"),ue.Display.factionAugmentationsContent.style.display="none",ue.Display.augmentationsContent=document.getElementById("augmentations-container"),ue.Display.augmentationsContent.style.display="none",ue.Display.tutorialContent=document.getElementById("tutorial-container"),ue.Display.tutorialContent.style.display="none",ue.Display.infiltrationContent=document.getElementById("infiltration-container"),ue.Display.infiltrationContent.style.display="none",ue.Display.stockMarketContent=document.getElementById("stock-market-container"),ue.Display.stockMarketContent.style.display="none",ue.Display.missionContent=document.getElementById("mission-container"),ue.Display.missionContent.style.display="none",ue.Display.characterInfo=document.getElementById("character-content"),ue.aevumLocationsList=document.getElementById("aevum-locations-list"),ue.chongqingLocationsList=document.getElementById("chongqing-locations-list"),ue.sector12LocationsList=document.getElementById("sector12-locations-list"),ue.newTokyoLocationsList=document.getElementById("newtokyo-locations-list"),ue.ishimaLocationsList=document.getElementById("ishima-locations-list"),ue.volhavenLocationsList=document.getElementById("volhaven-locations-list"),ue.Display.locationContent=document.getElementById("location-container"),ue.Display.locationContent.style.display="none",ue.Display.workInProgressContent=document.getElementById("work-in-progress-container"),ue.Display.workInProgressContent.style.display="none",ue.Display.redPillContent=document.getElementById("red-pill-container"),ue.Display.redPillContent.style.display="none",ue.Display.cinematicTextContent=document.getElementById("cinematic-text-container"),ue.Display.cinematicTextContent.style.display="none",Object(E.b)(),!Object(Q.initializeMainMenuLinks)()){const e="Failed to initialize Main Menu Links. Please try refreshing the page. If that doesn't work, report the issue to the developer";return Object(ae.exceptionAlert)(new Error(e)),void console.error(e)}},init:function(){if(document.getElementById("import-game-link").onclick=function(){I.b.importGame()},!Object(X.initializeMainMenuHeaders)(w.a,!1)){const e="Failed to initialize Main Menu Headers. Please try refreshing the page. If that doesn't work, report the issue to the developer";return Object(ae.exceptionAlert)(new Error(e)),void console.error(e)}(Q.MainMenuLinks.Terminal.addEventListener("click",function(){return ue.loadTerminalContent(),!1}),Q.MainMenuLinks.ScriptEditor.addEventListener("click",function(){return ue.loadScriptEditorContent(),!1}),Q.MainMenuLinks.ActiveScripts.addEventListener("click",function(){return ue.loadActiveScriptsContent(),!1}),Q.MainMenuLinks.CreateProgram.addEventListener("click",function(){return ue.loadCreateProgramContent(),!1}),Q.MainMenuLinks.Stats.addEventListener("click",function(){return ue.loadCharacterContent(),!1}),Q.MainMenuLinks.Factions.addEventListener("click",function(){return ue.loadFactionsContent(),!1}),Q.MainMenuLinks.Augmentations.addEventListener("click",function(){return ue.loadAugmentationsContent(),!1}),Q.MainMenuLinks.HacknetNodes.addEventListener("click",function(){return ue.loadHacknetNodesContent(),!1}),Q.MainMenuLinks.Sleeves.addEventListener("click",function(){return ue.loadSleevesContent(),Q.MainMenuLinks.Sleeves.classList.add("active"),!1}),Q.MainMenuLinks.City.addEventListener("click",function(){return ue.loadWorldContent(),!1}),Q.MainMenuLinks.Travel.addEventListener("click",function(){return ue.loadTravelContent(),Q.MainMenuLinks.Travel.classList.add("active"),!1}),Q.MainMenuLinks.Job.addEventListener("click",function(){return ue.loadJobContent(),Q.MainMenuLinks.Job.classList.add("active"),!1}),Q.MainMenuLinks.StockMarket.addEventListener("click",function(){return ue.loadStockMarketContent(),Q.MainMenuLinks.StockMarket.classList.add("active"),!1}),Q.MainMenuLinks.Bladeburner.addEventListener("click",function(){return ue.loadBladeburnerContent(),!1}),Q.MainMenuLinks.Corporation.addEventListener("click",function(){return ue.loadCorporationContent(),Q.MainMenuLinks.Corporation.classList.add("active"),!1}),Q.MainMenuLinks.Gang.addEventListener("click",function(){return ue.loadGangContent(),!1}),Q.MainMenuLinks.Tutorial.addEventListener("click",function(){return ue.loadTutorialContent(),!1}),Q.MainMenuLinks.DevMenu.addEventListener("click",function(){return!1}),ue.ActiveScriptsList=document.getElementById("active-scripts-list"),ue.Clickables.saveMainMenuButton=document.getElementById("save-game-link"),ue.Clickables.saveMainMenuButton.addEventListener("click",function(){return I.b.saveGame(pe),!1}),ue.Clickables.deleteMainMenuButton=document.getElementById("delete-game-link"),ue.Clickables.deleteMainMenuButton.addEventListener("click",function(){return I.b.deleteGame(pe),!1}),document.getElementById("export-game-link").addEventListener("click",function(){return I.b.exportGame(),!1}),document.getElementById("character-overview-save-button").addEventListener("click",function(){return I.b.saveGame(pe),!1}),document.getElementById("character-overview-options-button").addEventListener("click",function(){return Object(ee.b)(),!1}),Object(R.c)(),Object(H.b)(),w.a.isWorking)&&(document.getElementById("work-in-progress-cancel-button").addEventListener("click",function(){if(w.a.workType==_.CONSTANTS.WorkTypeFaction){y.Factions[w.a.currentWorkFactionName];w.a.finishFactionWork(!0)}else w.a.workType==_.CONSTANTS.WorkTypeCreateProgram?w.a.finishCreateProgramWork(!0):w.a.workType==_.CONSTANTS.WorkTypeStudyClass?w.a.finishClass():w.a.workType==_.CONSTANTS.WorkTypeCrime?w.a.finishCrime(!0):w.a.workType==_.CONSTANTS.WorkTypeCompanyPartTime?w.a.finishWorkPartTime():w.a.finishWork(!0)}),ue.loadWorkInProgressContent());document.getElementById("character-overview-container").style.display="block",document.getElementById("terminal-menu-link").removeAttribute("class"),document.getElementById("stats-menu-link").removeAttribute("class"),document.getElementById("create-script-menu-link").removeAttribute("class"),document.getElementById("active-scripts-menu-link").removeAttribute("class"),document.getElementById("hacknet-nodes-menu-link").removeAttribute("class"),document.getElementById("city-menu-link").removeAttribute("class"),document.getElementById("tutorial-menu-link").removeAttribute("class"),document.getElementById("copy-save-to-clipboard-link").addEventListener("click",function(){const e=I.b.getSaveString();if(navigator.clipboard)navigator.clipboard.writeText(e).then(function(){Object($.createStatusText)("Copied save to clipboard")},function(e){console.error("Unable to copy save data to clipboard using Async API"),Object($.createStatusText)("Failed to copy save")});else{const t=document.createElement("textarea");t.value=e,t.setAttribute("readonly",""),t.style.position="absolute",t.left="-9999px",document.body.appendChild(t),t.focus(),t.select();try{document.execCommand("copy")?Object($.createStatusText)("Copied save to clipboard"):Object($.createStatusText)("Failed to copy save")}catch(e){console.error("Unable to copy save data to clipboard using document.execCommand('copy')"),Object($.createStatusText)("Failed to copy save")}document.body.removeChild(t)}}),document.getElementById("debug-delete-scripts-link").addEventListener("click",function(){return console.log("Deleting running scripts on home computer"),w.a.getHomeComputer().runningScripts=[],Object(Z.dialogBoxCreate)("Forcefully deleted all running scripts on home computer. Please save and refresh page"),Object(ee.a)(),!1}),document.getElementById("debug-soft-reset").addEventListener("click",function(){return Object(Z.dialogBoxCreate)("Soft Reset!"),Object(x.a)(),Object(ee.a)(),!1})},start:function(){ue.idleTimer(),Object(A.f)()}};var pe,me;window.onload=function(){if(!window.indexedDB)return ue.load(null);(me=window.indexedDB.open("bitburnerSave",1)).onerror=function(e){return console.log("Error opening indexedDB: "),console.log(e),ue.load(null)},me.onsuccess=function(e){console.log("Opening bitburnerSave database successful!");var t=(pe=e.target.result).transaction(["savestring"]).objectStore("savestring").get("save");t.onerror=function(e){return console.log("Error in Database request to get savestring: "+e),ue.load(null)},t.onsuccess=function(e){ue.load(t.result)}},me.onupgradeneeded=function(e){e.target.result.createObjectStore("savestring")}}}.call(this,n(79))},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e){e.Terminal="Terminal",e.CharacterInfo="CharacterInfo",e.ScriptEditor="ScriptEditor",e.ActiveScripts="ActiveScripts",e.HacknetNodes="HacknetNodes",e.World="World",e.CreateProgram="CreateProgram",e.Factions="Factions",e.Faction="Faction",e.Augmentations="Augmentations",e.Tutorial="Tutorial",e.DevMenu="Dev Menu",e.Location="Location",e.workInProgress="WorkInProgress",e.RedPill="RedPill",e.CinematicText="CinematicText",e.Infiltration="Infiltration",e.StockMarket="StockMarket",e.Gang="Gang",e.Mission="Mission",e.Corporation="Corporation",e.Bladeburner="Bladeburner",e.Sleeves="Sleeves",e.Resleeves="Re-sleeving"}(t.Page||(t.Page={}));t.routing=new class{constructor(){this.currentPage=null}isOn(e){return this.currentPage===e}navigateTo(e){this.currentPage=e}}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Augmentations={}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const a=n(69),i=n(150),r=n(17);function o(e){const n=e.name;t.Factions[n]=e}function s(e){return t.Factions.hasOwnProperty(e)}function l(e){if(!(e instanceof a.Faction))throw new Error("Invalid argument 'newFactionObject' passed into resetFaction()");const n=e.name;s(n)&&(e.favor=t.Factions[n].favor,delete t.Factions[n]),o(e)}t.Factions={},t.loadFactions=function(e){t.Factions=JSON.parse(e,r.Reviver)},t.AddToFactions=o,t.factionExists=s,t.initFactions=function(e=1){for(const e in i.FactionInfos)l(new a.Faction(e))},t.resetFaction=l},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getRandomInt=function(e,t){const n=Math.min(e,t),a=Math.max(e,t);return Math.floor(Math.random()*(a-n+1))+n}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const a=n(1),i=n(20),r=n(14),o=n(17);class s{constructor(e={info:"",moneyCost:0,name:"",repCost:0}){this.baseCost=0,this.baseRepRequirement=0,this.info="",this.level=0,this.name="",this.owned=!1,this.prereqs=[],this.mults={},this.startingCost=0,this.name=e.name,this.info=e.info,this.prereqs=e.prereqs?e.prereqs:[],this.baseRepRequirement=e.repCost*a.CONSTANTS.AugmentationRepMultiplier*i.BitNodeMultipliers.AugmentationRepCost,this.baseCost=e.moneyCost*a.CONSTANTS.AugmentationCostMultiplier*i.BitNodeMultipliers.AugmentationMoneyCost,this.startingCost=this.baseCost,this.level=0,e.hacking_mult&&(this.mults.hacking_mult=e.hacking_mult),e.strength_mult&&(this.mults.strength_mult=e.strength_mult),e.defense_mult&&(this.mults.defense_mult=e.defense_mult),e.dexterity_mult&&(this.mults.dexterity_mult=e.dexterity_mult),e.agility_mult&&(this.mults.agility_mult=e.agility_mult),e.charisma_mult&&(this.mults.charisma_mult=e.charisma_mult),e.hacking_exp_mult&&(this.mults.hacking_exp_mult=e.hacking_exp_mult),e.strength_exp_mult&&(this.mults.strength_exp_mult=e.strength_exp_mult),e.defense_exp_mult&&(this.mults.defense_exp_mult=e.defense_exp_mult),e.dexterity_exp_mult&&(this.mults.dexterity_exp_mult=e.dexterity_exp_mult),e.agility_exp_mult&&(this.mults.agility_exp_mult=e.agility_exp_mult),e.charisma_exp_mult&&(this.mults.charisma_exp_mult=e.charisma_exp_mult),e.hacking_chance_mult&&(this.mults.hacking_chance_mult=e.hacking_chance_mult),e.hacking_speed_mult&&(this.mults.hacking_speed_mult=e.hacking_speed_mult),e.hacking_money_mult&&(this.mults.hacking_money_mult=e.hacking_money_mult),e.hacking_grow_mult&&(this.mults.hacking_grow_mult=e.hacking_grow_mult),e.company_rep_mult&&(this.mults.company_rep_mult=e.company_rep_mult),e.faction_rep_mult&&(this.mults.faction_rep_mult=e.faction_rep_mult),e.crime_money_mult&&(this.mults.crime_money_mult=e.crime_money_mult),e.crime_success_mult&&(this.mults.crime_success_mult=e.crime_success_mult),e.work_money_mult&&(this.mults.work_money_mult=e.work_money_mult),e.hacknet_node_money_mult&&(this.mults.hacknet_node_money_mult=e.hacknet_node_money_mult),e.hacknet_node_purchase_cost_mult&&(this.mults.hacknet_node_purchase_cost_mult=e.hacknet_node_purchase_cost_mult),e.hacknet_node_ram_cost_mult&&(this.mults.hacknet_node_ram_cost_mult=e.hacknet_node_ram_cost_mult),e.hacknet_node_core_cost_mult&&(this.mults.hacknet_node_core_cost_mult=e.hacknet_node_core_cost_mult),e.hacknet_node_level_cost_mult&&(this.mults.hacknet_node_level_cost_mult=e.hacknet_node_level_cost_mult),e.bladeburner_max_stamina_mult&&(this.mults.bladeburner_max_stamina_mult=e.bladeburner_max_stamina_mult),e.bladeburner_stamina_gain_mult&&(this.mults.bladeburner_stamina_gain_mult=e.bladeburner_stamina_gain_mult),e.bladeburner_analysis_mult&&(this.mults.bladeburner_analysis_mult=e.bladeburner_analysis_mult),e.bladeburner_success_chance_mult&&(this.mults.bladeburner_success_chance_mult=e.bladeburner_success_chance_mult)}static fromJSON(e){return o.Generic_fromJSON(s,e.data)}addToFactions(e){for(let t=0;t{!function(e){null!=t.Companies[e.name]&&console.warn(`Duplicate Company Position being defined: ${e.name}`),t.Companies[e.name]=new i.Company(e)}(e)});for(const n in t.Companies){const a=t.Companies[n];e[n]instanceof i.Company?(a.favor=e[n].favor,isNaN(a.favor)&&(a.favor=0)):a.favor=0}},t.loadCompanies=function(e){t.Companies=JSON.parse(e,r.Reviver)},t.companyExists=function(e){return t.Companies.hasOwnProperty(e)}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const a=n(47),i={AutosaveInterval:60,CodeInstructionRunTime:50,DisableHotkeys:!1,Locale:"en",MaxLogCapacity:50,MaxPortCapacity:50,SuppressBuyAugmentationConfirmation:!1,SuppressFactionInvites:!1,SuppressHospitalizationPopup:!1,SuppressMessages:!1,SuppressTravelConfirmation:!1};t.Settings={AutosaveInterval:i.AutosaveInterval,CodeInstructionRunTime:25,DisableHotkeys:i.DisableHotkeys,Editor:a.EditorSetting.Ace,EditorKeybinding:a.AceKeybindingSetting.Ace,EditorTheme:"Monokai",Locale:"en",MaxLogCapacity:i.MaxLogCapacity,MaxPortCapacity:i.MaxPortCapacity,OwnedAugmentationsOrder:a.OwnedAugmentationsOrderSetting.AcquirementTime,PurchaseAugmentationsOrder:a.PurchaseAugmentationsOrderSetting.Default,SuppressBuyAugmentationConfirmation:i.SuppressBuyAugmentationConfirmation,SuppressFactionInvites:i.SuppressFactionInvites,SuppressHospitalizationPopup:i.SuppressHospitalizationPopup,SuppressMessages:i.SuppressMessages,SuppressTravelConfirmation:i.SuppressTravelConfirmation,init(){Object.assign(t.Settings,i)},load(e){Object.assign(t.Settings,JSON.parse(e))}}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.BitNodeMultipliers={HackingLevelMultiplier:1,StrengthLevelMultiplier:1,DefenseLevelMultiplier:1,DexterityLevelMultiplier:1,AgilityLevelMultiplier:1,CharismaLevelMultiplier:1,ServerGrowthRate:1,ServerMaxMoney:1,ServerStartingMoney:1,ServerStartingSecurity:1,ServerWeakenRate:1,HomeComputerRamCost:1,PurchasedServerCost:1,PurchasedServerLimit:1,PurchasedServerMaxRam:1,CompanyWorkMoney:1,CrimeMoney:1,HacknetNodeMoney:1,ManualHackMoney:1,ScriptHackMoney:1,CodingContractMoney:1,ClassGymExpGain:1,CompanyWorkExpGain:1,CrimeExpGain:1,FactionWorkExpGain:1,HackExpGain:1,FactionPassiveRepGain:1,FactionWorkRepGain:1,RepToDonateToFaction:1,AugmentationMoneyCost:1,AugmentationRepCost:1,InfiltrationMoney:1,InfiltrationRep:1,FourSigmaMarketDataCost:1,FourSigmaMarketDataApiCost:1,CorporationValuation:1,BladeburnerRank:1,BladeburnerSkillCost:1,DaedalusAugsRequirement:1}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const a=n(23),i=n(20),r=n(1),o=n(30),s=n(123);function l(e,t,n){let a=1+(r.CONSTANTS.ServerBaseGrowthRate-1)/e.hackDifficulty;a>r.CONSTANTS.ServerMaxGrowthRate&&(a=r.CONSTANTS.ServerMaxGrowthRate);const o=e.serverGrowth/100;return Math.log(t)/(Math.log(a)*n.hacking_grow_mult*o*i.BitNodeMultipliers.ServerGrowthRate)}function c(e){for(var t in a.AllServers)if(a.AllServers.hasOwnProperty(t)&&a.AllServers[t].hostname==e)return a.AllServers[t];return null}t.numCycleForGrowth=l,t.processSingleServerGrowth=function(e,t,n){const a=Math.max(Math.floor(t/450),0);var o=1+(r.CONSTANTS.ServerBaseGrowthRate-1)/e.hackDifficulty;o>r.CONSTANTS.ServerMaxGrowthRate&&(o=r.CONSTANTS.ServerMaxGrowthRate);const s=a*(e.serverGrowth/100)*i.BitNodeMultipliers.ServerGrowthRate;let c=Math.pow(o,s*n.hacking_grow_mult);c<1&&(console.log("WARN: serverGrowth calculated to be less than 1"),c=1);const u=e.moneyAvailable;if(e.moneyAvailable*=c,e.moneyMax&&isNaN(e.moneyAvailable)&&(e.moneyAvailable=e.moneyMax),e.moneyMax&&e.moneyAvailable>e.moneyMax&&(e.moneyAvailable=e.moneyMax),u!==e.moneyAvailable){let t=l(e,e.moneyAvailable/u,n);t=Math.max(0,t),e.fortify(2*r.CONSTANTS.ServerFortifyAmount*Math.ceil(t))}return e.moneyAvailable/u},t.prestigeHomeComputer=function(e){const t=e.programs.includes(o.Programs.BitFlume.name);e.programs.length=0,e.runningScripts=[],e.serversOnNetwork=[],e.isConnectedTo=!0,e.ramUsed=0,e.programs.push(o.Programs.NukeProgram.name),t&&e.programs.push(o.Programs.BitFlume.name),e.scripts.forEach(function(e){e.updateRamUsage()}),e.messages.length=0,e.messages.push("hackers-starting-handbook.lit")},t.GetServerByHostname=c,t.getServer=function(e){return s.isValidIPAddress(e)?void 0!==a.AllServers[e]?a.AllServers[e]:null:c(e)},t.getServerOnNetwork=function(e,t){if(!(t>e.serversOnNetwork.length))return a.AllServers[e.serversOnNetwork[t]];console.error("Tried to get server on network that was out of range")}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const a=n(68);t.clearEventListeners=function(e){try{let t;const n=(t="string"==typeof e?a.getElementById(e):e).cloneNode(!0);return null!==t.parentNode&&t.parentNode.replaceChild(n,t),n}catch(e){return console.error(e),null}}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const a=n(74),i=n(40),r=n(271),o=n(90),s=n(15),l=n(17);function c(e){var n=e.ip;if(o.ipExists(n))throw console.log("IP of server that's being added: "+n),console.log("Hostname of the server thats being added: "+e.hostname),console.log("The server that already has this IP is: "+t.AllServers[n].hostname),new Error("Error: Trying to add a server with an existing IP");t.AllServers[n]=e}t.AllServers={},t.AddToAllServers=c,t.initForeignServers=function(e){const t=[];for(let e=0;e<15;e++)t.push([]);const n=["hackDifficulty","moneyAvailable","requiredHackingSkill","serverGrowth"],l=e=>{switch(typeof e){case"number":return e;case"object":return s.getRandomInt(e.min,e.max);default:throw Error(`Do not know how to convert the type '${typeof e}' to a number`)}};for(const e of r.serverMetadata){const r={hostname:e.hostname,ip:o.createRandomIp(),numOpenPortsRequired:e.numOpenPortsRequired,organizationName:e.organizationName};void 0!==e.maxRamExponent&&(r.maxRam=Math.pow(2,l(e.maxRamExponent)));for(const t of n)void 0!==e[t]&&(r[t]=l(e[t]));const s=new a.Server(r);for(const t of e.literature||[])s.messages.push(t);void 0!==e.specialName&&i.SpecialServerIps.addIp(e.specialName,s.ip),c(s),void 0!==e.networkLayer&&t[l(e.networkLayer)-1].push(s)}const u=(e,t)=>{e.serversOnNetwork.push(t.ip),t.serversOnNetwork.push(e.ip)},p=e=>e[Math.floor(Math.random()*e.length)],m=(e,t)=>{for(const n of e)u(n,t())};m(t[0],()=>e);for(let e=1;ep(t[e-1]))},t.prestigeAllServers=function(){for(var e in t.AllServers)delete t.AllServers[e];t.AllServers={}},t.loadAllServers=function(e){t.AllServers=JSON.parse(e,l.Reviver)}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.EmployeePositions={Operations:"Operations",Engineer:"Engineer",Business:"Business",Management:"Management",RandD:"Research & Development",Training:"Training",Unassigned:"Unassigned"}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const a=n(22);t.yesNoBoxOpen=!1;const i=document.getElementById("yes-no-box-container"),r=document.getElementById("yes-no-box-text");function o(e){if(27===e.keyCode)s();else if(13===e.keyCode){const e=document.getElementById("yes-no-box-yes");e?e.click():console.error("Could not find YesNoBox Yes button DOM element")}}function s(){return i?i.style.display="none":console.error("Container not found for YesNoBox"),t.yesNoBoxOpen=!1,document.removeEventListener("keydown",o),!1}t.yesNoBoxHotkeyHandler=o,t.yesNoBoxClose=s,t.yesNoBoxGetYesButton=function(){return a.clearEventListeners("yes-no-box-yes")},t.yesNoBoxGetNoButton=function(){return a.clearEventListeners("yes-no-box-no")},t.yesNoBoxCreate=function(e){return!t.yesNoBoxOpen&&(t.yesNoBoxOpen=!0,r?r.innerHTML=e:console.error("Text element not found for YesNoBox"),i?i.style.display="flex":console.error("Container not found for YesNoBox"),document.addEventListener("keydown",o),!0)};const l=document.getElementById("yes-no-text-input-box-container"),c=document.getElementById("yes-no-text-input-box-input"),u=document.getElementById("yes-no-text-input-box-text");function p(e){if(27===e.keyCode)m();else if(13===e.keyCode){const e=document.getElementById("yes-no-text-input-box-yes");e?e.click():console.error("Could not find YesNoTxtInputBox Yes button DOM element")}}function m(){return null==l?(console.error("Container not found for YesNoTextInputBox"),!1):(l.style.display="none",t.yesNoBoxOpen=!1,c.value="",document.removeEventListener("keydown",p),!1)}t.yesNoTxtInpBoxHotkeyHandler=p,t.yesNoTxtInpBoxClose=m,t.yesNoTxtInpBoxGetYesButton=function(){return a.clearEventListeners("yes-no-text-input-box-yes")},t.yesNoTxtInpBoxGetNoButton=function(){return a.clearEventListeners("yes-no-text-input-box-no")},t.yesNoTxtInpBoxGetInput=function(){if(null==c)return console.error("Could not find YesNoTextInputBox input element"),"";let e=c.value;return e=e.replace(/\s+/g,"")},t.yesNoTxtInpBoxCreate=function(e){t.yesNoBoxOpen=!0,u&&(u.innerHTML=e),l?l.style.display="flex":console.error("Container not found for YesNoTextInputBox"),document.addEventListener("keydown",p),c.focus()}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const a=n(68),i=n(75);t.removeElementById=function(e){try{const t=a.getElementById(e);i.removeElement(t)}catch(e){}}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const a=n(293),i=n(3);t.Industries={Energy:"Energy",Utilities:"Water Utilities",Agriculture:"Agriculture",Fishing:"Fishing",Mining:"Mining",Food:"Food",Tobacco:"Tobacco",Chemical:"Chemical",Pharmaceutical:"Pharmaceutical",Computer:"Computer Hardware",Robotics:"Robotics",Software:"Software",Healthcare:"Healthcare",RealEstate:"RealEstate"},t.IndustryStartingCosts={Energy:225e9,Utilities:15e10,Agriculture:4e10,Fishing:8e10,Mining:3e11,Food:1e10,Tobacco:2e10,Chemical:7e10,Pharmaceutical:2e11,Computer:5e11,Robotics:1e12,Software:25e9,Healthcare:75e10,RealEstate:6e11},t.IndustryDescriptions={Energy:"Engage in the production and distribution of energy.

    Starting cost: "+i.numeralWrapper.format(t.IndustryStartingCosts.Energy,"$0.000a")+"
    Recommended starting Industry: NO",Utilities:"Distributes water and provides wastewater services.

    Starting cost: "+i.numeralWrapper.format(t.IndustryStartingCosts.Utilities,"$0.000a")+"
    Recommended starting Industry: NO",Agriculture:"Cultive crops and breed livestock to produce food.

    Starting cost: "+i.numeralWrapper.format(t.IndustryStartingCosts.Agriculture,"$0.000a")+"
    Recommended starting Industry: YES",Fishing:"Produce food through the breeding and processing of fish and fish products

    Starting cost: "+i.numeralWrapper.format(t.IndustryStartingCosts.Fishing,"$0.000a")+"
    Recommended starting Industry: NO",Mining:"Extract and process metals from the earth.

    Starting cost: "+i.numeralWrapper.format(t.IndustryStartingCosts.Mining,"$0.000a")+"
    Recommended starting Industry: NO",Food:"Create your own restaurants all around the world.

    Starting cost: "+i.numeralWrapper.format(t.IndustryStartingCosts.Food,"$0.000a")+"
    Recommended starting Industry: YES",Tobacco:"Create and distribute tobacco and tobacco-related products.

    Starting cost: "+i.numeralWrapper.format(t.IndustryStartingCosts.Tobacco,"$0.000a")+"
    Recommended starting Industry: YES",Chemical:"Product industrial chemicals

    Starting cost: "+i.numeralWrapper.format(t.IndustryStartingCosts.Chemical,"$0.000a")+"
    Recommended starting Industry: NO",Pharmaceutical:"Discover, develop, and create new pharmaceutical drugs.

    Starting cost: "+i.numeralWrapper.format(t.IndustryStartingCosts.Pharmaceutical,"$0.000a")+"
    Recommended starting Industry: NO",Computer:"Develop and manufacture new computer hardware and networking infrastructures.

    Starting cost: "+i.numeralWrapper.format(t.IndustryStartingCosts.Computer,"$0.000a")+"
    Recommended starting Industry: NO",Robotics:"Develop and create robots.

    Starting cost: "+i.numeralWrapper.format(t.IndustryStartingCosts.Robotics,"$0.000a")+"
    Recommended starting Industry: NO",Software:"Develop computer software and create AI Cores.

    Starting cost: "+i.numeralWrapper.format(t.IndustryStartingCosts.Software,"$0.000a")+"
    Recommended starting Industry: YES",Healthcare:"Create and manage hospitals.

    Starting cost: "+i.numeralWrapper.format(t.IndustryStartingCosts.Healthcare,"$0.000a")+"
    Recommended starting Industry: NO",RealEstate:"Develop and manage real estate properties.

    Starting cost: "+i.numeralWrapper.format(t.IndustryStartingCosts.RealEstate,"$0.000a")+"
    Recommended starting Industry: NO"},t.IndustryResearchTrees={Energy:a.getBaseResearchTreeCopy(),Utilities:a.getBaseResearchTreeCopy(),Agriculture:a.getBaseResearchTreeCopy(),Fishing:a.getBaseResearchTreeCopy(),Mining:a.getBaseResearchTreeCopy(),Food:a.getProductIndustryResearchTreeCopy(),Tobacco:a.getProductIndustryResearchTreeCopy(),Chemical:a.getBaseResearchTreeCopy(),Pharmaceutical:a.getProductIndustryResearchTreeCopy(),Computer:a.getProductIndustryResearchTreeCopy(),Robotics:a.getProductIndustryResearchTreeCopy(),Software:a.getProductIndustryResearchTreeCopy(),Healthcare:a.getProductIndustryResearchTreeCopy(),RealEstate:a.getProductIndustryResearchTreeCopy()},t.resetIndustryResearchTrees=function(){t.IndustryResearchTrees.Energy=a.getBaseResearchTreeCopy(),t.IndustryResearchTrees.Utilities=a.getBaseResearchTreeCopy(),t.IndustryResearchTrees.Agriculture=a.getBaseResearchTreeCopy(),t.IndustryResearchTrees.Fishing=a.getBaseResearchTreeCopy(),t.IndustryResearchTrees.Mining=a.getBaseResearchTreeCopy(),t.IndustryResearchTrees.Food=a.getBaseResearchTreeCopy(),t.IndustryResearchTrees.Tobacco=a.getBaseResearchTreeCopy(),t.IndustryResearchTrees.Chemical=a.getBaseResearchTreeCopy(),t.IndustryResearchTrees.Pharmaceutical=a.getBaseResearchTreeCopy(),t.IndustryResearchTrees.Computer=a.getBaseResearchTreeCopy(),t.IndustryResearchTrees.Robotics=a.getBaseResearchTreeCopy(),t.IndustryResearchTrees.Software=a.getBaseResearchTreeCopy(),t.IndustryResearchTrees.Healthcare=a.getBaseResearchTreeCopy(),t.IndustryResearchTrees.RealEstate=a.getBaseResearchTreeCopy()}},function(module,__webpack_exports__,__webpack_require__){"use strict";(function($){__webpack_require__.d(__webpack_exports__,"f",function(){return IssueNewSharesCooldown}),__webpack_require__.d(__webpack_exports__,"k",function(){return SellSharesCooldown}),__webpack_require__.d(__webpack_exports__,"m",function(){return WarehouseInitialCost}),__webpack_require__.d(__webpack_exports__,"n",function(){return WarehouseInitialSize}),__webpack_require__.d(__webpack_exports__,"o",function(){return WarehouseUpgradeBaseCost}),__webpack_require__.d(__webpack_exports__,"g",function(){return OfficeInitialCost}),__webpack_require__.d(__webpack_exports__,"h",function(){return OfficeInitialSize}),__webpack_require__.d(__webpack_exports__,"a",function(){return BribeThreshold}),__webpack_require__.d(__webpack_exports__,"b",function(){return BribeToRepRatio}),__webpack_require__.d(__webpack_exports__,"j",function(){return ProductProductionCostRatio}),__webpack_require__.d(__webpack_exports__,"d",function(){return DividendMaxPercentage}),__webpack_require__.d(__webpack_exports__,"c",function(){return Corporation}),__webpack_require__.d(__webpack_exports__,"e",function(){return Industry}),__webpack_require__.d(__webpack_exports__,"i",function(){return OfficeSpace});var _CorporationState__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(160),_CorporationState__WEBPACK_IMPORTED_MODULE_0___default=__webpack_require__.n(_CorporationState__WEBPACK_IMPORTED_MODULE_0__),_data_CorporationUnlockUpgrades__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(138),_data_CorporationUnlockUpgrades__WEBPACK_IMPORTED_MODULE_1___default=__webpack_require__.n(_data_CorporationUnlockUpgrades__WEBPACK_IMPORTED_MODULE_1__),_data_CorporationUpgrades__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(137),_data_CorporationUpgrades__WEBPACK_IMPORTED_MODULE_2___default=__webpack_require__.n(_data_CorporationUpgrades__WEBPACK_IMPORTED_MODULE_2__),_EmployeePositions__WEBPACK_IMPORTED_MODULE_3__=__webpack_require__(24),_EmployeePositions__WEBPACK_IMPORTED_MODULE_3___default=__webpack_require__.n(_EmployeePositions__WEBPACK_IMPORTED_MODULE_3__),_IndustryData__WEBPACK_IMPORTED_MODULE_4__=__webpack_require__(27),_IndustryData__WEBPACK_IMPORTED_MODULE_4___default=__webpack_require__.n(_IndustryData__WEBPACK_IMPORTED_MODULE_4__),_IndustryUpgrades__WEBPACK_IMPORTED_MODULE_5__=__webpack_require__(127),_IndustryUpgrades__WEBPACK_IMPORTED_MODULE_5___default=__webpack_require__.n(_IndustryUpgrades__WEBPACK_IMPORTED_MODULE_5__),_Material__WEBPACK_IMPORTED_MODULE_6__=__webpack_require__(124),_Material__WEBPACK_IMPORTED_MODULE_6___default=__webpack_require__.n(_Material__WEBPACK_IMPORTED_MODULE_6__),_MaterialSizes__WEBPACK_IMPORTED_MODULE_7__=__webpack_require__(91),_MaterialSizes__WEBPACK_IMPORTED_MODULE_7___default=__webpack_require__.n(_MaterialSizes__WEBPACK_IMPORTED_MODULE_7__),_Product__WEBPACK_IMPORTED_MODULE_8__=__webpack_require__(109),_Product__WEBPACK_IMPORTED_MODULE_8___default=__webpack_require__.n(_Product__WEBPACK_IMPORTED_MODULE_8__),_ResearchMap__WEBPACK_IMPORTED_MODULE_9__=__webpack_require__(133),_ResearchMap__WEBPACK_IMPORTED_MODULE_9___default=__webpack_require__.n(_ResearchMap__WEBPACK_IMPORTED_MODULE_9__),_Warehouse__WEBPACK_IMPORTED_MODULE_10__=__webpack_require__(82),_Warehouse__WEBPACK_IMPORTED_MODULE_10___default=__webpack_require__.n(_Warehouse__WEBPACK_IMPORTED_MODULE_10__);__webpack_require__.d(__webpack_exports__,"l",function(){return _Warehouse__WEBPACK_IMPORTED_MODULE_10__.Warehouse});var _BitNode_BitNodeMultipliers__WEBPACK_IMPORTED_MODULE_11__=__webpack_require__(20),_BitNode_BitNodeMultipliers__WEBPACK_IMPORTED_MODULE_11___default=__webpack_require__.n(_BitNode_BitNodeMultipliers__WEBPACK_IMPORTED_MODULE_11__),_Constants__WEBPACK_IMPORTED_MODULE_12__=__webpack_require__(1),_Constants__WEBPACK_IMPORTED_MODULE_12___default=__webpack_require__.n(_Constants__WEBPACK_IMPORTED_MODULE_12__),_Faction_Factions__WEBPACK_IMPORTED_MODULE_13__=__webpack_require__(14),_Faction_Factions__WEBPACK_IMPORTED_MODULE_13___default=__webpack_require__.n(_Faction_Factions__WEBPACK_IMPORTED_MODULE_13__),_Literature__WEBPACK_IMPORTED_MODULE_14__=__webpack_require__(108),_Locations__WEBPACK_IMPORTED_MODULE_15__=__webpack_require__(6),_Locations__WEBPACK_IMPORTED_MODULE_15___default=__webpack_require__.n(_Locations__WEBPACK_IMPORTED_MODULE_15__),_Locations_Cities__WEBPACK_IMPORTED_MODULE_16__=__webpack_require__(89),_Locations_Cities__WEBPACK_IMPORTED_MODULE_16___default=__webpack_require__.n(_Locations_Cities__WEBPACK_IMPORTED_MODULE_16__),_Player__WEBPACK_IMPORTED_MODULE_17__=__webpack_require__(0),_ui_numeralFormat__WEBPACK_IMPORTED_MODULE_18__=__webpack_require__(3),_ui_numeralFormat__WEBPACK_IMPORTED_MODULE_18___default=__webpack_require__.n(_ui_numeralFormat__WEBPACK_IMPORTED_MODULE_18__),_ui_navigationTracking__WEBPACK_IMPORTED_MODULE_19__=__webpack_require__(12),_ui_navigationTracking__WEBPACK_IMPORTED_MODULE_19___default=__webpack_require__.n(_ui_navigationTracking__WEBPACK_IMPORTED_MODULE_19__),_utils_calculateEffectWithFactors__WEBPACK_IMPORTED_MODULE_20__=__webpack_require__(194),_utils_calculateEffectWithFactors__WEBPACK_IMPORTED_MODULE_20___default=__webpack_require__.n(_utils_calculateEffectWithFactors__WEBPACK_IMPORTED_MODULE_20__),_utils_DialogBox__WEBPACK_IMPORTED_MODULE_21__=__webpack_require__(9),_utils_uiHelpers_clearSelector__WEBPACK_IMPORTED_MODULE_22__=__webpack_require__(154),_utils_uiHelpers_clearSelector__WEBPACK_IMPORTED_MODULE_22___default=__webpack_require__.n(_utils_uiHelpers_clearSelector__WEBPACK_IMPORTED_MODULE_22__),_utils_JSONReviver__WEBPACK_IMPORTED_MODULE_23__=__webpack_require__(17),_utils_uiHelpers_appendLineBreaks__WEBPACK_IMPORTED_MODULE_24__=__webpack_require__(76),_utils_uiHelpers_appendLineBreaks__WEBPACK_IMPORTED_MODULE_24___default=__webpack_require__.n(_utils_uiHelpers_appendLineBreaks__WEBPACK_IMPORTED_MODULE_24__),_utils_uiHelpers_createElement__WEBPACK_IMPORTED_MODULE_25__=__webpack_require__(4),_utils_uiHelpers_createElement__WEBPACK_IMPORTED_MODULE_25___default=__webpack_require__.n(_utils_uiHelpers_createElement__WEBPACK_IMPORTED_MODULE_25__),_utils_uiHelpers_createPopup__WEBPACK_IMPORTED_MODULE_26__=__webpack_require__(37),_utils_uiHelpers_createPopup__WEBPACK_IMPORTED_MODULE_26___default=__webpack_require__.n(_utils_uiHelpers_createPopup__WEBPACK_IMPORTED_MODULE_26__),_utils_uiHelpers_createPopupCloseButton__WEBPACK_IMPORTED_MODULE_27__=__webpack_require__(55),_utils_uiHelpers_createPopupCloseButton__WEBPACK_IMPORTED_MODULE_27___default=__webpack_require__.n(_utils_uiHelpers_createPopupCloseButton__WEBPACK_IMPORTED_MODULE_27__),_utils_StringHelperFunctions__WEBPACK_IMPORTED_MODULE_28__=__webpack_require__(7),_utils_StringHelperFunctions__WEBPACK_IMPORTED_MODULE_28___default=__webpack_require__.n(_utils_StringHelperFunctions__WEBPACK_IMPORTED_MODULE_28__),_utils_helpers_getRandomInt__WEBPACK_IMPORTED_MODULE_29__=__webpack_require__(15),_utils_helpers_getRandomInt__WEBPACK_IMPORTED_MODULE_29___default=__webpack_require__.n(_utils_helpers_getRandomInt__WEBPACK_IMPORTED_MODULE_29__),_utils_helpers_isString__WEBPACK_IMPORTED_MODULE_30__=__webpack_require__(44),_utils_helpers_isString__WEBPACK_IMPORTED_MODULE_30___default=__webpack_require__.n(_utils_helpers_isString__WEBPACK_IMPORTED_MODULE_30__),_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_31__=__webpack_require__(31),_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_31___default=__webpack_require__.n(_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_31__),_utils_uiHelpers_removeElement__WEBPACK_IMPORTED_MODULE_32__=__webpack_require__(75),_utils_uiHelpers_removeElement__WEBPACK_IMPORTED_MODULE_32___default=__webpack_require__.n(_utils_uiHelpers_removeElement__WEBPACK_IMPORTED_MODULE_32__),_utils_uiHelpers_removeElementById__WEBPACK_IMPORTED_MODULE_33__=__webpack_require__(26),_utils_uiHelpers_removeElementById__WEBPACK_IMPORTED_MODULE_33___default=__webpack_require__.n(_utils_uiHelpers_removeElementById__WEBPACK_IMPORTED_MODULE_33__),_utils_YesNoBox__WEBPACK_IMPORTED_MODULE_34__=__webpack_require__(25),_utils_YesNoBox__WEBPACK_IMPORTED_MODULE_34___default=__webpack_require__.n(_utils_YesNoBox__WEBPACK_IMPORTED_MODULE_34__),react__WEBPACK_IMPORTED_MODULE_35__=__webpack_require__(2),react__WEBPACK_IMPORTED_MODULE_35___default=__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_35__),react_dom__WEBPACK_IMPORTED_MODULE_36__=__webpack_require__(113),react_dom__WEBPACK_IMPORTED_MODULE_36___default=__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_36__),_ui_CorporationUIEventHandler__WEBPACK_IMPORTED_MODULE_37__=__webpack_require__(193),_ui_Root__WEBPACK_IMPORTED_MODULE_38__=__webpack_require__(192),_ui_Routing__WEBPACK_IMPORTED_MODULE_39__=__webpack_require__(114),_ui_Routing__WEBPACK_IMPORTED_MODULE_39___default=__webpack_require__.n(_ui_Routing__WEBPACK_IMPORTED_MODULE_39__),decimal_js__WEBPACK_IMPORTED_MODULE_40__=__webpack_require__(46);const INITIALSHARES=1e9,SHARESPERPRICEUPDATE=1e6,IssueNewSharesCooldown=216e3,SellSharesCooldown=18e3,CyclesPerMarketCycle=50,CyclesPerIndustryStateCycle=CyclesPerMarketCycle/_CorporationState__WEBPACK_IMPORTED_MODULE_0__.AllCorporationStates.length,SecsPerMarketCycle=CyclesPerMarketCycle/5,Cities=["Aevum","Chongqing","Sector-12","New Tokyo","Ishima","Volhaven"],WarehouseInitialCost=5e9,WarehouseInitialSize=100,WarehouseUpgradeBaseCost=1e9,OfficeInitialCost=4e9,OfficeInitialSize=3,OfficeUpgradeBaseCost=1e9,BribeThreshold=1e14,BribeToRepRatio=1e9,ProductProductionCostRatio=5,DividendMaxPercentage=50,EmployeeSalaryMultiplier=3,CyclesPerEmployeeRaise=400,EmployeeRaiseAmount=50,BaseMaxProducts=3;let researchTreeBoxOpened=!1,researchTreeBox=null;$(document).mousedown(function(e){researchTreeBoxOpened&&null==$(e.target).closest("#corporation-research-popup-box-content").get(0)&&(Object(_utils_uiHelpers_removeElement__WEBPACK_IMPORTED_MODULE_32__.removeElement)(researchTreeBox),researchTreeBox=null,researchTreeBoxOpened=!1)});var empManualAssignmentModeActive=!1;function Industry(e={}){this.offices={[_Locations__WEBPACK_IMPORTED_MODULE_15__.Locations.Aevum]:0,[_Locations__WEBPACK_IMPORTED_MODULE_15__.Locations.Chongqing]:0,[_Locations__WEBPACK_IMPORTED_MODULE_15__.Locations.Sector12]:new OfficeSpace({loc:_Locations__WEBPACK_IMPORTED_MODULE_15__.Locations.Sector12,size:OfficeInitialSize}),[_Locations__WEBPACK_IMPORTED_MODULE_15__.Locations.NewTokyo]:0,[_Locations__WEBPACK_IMPORTED_MODULE_15__.Locations.Ishima]:0,[_Locations__WEBPACK_IMPORTED_MODULE_15__.Locations.Volhaven]:0},this.name=e.name?e.name:0,this.type=e.type?e.type:0,this.sciResearch=new _Material__WEBPACK_IMPORTED_MODULE_6__.Material({name:"Scientific Research"}),this.researched={},this.reqMats={},this.prodMats=[],this.products={},this.makesProducts=!1,this.awareness=0,this.popularity=0,this.startingCost=0,this.reFac=0,this.sciFac=0,this.hwFac=0,this.robFac=0,this.aiFac=0,this.advFac=0,this.prodMult=0,this.lastCycleRevenue=new decimal_js__WEBPACK_IMPORTED_MODULE_40__.a(0),this.lastCycleExpenses=new decimal_js__WEBPACK_IMPORTED_MODULE_40__.a(0),this.thisCycleRevenue=new decimal_js__WEBPACK_IMPORTED_MODULE_40__.a(0),this.thisCycleExpenses=new decimal_js__WEBPACK_IMPORTED_MODULE_40__.a(0);var t=Object.keys(_IndustryUpgrades__WEBPACK_IMPORTED_MODULE_5__.IndustryUpgrades).length;this.upgrades=Array(t).fill(0),this.state="START",this.newInd=!0,this.warehouses={[_Locations__WEBPACK_IMPORTED_MODULE_15__.Locations.Aevum]:0,[_Locations__WEBPACK_IMPORTED_MODULE_15__.Locations.Chonqing]:0,[_Locations__WEBPACK_IMPORTED_MODULE_15__.Locations.Sector12]:new _Warehouse__WEBPACK_IMPORTED_MODULE_10__.Warehouse({corp:e.corp,industry:this,loc:_Locations__WEBPACK_IMPORTED_MODULE_15__.Locations.Sector12,size:WarehouseInitialSize}),[_Locations__WEBPACK_IMPORTED_MODULE_15__.Locations.NewTokyo]:0,[_Locations__WEBPACK_IMPORTED_MODULE_15__.Locations.Ishima]:0,[_Locations__WEBPACK_IMPORTED_MODULE_15__.Locations.Volhaven]:0},this.init()}function Employee(e={}){if(!(this instanceof Employee))return new Employee(e);this.name=e.name?e.name:"Bobby",this.mor=e.morale?e.morale:Object(_utils_helpers_getRandomInt__WEBPACK_IMPORTED_MODULE_29__.getRandomInt)(50,100),this.hap=e.happiness?e.happiness:Object(_utils_helpers_getRandomInt__WEBPACK_IMPORTED_MODULE_29__.getRandomInt)(50,100),this.ene=e.energy?e.energy:Object(_utils_helpers_getRandomInt__WEBPACK_IMPORTED_MODULE_29__.getRandomInt)(50,100),this.age=e.age?e.age:Object(_utils_helpers_getRandomInt__WEBPACK_IMPORTED_MODULE_29__.getRandomInt)(20,50),this.int=e.intelligence?e.intelligence:Object(_utils_helpers_getRandomInt__WEBPACK_IMPORTED_MODULE_29__.getRandomInt)(10,50),this.cha=e.charisma?e.charisma:Object(_utils_helpers_getRandomInt__WEBPACK_IMPORTED_MODULE_29__.getRandomInt)(10,50),this.exp=e.experience?e.experience:Object(_utils_helpers_getRandomInt__WEBPACK_IMPORTED_MODULE_29__.getRandomInt)(10,50),this.cre=e.creativity?e.creativity:Object(_utils_helpers_getRandomInt__WEBPACK_IMPORTED_MODULE_29__.getRandomInt)(10,50),this.eff=e.efficiency?e.efficiency:Object(_utils_helpers_getRandomInt__WEBPACK_IMPORTED_MODULE_29__.getRandomInt)(10,50),this.sal=e.salary?e.salary:Object(_utils_helpers_getRandomInt__WEBPACK_IMPORTED_MODULE_29__.getRandomInt)(.1,5),this.pro=0,this.cyclesUntilRaise=CyclesPerEmployeeRaise,this.loc=e.loc?e.loc:"",this.pos=_EmployeePositions__WEBPACK_IMPORTED_MODULE_3__.EmployeePositions.Unassigned}Industry.prototype.init=function(){switch(this.startingCost=_IndustryData__WEBPACK_IMPORTED_MODULE_4__.IndustryStartingCosts[this.type],this.type){case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.Energy:this.reFac=.65,this.sciFac=.7,this.robFac=.05,this.aiFac=.3,this.advFac=.08,this.reqMats={Hardware:.1,Metal:.2},this.prodMats=["Energy"];break;case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.Utilities:case"Utilities":this.reFac=.5,this.sciFac=.6,this.robFac=.4,this.aiFac=.4,this.advFac=.08,this.reqMats={Hardware:.1,Metal:.1},this.prodMats=["Water"];break;case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.Agriculture:this.reFac=.72,this.sciFac=.5,this.hwFac=.2,this.robFac=.3,this.aiFac=.3,this.advFac=.04,this.reqMats={Water:.5,Energy:.5},this.prodMats=["Plants","Food"];break;case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.Fishing:this.reFac=.15,this.sciFac=.35,this.hwFac=.35,this.robFac=.5,this.aiFac=.2,this.advFac=.08,this.reqMats={Energy:.5},this.prodMats=["Food"];break;case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.Mining:this.reFac=.3,this.sciFac=.26,this.hwFac=.4,this.robFac=.45,this.aiFac=.45,this.advFac=.06,this.reqMats={Energy:.8},this.prodMats=["Metal"];break;case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.Food:this.sciFac=.12,this.hwFac=.15,this.robFac=.3,this.aiFac=.25,this.advFac=.25,this.reFac=.05,this.reqMats={Food:.5,Water:.5,Energy:.2},this.makesProducts=!0;break;case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.Tobacco:this.reFac=.15,this.sciFac=.75,this.hwFac=.15,this.robFac=.2,this.aiFac=.15,this.advFac=.2,this.reqMats={Plants:1,Water:.2},this.makesProducts=!0;break;case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.Chemical:this.reFac=.25,this.sciFac=.75,this.hwFac=.2,this.robFac=.25,this.aiFac=.2,this.advFac=.07,this.reqMats={Plants:1,Energy:.5,Water:.5},this.prodMats=["Chemicals"];break;case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.Pharmaceutical:this.reFac=.05,this.sciFac=.8,this.hwFac=.15,this.robFac=.25,this.aiFac=.2,this.advFac=.16,this.reqMats={Chemicals:2,Energy:1,Water:.5},this.prodMats=["Drugs"],this.makesProducts=!0;break;case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.Computer:case"Computer":this.reFac=.2,this.sciFac=.62,this.robFac=.36,this.aiFac=.19,this.advFac=.17,this.reqMats={Metal:2,Energy:1},this.prodMats=["Hardware"],this.makesProducts=!0;break;case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.Robotics:this.reFac=.32,this.sciFac=.65,this.aiFac=.36,this.advFac=.18,this.hwFac=.19,this.reqMats={Hardware:5,Energy:3},this.prodMats=["Robots"],this.makesProducts=!0;break;case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.Software:this.sciFac=.62,this.advFac=.16,this.hwFac=.25,this.reFac=.15,this.aiFac=.18,this.robFac=.05,this.reqMats={Hardware:.5,Energy:.5},this.prodMats=["AICores"],this.makesProducts=!0;break;case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.Healthcare:this.reFac=.1,this.sciFac=.75,this.advFac=.11,this.hwFac=.1,this.robFac=.1,this.aiFac=.1,this.reqMats={Robots:10,AICores:5,Energy:5,Water:5},this.makesProducts=!0;break;case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.RealEstate:this.robFac=.6,this.aiFac=.6,this.advFac=.25,this.sciFac=.05,this.hwFac=.05,this.reqMats={Metal:5,Energy:5,Water:2,Hardware:4},this.prodMats=["RealEstate"],this.makesProducts=!0;break;default:return void console.log("ERR: Invalid Industry Type passed into Industry.init(): "+this.type)}},Industry.prototype.getProductDescriptionText=function(){if(this.makesProducts)switch(this.type){case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.Food:return"create and manage restaurants";case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.Tobacco:return"create tobacco and tobacco-related products";case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.Pharmaceutical:return"develop new pharmaceutical drugs";case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.Computer:case"Computer":return"create new computer hardware and networking infrastructures";case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.Robotics:return"build specialized robots and robot-related products";case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.Software:return"develop computer software";case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.Healthcare:return"build and manage hospitals";case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.RealEstate:return"develop and manage real estate properties";default:return console.log("ERROR: Invalid industry type in Industry.getProductDescriptionText"),""}},Industry.prototype.getMaximumNumberProducts=function(){if(!this.makesProducts)return 0;let e=0;return this.hasResearch("uPgrade: Capacity.I")&&++e,this.hasResearch("uPgrade: Capacity.II")&&++e,BaseMaxProducts+e},Industry.prototype.hasMaximumNumberProducts=function(){return Object.keys(this.products).length>=this.getMaximumNumberProducts()},Industry.prototype.calculateProductionFactors=function(){for(var e=0,t=0;t0&&(e.breakdown+=t+": "+Object(_utils_StringHelperFunctions__WEBPACK_IMPORTED_MODULE_28__.formatNumber)(n.data[e.loc][0]*n.siz,0)+"
    ")}},Industry.prototype.process=function(e=1,t,n){if(this.state=t,"START"!==t){var a=this.processMaterials(e,n);this.thisCycleRevenue=this.thisCycleRevenue.plus(a[0]),this.thisCycleExpenses=this.thisCycleExpenses.plus(a[1]),a=this.processProducts(e,n),this.thisCycleRevenue=this.thisCycleRevenue.plus(a[0]),this.thisCycleExpenses=this.thisCycleExpenses.plus(a[1])}else{(isNaN(this.thisCycleRevenue)||isNaN(this.thisCycleExpenses))&&(console.log("ERROR: NaN in Corporation's computed revenue/expenses"),console.log(this.thisCycleRevenue.toString()),console.log(this.thisCycleExpenses.toString()),Object(_utils_DialogBox__WEBPACK_IMPORTED_MODULE_21__.dialogBoxCreate)("Something went wrong when compting Corporation's revenue/expenses. This is a bug. Please report to game developer"),this.thisCycleRevenue=new decimal_js__WEBPACK_IMPORTED_MODULE_40__.a(0),this.thisCycleExpenses=new decimal_js__WEBPACK_IMPORTED_MODULE_40__.a(0)),this.lastCycleRevenue=this.thisCycleRevenue.dividedBy(e*SecsPerMarketCycle),this.lastCycleExpenses=this.thisCycleExpenses.dividedBy(e*SecsPerMarketCycle),this.thisCycleRevenue=new decimal_js__WEBPACK_IMPORTED_MODULE_40__.a(0),this.thisCycleExpenses=new decimal_js__WEBPACK_IMPORTED_MODULE_40__.a(0),this.lastCycleRevenue.gt(0)&&(this.newInd=!1);var i=0;for(var r in this.offices)this.offices[r]instanceof OfficeSpace&&(i+=this.offices[r].process(e,{industry:this,corporation:n}));this.thisCycleExpenses=this.thisCycleExpenses.plus(i),this.processMaterialMarket(e),this.processProductMarket(e),this.popularity-=1e-4*e,this.popularity=Math.max(0,this.popularity);var o=n.getDreamSenseGain(),s=4*o;o>0&&(this.popularity+=o*e,this.awareness+=s*e)}},Industry.prototype.processMaterialMarket=function(e=1){for(var t=this.reqMats,n=this.prodMats,a=0;a0&&(i.qty+=a,expenses+=a*i.bCost)}(matName,industry),this.updateWarehouseSizeUsed(warehouse));break;case"PRODUCTION":if(warehouse.smartSupplyStore=0,this.prodMats.length>0){var mat=warehouse.materials[this.prodMats[0]],maxProd=this.getOfficeProductivity(office)*this.prodMult*company.getProductionMultiplier()*this.getProductionMultiplier();let e;e=mat.prdman[0]?Math.min(maxProd,mat.prdman[1]):maxProd,e*=SecsPerMarketCycle*marketCycles;var totalMatSize=0;for(let e=0;e0){var maxAmt=Math.floor((warehouse.size-warehouse.sizeUsed)/totalMatSize);e=Math.min(maxAmt,e)}e<0&&(e=0),warehouse.smartSupplyStore+=e/(SecsPerMarketCycle*marketCycles);var producableFrac=1;for(var reqMatName in this.reqMats)if(this.reqMats.hasOwnProperty(reqMatName)){var req=this.reqMats[reqMatName]*e;warehouse.materials[reqMatName].qty0&&e>0){for(const t in this.reqMats){var reqMatQtyNeeded=this.reqMats[t]*e*producableFrac;warehouse.materials[t].qty-=reqMatQtyNeeded,warehouse.materials[t].prd=0,warehouse.materials[t].prd-=reqMatQtyNeeded/(SecsPerMarketCycle*marketCycles)}for(let t=0;tmat.bCost?sCost-mat.bCost>markupLimit&&(markup=Math.pow(markupLimit/(sCost-mat.bCost),2)):sCost=0?(mat.qty-=sellAmt,revenue+=sellAmt*sCost,mat.sll=sellAmt/(SecsPerMarketCycle*marketCycles)):mat.sll=0}break;case"EXPORT":for(var matName in warehouse.materials)if(warehouse.materials.hasOwnProperty(matName)){var mat=warehouse.materials[matName];mat.totalExp=0;for(var expI=0;expI=expWarehouse.size)return;var maxAmt=Math.floor((expWarehouse.size-expWarehouse.sizeUsed)/_MaterialSizes__WEBPACK_IMPORTED_MODULE_7__.MaterialSizes[matName]);amt=Math.min(maxAmt,amt),expWarehouse.materials[matName].imp+=amt/(SecsPerMarketCycle*marketCycles),expWarehouse.materials[matName].qty+=amt,expWarehouse.materials[matName].qlt=mat.qlt,mat.qty-=amt,mat.totalExp+=amt,expIndustry.updateWarehouseSizeUsed(expWarehouse);break}}}mat.totalExp/=SecsPerMarketCycle*marketCycles}break;case"START":break;default:console.log("ERROR: Invalid state: "+this.state)}this.updateWarehouseSizeUsed(warehouse)}office instanceof OfficeSpace&&(this.sciResearch.qty+=.004*Math.pow(office.employeeProd[_EmployeePositions__WEBPACK_IMPORTED_MODULE_3__.EmployeePositions.RandD],.5)*company.getScientificResearchMultiplier()*this.getScientificResearchMultiplier())}return[revenue,expenses]},Industry.prototype.processProducts=function(e=1,t){var n=0;if("PRODUCTION"===this.state)for(const t in this.products){const n=this.products[t];if(!n.fin){const t=n.createCity,a=this.offices[t],i=a.employeeProd[_EmployeePositions__WEBPACK_IMPORTED_MODULE_3__.EmployeePositions.Engineer],r=a.employeeProd[_EmployeePositions__WEBPACK_IMPORTED_MODULE_3__.EmployeePositions.Management],o=a.employeeProd[_EmployeePositions__WEBPACK_IMPORTED_MODULE_3__.EmployeePositions.Operations],s=i+r+o;if(s<=0)break;const l=1+r/(1.2*s),c=(Math.pow(i,.34)+Math.pow(o,.2))*l;n.createProduct(e,c),n.prog>=100&&n.finishProduct(a.employeeProd,this);break}}for(var a in this.products)if(this.products.hasOwnProperty(a)){var i=this.products[a];i instanceof _Product__WEBPACK_IMPORTED_MODULE_8__.Product&&i.fin&&(n+=this.processProduct(e,i,t))}return[n,0]},Industry.prototype.processProduct=function(marketCycles=1,product,corporation){let totalProfit=0;for(let i=0;i0){var maxAmt=Math.floor((warehouse.size-warehouse.sizeUsed)/netStorageSize);prod=Math.min(maxAmt,prod)}warehouse.smartSupplyStore+=prod/(SecsPerMarketCycle*marketCycles);var producableFrac=1;for(var reqMatName in product.reqMats)if(product.reqMats.hasOwnProperty(reqMatName)){var req=product.reqMats[reqMatName]*prod;warehouse.materials[reqMatName].qty0&&prod>0){for(var reqMatName in product.reqMats)if(product.reqMats.hasOwnProperty(reqMatName)){var reqMatQtyNeeded=product.reqMats[reqMatName]*prod*producableFrac;warehouse.materials[reqMatName].qty-=reqMatQtyNeeded,warehouse.materials[reqMatName].prd-=reqMatQtyNeeded/(SecsPerMarketCycle*marketCycles)}product.data[city][0]+=prod*producableFrac}product.data[city][1]=prod*producableFrac/(SecsPerMarketCycle*marketCycles);break;case"SALE":for(var reqMatName in product.pCost=0,product.reqMats)product.reqMats.hasOwnProperty(reqMatName)&&(product.pCost+=product.reqMats[reqMatName]*warehouse.materials[reqMatName].bCost);product.pCost*=ProductProductionCostRatio;const businessFactor=this.getBusinessFactor(office),advertisingFactor=this.getAdvertisingFactors()[0],marketFactor=this.getMarketFactor(product),markupLimit=product.rat/product.mku;var sCost;if(product.marketTa2){const e=product.data[city][1],t=markupLimit,n=e,a=.5*Math.pow(product.rat,.65)*marketFactor*corporation.getSalesMultiplier()*businessFactor*advertisingFactor*this.getSalesMultiplier(),i=Math.sqrt(n/a);let r;r=0===a||0===i?0:t/i+product.pCost,product.marketTa2Price[city]=r,sCost=r}else product.marketTa1?sCost=product.pCost+markupLimit:Object(_utils_helpers_isString__WEBPACK_IMPORTED_MODULE_30__.isString)(product.sCost)?(sCost=product.sCost.replace(/MP/g,product.pCost+product.rat/product.mku),sCost=eval(sCost)):sCost=product.sCost;var markup=1;sCost>product.pCost&&sCost-product.pCost>markupLimit&&(markup=markupLimit/(sCost-product.pCost));var maxSell=.5*Math.pow(product.rat,.65)*marketFactor*corporation.getSalesMultiplier()*Math.pow(markup,2)*businessFactor*advertisingFactor*this.getSalesMultiplier(),sellAmt;if(product.sllman[city][0]&&Object(_utils_helpers_isString__WEBPACK_IMPORTED_MODULE_30__.isString)(product.sllman[city][1])){var tmp=product.sllman[city][1].replace(/MAX/g,maxSell);tmp=tmp.replace(/PROD/g,product.data[city][1]);try{tmp=eval(tmp)}catch(e){Object(_utils_DialogBox__WEBPACK_IMPORTED_MODULE_21__.dialogBoxCreate)("Error evaluating your sell price expression for "+product.name+" in "+this.name+"'s "+city+" office. Sell price is being set to MAX"),tmp=maxSell}sellAmt=Math.min(maxSell,tmp)}else sellAmt=product.sllman[city][0]&&product.sllman[city][1]>0?Math.min(maxSell,product.sllman[city][1]):!1===product.sllman[city][0]?0:maxSell;sellAmt<0&&(sellAmt=0),sellAmt=sellAmt*SecsPerMarketCycle*marketCycles,sellAmt=Math.min(product.data[city][0],sellAmt),sellAmt&&sCost?(product.data[city][0]-=sellAmt,totalProfit+=sellAmt*sCost,product.data[city][2]=sellAmt/(SecsPerMarketCycle*marketCycles)):product.data[city][2]=0;break;case"START":case"PURCHASE":case"EXPORT":break;default:console.log("ERROR: Invalid State: "+this.state)}}return totalProfit},Industry.prototype.discontinueProduct=function(e){for(var t in this.products)this.products.hasOwnProperty(t)&&e===this.products[t]&&delete this.products[t]},Industry.prototype.upgrade=function(e,t){var n=t.corporation,a=(t.division,t.office),i=e[0];for(e[1],e[2],e[3];this.upgrades.length<=i;)this.upgrades.push(0);switch(++this.upgrades[i],i){case 0:for(let e=0;e{if(this.sciResearch.qty>=n.cost)return this.sciResearch.qty-=n.cost,t.research(a[e]),this.researched[a[e]]=!0,Object(_utils_DialogBox__WEBPACK_IMPORTED_MODULE_21__.dialogBoxCreate)(`Researched ${a[e]}. It may take a market cycle `+`(~${SecsPerMarketCycle} seconds) before the effects of `+"the Research apply."),this.createResearchBox();Object(_utils_DialogBox__WEBPACK_IMPORTED_MODULE_21__.dialogBoxCreate)(`You do not have enough Scientific Research for ${n.name}`)}):console.warn(`Could not find Research Tree div for ${i}`)}const i=document.getElementById(`${e}-content`);null!=i&&(Object(_utils_uiHelpers_appendLineBreaks__WEBPACK_IMPORTED_MODULE_24__.appendLineBreaks)(i,2),i.appendChild(Object(_utils_uiHelpers_createElement__WEBPACK_IMPORTED_MODULE_25__.createElement)("pre",{display:"block",innerText:"Multipliers from research:\n"+` * Advertising Multiplier: x${t.getAdvertisingMultiplier()}\n`+` * Employee Charisma Multiplier: x${t.getEmployeeChaMultiplier()}\n`+` * Employee Creativity Multiplier: x${t.getEmployeeCreMultiplier()}\n`+` * Employee Efficiency Multiplier: x${t.getEmployeeEffMultiplier()}\n`+` * Employee Intelligence Multiplier: x${t.getEmployeeIntMultiplier()}\n`+` * Production Multiplier: x${t.getProductionMultiplier()}\n`+` * Sales Multiplier: x${t.getSalesMultiplier()}\n`+` * Scientific Research Multiplier: x${t.getScientificResearchMultiplier()}\n`+` * Storage Multiplier: x${t.getStorageMultiplier()}`})),i.appendChild(Object(_utils_uiHelpers_createPopupCloseButton__WEBPACK_IMPORTED_MODULE_27__.createPopupCloseButton)(researchTreeBox,{class:"std-button",display:"block",innerText:"Close"}))),researchTreeBoxOpened=!0},Industry.prototype.toJSON=function(){return Object(_utils_JSONReviver__WEBPACK_IMPORTED_MODULE_23__.Generic_toJSON)("Industry",this)},Industry.fromJSON=function(e){return Object(_utils_JSONReviver__WEBPACK_IMPORTED_MODULE_23__.Generic_fromJSON)(Industry,e.data)},_utils_JSONReviver__WEBPACK_IMPORTED_MODULE_23__.Reviver.constructors.Industry=Industry,Employee.prototype.process=function(e=1,t){var n=.003*e,a=n*Math.random();this.age+=n,this.exp+=n,this.age>150&&(this.int-=a,this.eff-=a,this.cha-=a),this.cyclesUntilRaise-=e,this.cyclesUntilRaise<=0&&(this.salary+=EmployeeRaiseAmount,this.cyclesUntilRaise+=CyclesPerEmployeeRaise);var i=n*Math.random();return this.pos===_EmployeePositions__WEBPACK_IMPORTED_MODULE_3__.EmployeePositions.Training&&(this.cha+=i,this.exp+=i,this.eff+=i),this.ene-=a,this.hap-=a,this.eneHappiness: "+Object(_utils_StringHelperFunctions__WEBPACK_IMPORTED_MODULE_28__.formatNumber)(this.hap,3)+"
    Energy: "+Object(_utils_StringHelperFunctions__WEBPACK_IMPORTED_MODULE_28__.formatNumber)(this.ene,3)+"
    Age: "+Object(_utils_StringHelperFunctions__WEBPACK_IMPORTED_MODULE_28__.formatNumber)(this.age,3)+"
    Intelligence: "+Object(_utils_StringHelperFunctions__WEBPACK_IMPORTED_MODULE_28__.formatNumber)(r,3)+"
    Charisma: "+Object(_utils_StringHelperFunctions__WEBPACK_IMPORTED_MODULE_28__.formatNumber)(i,3)+"
    Experience: "+Object(_utils_StringHelperFunctions__WEBPACK_IMPORTED_MODULE_28__.formatNumber)(this.exp,3)+"
    Creativity: "+Object(_utils_StringHelperFunctions__WEBPACK_IMPORTED_MODULE_28__.formatNumber)(a,3)+"
    Efficiency: "+Object(_utils_StringHelperFunctions__WEBPACK_IMPORTED_MODULE_28__.formatNumber)(o,3)+"
    Salary: "+_ui_numeralFormat__WEBPACK_IMPORTED_MODULE_18__.numeralWrapper.format(this.sal,"$0.000a")+"/ s
    "}));var s=Object(_utils_uiHelpers_createElement__WEBPACK_IMPORTED_MODULE_25__.createElement)("select",{});for(var l in _EmployeePositions__WEBPACK_IMPORTED_MODULE_3__.EmployeePositions)_EmployeePositions__WEBPACK_IMPORTED_MODULE_3__.EmployeePositions.hasOwnProperty(l)&&s.add(Object(_utils_uiHelpers_createElement__WEBPACK_IMPORTED_MODULE_25__.createElement)("option",{text:_EmployeePositions__WEBPACK_IMPORTED_MODULE_3__.EmployeePositions[l],value:_EmployeePositions__WEBPACK_IMPORTED_MODULE_3__.EmployeePositions[l]}));s.addEventListener("change",()=>{this.pos=s.options[s.selectedIndex].value});for(var c=0;c=this.size},OfficeSpace.prototype.process=function(e=1,t){t.corporation;var n=t.industry;if(n.hasResearch("HRBuddy-Recruitment")&&!this.atCapacity()){const e=this.hireRandomEmployee();n.hasResearch("HRBuddy-Training")&&(e.pos=_EmployeePositions__WEBPACK_IMPORTED_MODULE_3__.EmployeePositions.Training)}this.maxEne=100,this.maxHap=100,this.maxMor=100,n.hasResearch("Go-Juice")&&(this.maxEne+=10),n.hasResearch("JoyWire")&&(this.maxHap+=10),n.hasResearch("Sti.mu")&&(this.maxMor+=10);var a=1;n.funds<0&&n.lastCycleRevenue<0?a=Math.pow(.99,e):n.funds>0&&n.lastCycleRevenue>0&&(a=Math.pow(1.01,e));const i=n.hasResearch("AutoBrew"),r=n.hasResearch("AutoPartyManager");var o=0;for(let t=0;tCharisma: "+Object(_utils_StringHelperFunctions__WEBPACK_IMPORTED_MODULE_28__.formatNumber)(t.cha,1)+"
    Experience: "+Object(_utils_StringHelperFunctions__WEBPACK_IMPORTED_MODULE_28__.formatNumber)(t.exp,1)+"
    Creativity: "+Object(_utils_StringHelperFunctions__WEBPACK_IMPORTED_MODULE_28__.formatNumber)(t.cre,1)+"
    Efficiency: "+Object(_utils_StringHelperFunctions__WEBPACK_IMPORTED_MODULE_28__.formatNumber)(t.eff,1)+"
    Salary: "+_ui_numeralFormat__WEBPACK_IMPORTED_MODULE_18__.numeralWrapper.format(t.sal,"$0.000a")+" s
    ",clickListener:()=>(n.hireEmployee(t,e),Object(_utils_uiHelpers_removeElementById__WEBPACK_IMPORTED_MODULE_33__.removeElementById)("cmpy-mgmt-hire-employee-popup"),!1)})},g=Object(_utils_uiHelpers_createElement__WEBPACK_IMPORTED_MODULE_25__.createElement)("a",{class:"a-link-button",innerText:"Cancel",float:"right",clickListener:()=>(Object(_utils_uiHelpers_removeElementById__WEBPACK_IMPORTED_MODULE_33__.removeElementById)("cmpy-mgmt-hire-employee-popup"),!1)}),_=[h,d(u,this),d(p,this),d(m,this),g];Object(_utils_uiHelpers_createPopup__WEBPACK_IMPORTED_MODULE_26__.createPopup)("cmpy-mgmt-hire-employee-popup",_)}},OfficeSpace.prototype.hireEmployee=function(e,t){var n=t.corporation,a=(t.industry,Object(_utils_YesNoBox__WEBPACK_IMPORTED_MODULE_34__.yesNoTxtInpBoxGetYesButton)()),i=Object(_utils_YesNoBox__WEBPACK_IMPORTED_MODULE_34__.yesNoTxtInpBoxGetNoButton)();a.innerHTML="Hire",i.innerHTML="Cancel",a.addEventListener("click",()=>{for(var t=Object(_utils_YesNoBox__WEBPACK_IMPORTED_MODULE_34__.yesNoTxtInpBoxGetInput)(),a=0;aObject(_utils_YesNoBox__WEBPACK_IMPORTED_MODULE_34__.yesNoTxtInpBoxClose)()),Object(_utils_YesNoBox__WEBPACK_IMPORTED_MODULE_34__.yesNoTxtInpBoxCreate)("Give your employee a nickname!")},OfficeSpace.prototype.hireRandomEmployee=function(){if(!this.atCapacity()&&null==document.getElementById("cmpy-mgmt-hire-employee-popup")){var e=Object(_utils_helpers_getRandomInt__WEBPACK_IMPORTED_MODULE_29__.getRandomInt)(76,100)/100,t=Object(_utils_helpers_getRandomInt__WEBPACK_IMPORTED_MODULE_29__.getRandomInt)(50,100),n=Object(_utils_helpers_getRandomInt__WEBPACK_IMPORTED_MODULE_29__.getRandomInt)(50,100),a=Object(_utils_helpers_getRandomInt__WEBPACK_IMPORTED_MODULE_29__.getRandomInt)(50,100),i=Object(_utils_helpers_getRandomInt__WEBPACK_IMPORTED_MODULE_29__.getRandomInt)(50,100),r=Object(_utils_helpers_getRandomInt__WEBPACK_IMPORTED_MODULE_29__.getRandomInt)(50,100),o=new Employee({intelligence:t*e,charisma:n*e,experience:a*e,creativity:i*e,efficiency:r*e,salary:EmployeeSalaryMultiplier*(t+n+a+i+r)*e}),s=Object(_utils_StringHelperFunctions__WEBPACK_IMPORTED_MODULE_28__.generateRandomString)(7);for(let e=0;e=CyclesPerIndustryStateCycle){const t=this.getState(),n=1,a=n*CyclesPerIndustryStateCycle;if(this.storedCycles-=a,this.divisions.forEach(function(a){a.process(n,t,e)}),this.shareSaleCooldown>0&&(this.shareSaleCooldown-=a),this.issueNewSharesCooldown>0&&(this.issueNewSharesCooldown-=a),"START"===t){this.revenue=new decimal_js__WEBPACK_IMPORTED_MODULE_40__.a(0),this.expenses=new decimal_js__WEBPACK_IMPORTED_MODULE_40__.a(0),this.divisions.forEach(e=>{e.lastCycleRevenue!==-1/0&&e.lastCycleRevenue!==1/0&&e.lastCycleExpenses!==-1/0&&e.lastCycleExpenses!==1/0&&(this.revenue=this.revenue.plus(e.lastCycleRevenue),this.expenses=this.expenses.plus(e.lastCycleExpenses))});const e=this.revenue.minus(this.expenses).times(n*SecsPerMarketCycle);if(isNaN(this.funds)&&(Object(_utils_DialogBox__WEBPACK_IMPORTED_MODULE_21__.dialogBoxCreate)("There was an error calculating your Corporations funds and they got reset to 0. This is a bug. Please report to game developer.

    (Your funds have been set to $150b for the inconvenience)"),this.funds=new decimal_js__WEBPACK_IMPORTED_MODULE_40__.a(15e10)),this.dividendPercentage>0&&e>0)if(isNaN(this.dividendPercentage)||this.dividendPercentage<0||this.dividendPercentage>DividendMaxPercentage)console.error(`Invalid Corporation dividend percentage: ${this.dividendPercentage}`);else{const t=this.dividendPercentage/100*e,n=e-t,a=t/this.totalShares,i=this.numShares*a*(1-this.dividendTaxPercentage/100);_Player__WEBPACK_IMPORTED_MODULE_17__.a.gainMoney(i),_Player__WEBPACK_IMPORTED_MODULE_17__.a.recordMoneySource(i,"corporation"),this.funds=this.funds.plus(n)}else this.funds=this.funds.plus(e);this.updateSharePrice()}this.state.nextState(),_ui_navigationTracking__WEBPACK_IMPORTED_MODULE_19__.routing.isOn(_ui_navigationTracking__WEBPACK_IMPORTED_MODULE_19__.Page.Corporation)&&this.rerender()}},Corporation.prototype.determineValuation=function(){var e,t=this.revenue.minus(this.expenses).toNumber();return this.public?(this.dividendPercentage>0&&(t*=(100-this.dividendPercentage)/100),e=this.funds.toNumber()+85e3*t,e*=Math.pow(1.1,this.divisions.length),e=Math.max(e,0)):(e=1e10+Math.max(this.funds.toNumber(),0)/3,t>0?(e+=315e3*t,e*=Math.pow(1.1,this.divisions.length)):e=1e10*Math.pow(1.1,this.divisions.length),e-=e%1e6),e*_BitNode_BitNodeMultipliers__WEBPACK_IMPORTED_MODULE_11__.BitNodeMultipliers.CorporationValuation},Corporation.prototype.getInvestment=function(){var e,t=this.determineValuation();let n=4;switch(this.fundingRound){case 0:e=.1,n=4;break;case 1:e=.35,n=3;break;case 2:e=.25,n=3;break;case 3:e=.2,n=2.5;break;case 4:return}var a=t*e*n,i=Math.floor(INITIALSHARES*e),r=Object(_utils_YesNoBox__WEBPACK_IMPORTED_MODULE_34__.yesNoBoxGetYesButton)(),o=Object(_utils_YesNoBox__WEBPACK_IMPORTED_MODULE_34__.yesNoBoxGetNoButton)();r.innerHTML="Accept",o.innerHML="Reject",r.addEventListener("click",()=>(++this.fundingRound,this.funds=this.funds.plus(a),this.numShares-=i,this.rerender(),Object(_utils_YesNoBox__WEBPACK_IMPORTED_MODULE_34__.yesNoBoxClose)())),o.addEventListener("click",()=>Object(_utils_YesNoBox__WEBPACK_IMPORTED_MODULE_34__.yesNoBoxClose)()),Object(_utils_YesNoBox__WEBPACK_IMPORTED_MODULE_34__.yesNoBoxCreate)("An investment firm has offered you "+_ui_numeralFormat__WEBPACK_IMPORTED_MODULE_18__.numeralWrapper.format(a,"$0.000a")+" in funding in exchange for a "+_ui_numeralFormat__WEBPACK_IMPORTED_MODULE_18__.numeralWrapper.format(100*e,"0.000a")+"% stake in the company ("+_ui_numeralFormat__WEBPACK_IMPORTED_MODULE_18__.numeralWrapper.format(i,"0.000a")+" shares).

    Do you accept or reject this offer?

    Hint: Investment firms will offer more money if your corporation is turning a profit")},Corporation.prototype.goPublic=function(){var e,t=this.determineValuation()/this.totalShares,n=Object(_utils_uiHelpers_createElement__WEBPACK_IMPORTED_MODULE_25__.createElement)("p",{innerHTML:"Enter the number of shares you would like to issue for your IPO. These shares will be publicly sold and you will no longer own them. Your Corporation will receive "+_ui_numeralFormat__WEBPACK_IMPORTED_MODULE_18__.numeralWrapper.format(t,"$0.000a")+" per share (the IPO money will be deposited directly into your Corporation's funds).

    You have a total of "+_ui_numeralFormat__WEBPACK_IMPORTED_MODULE_18__.numeralWrapper.format(this.numShares,"0.000a")+" of shares that you can issue."}),a=Object(_utils_uiHelpers_createElement__WEBPACK_IMPORTED_MODULE_25__.createElement)("input",{type:"number",placeholder:"Shares to issue",onkeyup:t=>{t.preventDefault(),t.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_31__.KEY.ENTER&&e.click()}}),i=Object(_utils_uiHelpers_createElement__WEBPACK_IMPORTED_MODULE_25__.createElement)("br",{});e=Object(_utils_uiHelpers_createElement__WEBPACK_IMPORTED_MODULE_25__.createElement)("a",{class:"a-link-button",innerText:"Go Public",clickListener:()=>{var e=Math.round(a.value),t=this.determineValuation()/this.totalShares;return isNaN(e)?(Object(_utils_DialogBox__WEBPACK_IMPORTED_MODULE_21__.dialogBoxCreate)("Invalid value for number of issued shares"),!1):e>this.numShares?(Object(_utils_DialogBox__WEBPACK_IMPORTED_MODULE_21__.dialogBoxCreate)("Error: You don't have that many shares to issue!"),!1):(this.public=!0,this.sharePrice=t,this.issuedShares=e,this.numShares-=e,this.funds=this.funds.plus(e*t),this.rerender(),Object(_utils_uiHelpers_removeElementById__WEBPACK_IMPORTED_MODULE_33__.removeElementById)("cmpy-mgmt-go-public-popup"),Object(_utils_DialogBox__WEBPACK_IMPORTED_MODULE_21__.dialogBoxCreate)(`You took your ${this.name} public and earned `+`${_ui_numeralFormat__WEBPACK_IMPORTED_MODULE_18__.numeralWrapper.formatMoney(e*t)} in your IPO`),!1)}});var r=Object(_utils_uiHelpers_createElement__WEBPACK_IMPORTED_MODULE_25__.createElement)("a",{class:"a-link-button",innerText:"Cancel",clickListener:()=>(Object(_utils_uiHelpers_removeElementById__WEBPACK_IMPORTED_MODULE_33__.removeElementById)("cmpy-mgmt-go-public-popup"),!1)});Object(_utils_uiHelpers_createPopup__WEBPACK_IMPORTED_MODULE_26__.createPopup)("cmpy-mgmt-go-public-popup",[n,i,a,e,r])},Corporation.prototype.getTargetSharePrice=function(){return this.determineValuation()/(2*(this.totalShares-this.numShares)+1)},Corporation.prototype.updateSharePrice=function(){const e=this.getTargetSharePrice();this.sharePrice<=e?this.sharePrice*=1+.01*Math.random():this.sharePrice*=1-.01*Math.random(),this.sharePrice<=.01&&(this.sharePrice=.01)},Corporation.prototype.immediatelyUpdateSharePrice=function(){this.sharePrice=this.getTargetSharePrice()},Corporation.prototype.calculateShareSale=function(e){let t=e,n=this.shareSalesUntilPriceUpdate,a=this.sharePrice,i=0,r=0;const o=Math.ceil(e/SHARESPERPRICEUPDATE);if(!(isNaN(o)||o>1e7)){for(let e=0;e3600?`${Math.floor(t/3600)} hour(s)`:t>60?`${Math.floor(t/60)} minute(s)`:`${Math.floor(t)} second(s)`},Corporation.prototype.unlock=function(e){const t=e[0],n=e[1];for(;this.unlockUpgrades.length<=t;)this.unlockUpgrades.push(0);this.funds.lt(n)?Object(_utils_DialogBox__WEBPACK_IMPORTED_MODULE_21__.dialogBoxCreate)("You don't have enough funds to unlock this!"):(this.unlockUpgrades[t]=1,this.funds=this.funds.minus(n),5===t?this.dividendTaxPercentage-=5:6===t&&(this.dividendTaxPercentage-=10))},Corporation.prototype.upgrade=function(e){for(var t=e[0],n=e[1],a=e[2],i=e[3];this.upgrades.length<=t;)this.upgrades.push(0);for(;this.upgradeMultipliers.length<=t;)this.upgradeMultipliers.push(1);var r=n*Math.pow(a,this.upgrades[t]);if(this.funds.lt(r))Object(_utils_DialogBox__WEBPACK_IMPORTED_MODULE_21__.dialogBoxCreate)("You don't have enough funds to purchase this!");else if(++this.upgrades[t],this.funds=this.funds.minus(r),this.upgradeMultipliers[t]=1+this.upgrades[t]*i,1===t)for(var o=0;ox.longestName?e.length:x.longestName,x.longestSymbol=A[e].length>x.longestSymbol?A[e].length:x.longestSymbol}function I(){for(var e in P)P.hasOwnProperty(e)&&delete P[e];const t=_.getRandomInt;var n=o.Locations.AevumECorp,i=new a.Stock(n,A[n],t(40,50)/100,!0,19,t(17e3,28e3),24e11);P[n]=i;var r=o.Locations.Sector12MegaCorp,s=new a.Stock(r,A[r],t(40,50)/100,!0,19,t(24e3,34e3),24e11);P[r]=s;var l=o.Locations.Sector12BladeIndustries,c=new a.Stock(l,A[l],t(70,80)/100,!0,13,t(12e3,25e3),16e11);P[l]=c;var u=o.Locations.AevumClarkeIncorporated,p=new a.Stock(u,A[u],t(65,75)/100,!0,12,t(1e4,25e3),15e11);P[u]=p;var m=o.Locations.VolhavenOmniTekIncorporated,h=new a.Stock(m,A[m],t(60,70)/100,!0,12,t(32e3,43e3),18e11);P[m]=h;var d=o.Locations.Sector12FourSigma,g=new a.Stock(d,A[d],t(100,110)/100,!0,17,t(5e4,8e4),2e12);P[d]=g;var f=o.Locations.ChongqingKuaiGongInternational,y=new a.Stock(f,A[f],t(75,85)/100,!0,10,t(16e3,28e3),19e11);P[f]=y;var b=o.Locations.AevumFulcrumTechnologies,v=new a.Stock(b,A[b],t(120,130)/100,!0,16,t(29e3,36e3),2e12);P[b]=v;var E=o.Locations.IshimaStormTechnologies,k=new a.Stock(E,A[E],t(80,90)/100,!0,7,t(2e4,25e3),12e11);P[E]=k;var C=o.Locations.NewTokyoDefComm,T=new a.Stock(C,A[C],t(60,70)/100,!0,10,t(6e3,19e3),9e11);P[C]=T;var O=o.Locations.VolhavenHeliosLabs,S=new a.Stock(O,A[O],t(55,65)/100,!0,9,t(1e4,18e3),825e9);P[O]=S;var M=o.Locations.NewTokyoVitaLife,w=new a.Stock(M,A[M],t(70,80)/100,!0,7,t(8e3,14e3),1e12);P[M]=w;var x=o.Locations.Sector12IcarusMicrosystems,R=new a.Stock(x,A[x],t(60,70)/100,!0,7.5,t(12e3,24e3),8e11);P[x]=R;var N=o.Locations.Sector12UniversalEnergy,I=new a.Stock(N,A[N],t(50,60)/100,!0,10,t(16e3,29e3),9e11);P[N]=I;var L=o.Locations.AevumAeroCorp,D=new a.Stock(L,A[L],t(55,65)/100,!0,6,t(8e3,17e3),64e10);P[L]=D;var B=o.Locations.VolhavenOmniaCybersystems,W=new a.Stock(B,A[B],t(65,75)/100,!0,4.5,t(6e3,15e3),6e11);P[B]=W;var j=o.Locations.ChongqingSolarisSpaceSystems,F=new a.Stock(j,A[j],t(70,80)/100,!0,8.5,t(14e3,28e3),705e9);P[j]=F;var U=o.Locations.NewTokyoGlobalPharmaceuticals,H=new a.Stock(U,A[U],t(55,65)/100,!0,10.5,t(12e3,3e4),695e9);P[U]=H;var G=o.Locations.IshimaNovaMedical,K=new a.Stock(G,A[G],t(70,80)/100,!0,5,t(15e3,27e3),6e11);P[G]=K;var q=o.Locations.AevumWatchdogSecurity,$=new a.Stock(q,A[q],t(240,260)/100,!0,1.5,t(4e3,8500),45e10);P[q]=$;var Y=o.Locations.VolhavenLexoCorp,z=new a.Stock(Y,A[Y],t(115,135)/100,!0,6,t(4500,8e3),3e11);P[Y]=z;var V=o.Locations.AevumRhoConstruction,J=new a.Stock(V,A[V],t(50,70)/100,!0,1,t(2e3,7e3),18e10);P[V]=J;var X=o.Locations.Sector12AlphaEnterprises,Q=new a.Stock(X,A[X],t(175,205)/100,!0,10,t(4e3,8500),24e10);P[X]=Q;var Z=o.Locations.VolhavenSysCoreSecurities,ee=new a.Stock(Z,A[Z],t(150,170)/100,!0,3,t(3e3,8e3),2e11);P[Z]=ee;var te=o.Locations.VolhavenCompuTek,ne=new a.Stock(te,A[te],t(80,100)/100,!0,4,t(1e3,6e3),185e9);P[te]=ne;var ae=o.Locations.AevumNetLinkTechnologies,ie=new a.Stock(ae,A[ae],t(400,430)/100,!0,1,t(1e3,5e3),58e9);P[ae]=ie;var re=o.Locations.IshimaOmegaSoftware,oe=new a.Stock(re,A[re],t(90,110)/100,!0,.5,t(1e3,8e3),6e10);P[re]=oe;var se=o.Locations.Sector12FoodNStuff,le=new a.Stock(se,A[se],t(70,80)/100,!1,1,t(500,4500),45e9);P[se]=le;var ce=new a.Stock("Sigma Cosmetics",A["Sigma Cosmetics"],t(260,300)/100,!0,0,t(1500,3500),3e10);P["Sigma Cosmetics"]=ce;var ue=new a.Stock("Joes Guns",A["Joes Guns"],t(360,400)/100,!0,1,t(250,1500),42e9);P["Joes Guns"]=ue;var pe="Catalyst Ventures",me=new a.Stock(pe,A[pe],t(120,175)/100,!0,13.5,t(250,1500),1e11);P[pe]=me;var he="Microdyne Technologies",de=new a.Stock(he,A[he],t(70,80)/100,!0,8,t(15e3,3e4),36e10);P[he]=de;var ge="Titan Laboratories",_e=new a.Stock(ge,A[ge],t(50,70)/100,!0,11,t(12e3,24e3),42e10);P[ge]=_e;var fe={};for(var ye in P)if(P.hasOwnProperty(ye)){var be=P[ye];if(!(be instanceof a.Stock))continue;fe[be.symbol]=[]}P.Orders=fe,P.storedCycles=0,P.lastUpdate=0}function L(){for(var e in A)if(A.hasOwnProperty(e)){var t=P[e];if(null==t){console.error(`Could not find Stock for ${e}`);continue}var n=A[e];w[n]=t}}function D(){for(var e in P)if(P.hasOwnProperty(e)){var t=P[e];if(!(t instanceof a.Stock))continue;var n=.6;t.b&&(n=.4),Math.random()e.maxShares)return Object(m.dialogBoxCreate)(`You cannot purchase this many shares. ${e.symbol} has a maximum of `+`${p.numeralWrapper.formatBigNumber(e.maxShares)} shares.`),!1;var a=e.playerShares*e.playerAvgPx;c.a.loseMoney(n+r.CONSTANTS.StockMarketCommission);var i=a+n;return e.playerShares=Math.round(e.playerShares+t),e.playerAvgPx=i/e.playerShares,ee(e),Object(m.dialogBoxCreate)("Bought "+p.numeralWrapper.format(t,"0,0")+" shares of "+e.symbol+" at "+p.numeralWrapper.format(e.price,"($0.000a)")+" per share. Paid "+p.numeralWrapper.format(r.CONSTANTS.StockMarketCommission,"($0.000a)")+" in commission fees."),!0}function W(e,t){if(0==t)return!1;if(null==e||t<0||isNaN(t))return Object(m.dialogBoxCreate)("Failed to sell stock. This may be a bug, contact developer"),!1;if((t=Math.round(t))>e.playerShares&&(t=e.playerShares),0===t)return!1;var n=e.price*t-r.CONSTANTS.StockMarketCommission;return c.a.gainMoney(n),c.a.recordMoneySource(n,"stock"),e.playerShares=Math.round(e.playerShares-t),0==e.playerShares&&(e.playerAvgPx=0),ee(e),Object(m.dialogBoxCreate)("Sold "+p.numeralWrapper.format(t,"0,0")+" shares of "+e.symbol+" at "+p.numeralWrapper.format(e.price,"($0.000a)")+" per share. After commissions, you gained a total of "+p.numeralWrapper.format(n,"($0.000a)")+"."),!0}function j(e,t,n=null){var a=n instanceof l.b;if(0===(t=Math.round(t))||t<0)return!1;if(null==e||isNaN(t))return a?n.scriptRef.log("ERROR: shortStock() failed because of invalid arguments."):Object(m.dialogBoxCreate)("Failed to initiate a short position in a stock. This is probably due to an invalid quantity. Otherwise, this may be a bug, so contact developer"),!1;var i=e.price*t;if(c.a.money.lt(i+r.CONSTANTS.StockMarketCommission))return a?n.scriptRef.log("ERROR: shortStock() failed because you do not have enough money to purchase this short position. You need "+p.numeralWrapper.format(i+r.CONSTANTS.StockMarketCommission,"($0.000a)")+"."):Object(m.dialogBoxCreate)("You do not have enough money to purchase this short position. You need "+p.numeralWrapper.format(i+r.CONSTANTS.StockMarketCommission,"($0.000a)")+"."),!1;if(t+e.playerShares+e.playerShortShares>e.maxShares)return a?n.scriptRef.log("ERROR: shortStock() failed because purchasing this many short shares would exceed "+`${e.symbol}'s maximum number of shares.`):Object(m.dialogBoxCreate)(`You cannot purchase this many shares. ${e.symbol} has a maximum of `+`${e.maxShares} shares.`),!1;var o=e.playerShortShares*e.playerAvgShortPx;c.a.loseMoney(i+r.CONSTANTS.StockMarketCommission);var s=o+i;return e.playerShortShares=Math.round(e.playerShortShares+t),e.playerAvgShortPx=s/e.playerShortShares,ee(e),a?null==n.disableLogs.ALL&&null==n.disableLogs.shortStock&&n.scriptRef.log("Bought a short position of "+p.numeralWrapper.format(t,"0,0")+" shares of "+e.symbol+" at "+p.numeralWrapper.format(e.price,"($0.000a)")+" per share. Paid "+p.numeralWrapper.format(r.CONSTANTS.StockMarketCommission,"($0.000a)")+" in commission fees."):Object(m.dialogBoxCreate)("Bought a short position of "+p.numeralWrapper.format(t,"0,0")+" shares of "+e.symbol+" at "+p.numeralWrapper.format(e.price,"($0.000a)")+" per share. Paid "+p.numeralWrapper.format(r.CONSTANTS.StockMarketCommission,"($0.000a)")+" in commission fees."),!0}function F(e,t,n=null){var a=n instanceof l.b;if(null==e||isNaN(t)||t<0)return a?n.scriptRef.log("ERROR: sellShort() failed because of invalid arguments."):Object(m.dialogBoxCreate)("Failed to sell a short position in a stock. This is probably due to an invalid quantity. Otherwise, this may be a bug, so contact developer"),!1;if((t=Math.round(t))>e.playerShortShares&&(t=e.playerShortShares),0===t)return!1;var i=t*e.playerAvgShortPx,o=(e.playerAvgShortPx-e.price)*t-r.CONSTANTS.StockMarketCommission;return isNaN(o)&&(o=0),c.a.gainMoney(i+o),c.a.recordMoneySource(o,"stock"),a&&(n.scriptRef.onlineMoneyMade+=o,c.a.scriptProdSinceLastAug+=o),e.playerShortShares=Math.round(e.playerShortShares-t),0===e.playerShortShares&&(e.playerAvgShortPx=0),ee(e),a?null==n.disableLogs.ALL&&null==n.disableLogs.sellShort&&n.scriptRef.log("Sold your short position of "+p.numeralWrapper.format(t,"0,0")+" shares of "+e.symbol+" at "+p.numeralWrapper.format(e.price,"($0.000a)")+" per share. After commissions, you gained a total of "+p.numeralWrapper.format(i+o,"($0.000a)")+"."):Object(m.dialogBoxCreate)("Sold your short position of "+p.numeralWrapper.format(t,"0,0")+" shares of "+e.symbol+" at "+p.numeralWrapper.format(e.price,"($0.000a)")+" per share. After commissions, you gained a total of "+p.numeralWrapper.format(i+o,"($0.000a)")+"."),!0}function U(e=1){(null==P.storedCycles||isNaN(P.storedCycles))&&(P.storedCycles=0),P.storedCycles+=e;const t=6e3/r.CONSTANTS.MilliPerCycle;if(P.storedCycles=s.cap&&(c=.1,s.b=!1);var p=Math.random();p50&&(s.otlkMag=50),s.otlkMag<0&&(s.otlkMag*=-1,s.b=!s.b)}}}function H(e,t,n){var i=P.Orders;if(null!=i){var r=i[e.symbol];if(null==r||r.constructor!==Array)return console.log("ERROR: Invalid Order book for "+e.symbol+" in processOrders()"),void(r=[]);for(var o=0;o=s.price&&S(s);break;case k.LimitSell:case k.StopBuy:s.pos===C.Long&&e.price>=s.price?S(s):s.pos===C.Short&&e.price<=s.price&&S(s);break;case k.StopSell:s.pos===C.Long&&e.price<=s.price?S(s):s.pos===C.Short&&e.price>=s.price&&S(s);break;default:return void console.log("Invalid order type: "+s.type)}}}else{var l={};for(var c in P)if(P.hasOwnProperty(c)){if(!((e=P[c])instanceof a.Stock))continue;l[e.symbol]=[]}P.Orders=l}}function G(e){K=e}var K=!1,q=!1,$=r.CONSTANTS.StockMarketCommission;function Y(){function e(e,t,n,a,i){e.innerText=a,e.classList.remove("a-link-button"),e.classList.remove("a-link-button-bought"),e.classList.remove("a-link-button-inactive"),!n&&c.a.money.gte(t)?e.classList.add("a-link-button"):n?(e.innerText=i,e.classList.add("a-link-button-bought")):e.classList.add("a-link-button-inactive")}null==c.a.hasWseAccount&&(c.a.hasWseAccount=!1),null==c.a.hasTixApiAccess&&(c.a.hasTixApiAccess=!1),null==c.a.has4SData&&(c.a.has4SData=!1),null==c.a.has4SDataTixApi&&(c.a.has4SDataTixApi=!1);var t=Object(h.clearEventListeners)("stock-market-buy-account");e(t,r.CONSTANTS.WSEAccountCost,c.a.hasWseAccount,"Buy WSE Account - "+p.numeralWrapper.format(r.CONSTANTS.WSEAccountCost,"($0.000a)"),"WSE Account - Purchased"),t.addEventListener("click",function(){return c.a.hasWseAccount=!0,I(),L(),c.a.loseMoney(r.CONSTANTS.WSEAccountCost),Y(),!1});var n=Object(h.clearEventListeners)("stock-market-buy-tix-api");e(n,r.CONSTANTS.TIXAPICost,c.a.hasTixApiAccess,"Buy Trade Information eXchange (TIX) API Access - "+p.numeralWrapper.format(r.CONSTANTS.TIXAPICost,"($0.000a)"),"TIX API Access - Purchased"),n.addEventListener("click",function(){return c.a.hasTixApiAccess=!0,c.a.loseMoney(r.CONSTANTS.TIXAPICost),Y(),!1});var o=Object(h.clearEventListeners)("stock-market-buy-4s-data");e(o,Object(i.getStockMarket4SDataCost)(),c.a.has4SData,"Buy 4S Market Data Access - "+p.numeralWrapper.format(Object(i.getStockMarket4SDataCost)(),"($0.000a)"),"4S Market Data - Purchased"),o.addEventListener("click",function(){return!c.a.money.lt(Object(i.getStockMarket4SDataCost)())&&(c.a.has4SData=!0,c.a.loseMoney(Object(i.getStockMarket4SDataCost)()),Y(),!1)}),o.appendChild(Object(y.createElement)("span",{class:"tooltiptext",innerText:"Lets you view additional pricing and volatility information about stocks"})),o.style.marginRight="2px";var s=Object(h.clearEventListeners)("stock-market-4s-data-help-tip");s.style.marginTop="10px",s.addEventListener("click",()=>(Object(m.dialogBoxCreate)("Access to the 4S Market Data feed will display two additional pieces of information about each stock: Price Forecast & Volatility

    Price Forecast indicates the probability the stock has of increasing or decreasing. A '+' forecast means the stock has a higher chance of increasing than decreasing, and a '-' means the opposite. The number of '+/-' symbols is used to illustrate the magnitude of these probabilities. For example, '+++' means that the stock has a significantly higher chance of increasing than decreasing, while '+' means that the stock only has a slightly higher chance of increasing than decreasing.

    Volatility represents the maximum percentage by which a stock's price can change every tick (a tick occurs every few seconds while the game is running).

    A stock's price forecast can change over time. This is also affected by volatility. The more volatile a stock is, the more its price forecast will change."),!1));var l=Object(h.clearEventListeners)("stock-market-buy-4s-tix-api");if(e(l,Object(i.getStockMarket4STixApiCost)(),c.a.has4SDataTixApi,"Buy 4S Market Data TIX API Access - "+p.numeralWrapper.format(Object(i.getStockMarket4STixApiCost)(),"($0.000a)"),"4S Market Data TIX API - Purchased"),c.a.hasTixApiAccess?(l.addEventListener("click",function(){return!c.a.money.lt(Object(i.getStockMarket4STixApiCost)())&&(c.a.has4SDataTixApi=!0,c.a.loseMoney(Object(i.getStockMarket4STixApiCost)()),Y(),!1)}),l.appendChild(Object(y.createElement)("span",{class:"tooltiptext",innerText:"Lets you access 4S Market Data through Netscript"}))):(l.classList.remove("a-link-button"),l.classList.remove("a-link-button-bought"),l.classList.remove("a-link-button-inactive"),l.classList.add("a-link-button-inactive"),l.appendChild(Object(y.createElement)("span",{class:"tooltiptext",innerText:"Requires TIX API Access"}))),null!=(E=document.getElementById("stock-market-list"))){var u=document.getElementById("stock-market-commission"),d=document.getElementById("stock-market-mode"),g=document.getElementById("stock-market-expand-tickers"),_=document.getElementById("stock-market-collapse-tickers"),b=document.getElementById("stock-market-watchlist-filter"),v=document.getElementById("stock-market-watchlist-filter-update");if(!c.a.hasWseAccount){for(K=!1;E.firstChild;)E.removeChild(E.firstChild);return u.style.visibility="hidden",d.style.visibility="hidden",g.style.visibility="hidden",_.style.visibility="hidden",b.style.visibility="hidden",void(v.style.visibility="hidden")}if(u.style.visibility="visible",d.style.visibility="visible",g.style.visibility="visible",_.style.visibility="visible",b.style.visibility="visible",v.style.visibility="visible",!K&&c.a.hasWseAccount){console.log("Creating Stock Market UI"),u.innerHTML="Commission Fees: Every transaction you make has a "+p.numeralWrapper.format(r.CONSTANTS.StockMarketCommission,"($0.000a)")+" commission fee.

    WARNING: When you reset after installing Augmentations, the Stock Market is reset. This means all your positions are lost, so make sure to sell your stocks before installing Augmentations!",Object(h.clearEventListeners)("stock-market-investopedia").addEventListener("click",function(){return Object(m.dialogBoxCreate)("When making a transaction on the stock market, there are two types of positions: Long and Short. A Long position is the typical scenario where you buy a stock and earn a profit if the price of that stock increases. Meanwhile, a Short position is the exact opposite. In a Short position you purchase shares of a stock and earn a profit if the price of that stock decreases. This is also called 'shorting' a stock.

    NOTE: Shorting stocks is not available immediately, and must be unlocked later on in the game.

    There are three different types of orders you can make to buy or sell stocks on the exchange: Market Order, Limit Order, and Stop Order. Note that Limit Orders and Stop Orders are not available immediately, and must be unlocked later on in the game.

    When you place a Market Order to buy or sell a stock, the order executes immediately at whatever the current price of the stock is. For example if you choose to short a stock with 5000 shares using a Market Order, you immediately purchase those 5000 shares in a Short position at whatever the current market price is for that stock.

    A Limit Order is an order that only executes under certain conditions. A Limit Order is used to buy or sell a stock at a specified price or better. For example, lets say you purchased a Long position of 100 shares of some stock at a price of $10 per share. You can place a Limit Order to sell those 100 shares at $50 or better. The Limit Order will execute when the price of the stock reaches a value of $50 or higher.

    A Stop Order is the opposite of a Limit Order. It is used to buy or sell a stock at a specified price (before the price gets 'worse'). For example, lets say you purchased a Short position of 100 shares of some stock at a price of $100 per share. The current price of the stock is $80 (a profit of $20 per share). You can place a Stop Order to sell the Short position if the stock's price reaches $90 or higher. This can be used to lock in your profits and limit any losses.

    Here is a summary of how each order works and when they execute:

    In a LONG Position:

    A Limit Order to buy will execute if the stock's price <= order's price
    A Limit Order to sell will execute if the stock's price >= order's price
    A Stop Order to buy will execute if the stock's price >= order's price
    A Stop Order to sell will execute if the stock's price <= order's price

    In a SHORT Position:

    A Limit Order to buy will execute if the stock's price >= order's price
    A Limit Order to sell will execute if the stock's price <= order's price
    A Stop Order to buy will execute if the stock's price <= order's price
    A Stop Order to sell will execute if the stock's price >= order's price."),!1}),d&&(q=!1,d.innerHTML="Switch to 'Portfolio' ModeDisplays only the stocks for which you have shares or orders",d.addEventListener("click",z));var E=document.getElementById("stock-market-list");g&&g.addEventListener("click",()=>{for(var e=E.getElementsByClassName("accordion-header"),t=0;t{for(var e=E.getElementsByClassName("accordion-header"),t=0;t{let e=b.value.toString();P.watchlistFilter=e.replace(/\s/g,""),q?z():V()}),b.addEventListener("keyup",e=>{e.preventDefault(),e.keyCode===f.KEY.ENTER&&v.click()})):console.warn("Stock Market Watchlist DOM elements could not be found"),J(),K=!0}if(c.a.hasWseAccount)for(var k in P)if(P.hasOwnProperty(k)){var C=P[k];C instanceof a.Stock&&(Z(C,null),te(C))}}}function z(){q=!0;var e=Object(h.clearEventListeners)("stock-market-mode");e&&(e.innerHTML="Switch to 'All stocks' ModeDisplays all stocks on the WSE",e.addEventListener("click",V)),J()}function V(){q=!1;var e=Object(h.clearEventListeners)("stock-market-mode");e&&(e.innerHTML="Switch to 'Portfolio' ModeDisplays only the stocks for which you have shares or orders",e.addEventListener("click",z)),J()}function J(){var e=document.getElementById("stock-market-list");null==e&&Object(g.exceptionAlert)("Error creating Stock Tickers UI. DOM element with ID 'stock-market-list' could not be found"),Object(b.removeChildrenFromElement)(e);var t=P.Orders;if(null==t){var n={};for(var i in P)if(P.hasOwnProperty(i)){if(!((o=P[i])instanceof a.Stock))continue;n[o.symbol]=[]}P.Orders=n,t=P.Orders}let r=null;if(null!=P.watchlistFilter&&""!==P.watchlistFilter){r=P.watchlistFilter.replace(/\s/g,"").split(",")}for(var i in P)if(P.hasOwnProperty(i)){var o;if(!((o=P[i])instanceof a.Stock))continue;if(r&&!r.includes(o.symbol))continue;let e=t[o.symbol];if(q&&0===o.playerShares&&0===o.playerShortShares&&0===e.length)continue;X(o)}Q()}function X(e){if(e instanceof a.Stock){var t="stock-market-ticker-"+e.symbol,n=document.createElement("li"),i=document.createElement("button"),r=document.createElement("pre");i.classList.add("accordion-header"),i.setAttribute("id",t+"-hdr"),r.textContent=e.name+" - "+e.symbol+" - "+p.numeralWrapper.format(e.price,"($0.000a)"),i.appendChild(r);var o=document.createElement("div");o.classList.add("accordion-panel"),o.setAttribute("id",t+"-panel");var l=document.createElement("input"),u=document.createElement("select",{class:"dropdown"}),h=document.createElement("select",{class:"dropdown"}),d=document.createElement("span"),g=document.createElement("span"),_=document.createElement("span"),f=document.createElement("span"),y=document.createElement("p"),b=document.createElement("ul");l.classList.add("stock-market-input"),l.placeholder="Quantity (Shares)",l.setAttribute("id",t+"-qty-input"),l.setAttribute("onkeydown","return ( event.ctrlKey || event.altKey || (4734 && event.keyCode<40) || (event.keyCode==46) )"),u.classList.add("stock-market-input"),u.classList.add("dropdown"),u.setAttribute("id",t+"-pos-selector");var v=document.createElement("option");if(v.text="Long",u.add(v),8===c.a.bitNodeN||s.f&&s.h>=2){var O=document.createElement("option");O.text="Short",u.add(O)}h.classList.add("stock-market-input"),h.classList.add("dropdown"),h.setAttribute("id",t+"-order-selector");var S=document.createElement("option");if(S.text="Market Order",h.add(S),8===c.a.bitNodeN||s.f&&s.h>=3){var M=document.createElement("option");M.text="Limit Order",h.add(M);var P=document.createElement("option");P.text="Stop Order",h.add(P)}d.classList.add("stock-market-input"),d.classList.add("a-link-button"),d.innerHTML="Buy",d.addEventListener("click",()=>{var n=u.options[u.selectedIndex].text;n="Long"===n?C.Long:C.Short;var a=h.options[h.selectedIndex].text,i=Number(document.getElementById(t+"-qty-input").value);if(isNaN(i))return!1;switch(a){case"Market Order":n===C.Long?B(e,i):j(e,i,null);break;case"Limit Order":case"Stop Order":var r=Object(E.yesNoTxtInpBoxGetYesButton)(),o=Object(E.yesNoTxtInpBoxGetNoButton)();r.innerText="Place Buy "+a,o.innerText="Cancel Order",r.addEventListener("click",()=>{var t,r=Number(Object(E.yesNoTxtInpBoxGetInput)());t="Limit Order"===a?k.LimitBuy:k.StopBuy,T(e,i,r,t,n),Object(E.yesNoTxtInpBoxClose)()}),o.addEventListener("click",()=>{Object(E.yesNoTxtInpBoxClose)()}),Object(E.yesNoTxtInpBoxCreate)("Enter the price for your "+a);break;default:console.log("ERROR: Invalid order type")}return!1}),g.classList.add("stock-market-input"),g.classList.add("a-link-button"),g.innerHTML="Sell",g.addEventListener("click",()=>{var n=u.options[u.selectedIndex].text;n="Long"===n?C.Long:C.Short;var a=h.options[h.selectedIndex].text,i=Number(document.getElementById(t+"-qty-input").value);if(isNaN(i))return!1;switch(a){case"Market Order":n===C.Long?W(e,i):F(e,i,null);break;case"Limit Order":case"Stop Order":var r=Object(E.yesNoTxtInpBoxGetYesButton)(),o=Object(E.yesNoTxtInpBoxGetNoButton)();r.innerText="Place Sell "+a,o.innerText="Cancel Order",r.addEventListener("click",()=>{var t,r=Number(Object(E.yesNoTxtInpBoxGetInput)());t="Limit Order"===a?k.LimitSell:k.StopSell,Object(E.yesNoTxtInpBoxClose)(),T(e,i,r,t,n)}),o.addEventListener("click",()=>{Object(E.yesNoTxtInpBoxClose)()}),Object(E.yesNoTxtInpBoxCreate)("Enter the price for your "+a);break;default:console.log("ERROR: Invalid order type")}return!1}),_.classList.add("stock-market-input"),_.classList.add("a-link-button"),_.innerHTML="Buy MAX",_.addEventListener("click",()=>{var t=u.options[u.selectedIndex].text;t="Long"===t?C.Long:C.Short;var n=h.options[h.selectedIndex].text,a=c.a.money.toNumber();switch(n){case"Market Order":var i=Math.floor((a-$)/e.price);i=Math.min(i,Math.round(e.maxShares-e.playerShares-e.playerShortShares)),t===C.Long?B(e,i):j(e,i,null);break;case"Limit Order":case"Stop Order":var r=Object(E.yesNoTxtInpBoxGetYesButton)(),o=Object(E.yesNoTxtInpBoxGetNoButton)();r.innerText="Place Buy "+n,o.innerText="Cancel Order",r.addEventListener("click",()=>{var i,r=Number(Object(E.yesNoTxtInpBoxGetInput)());i="Limit Order"===n?k.LimitBuy:k.StopBuy;var o=Math.floor((a-$)/r);o=Math.min(o,Math.round(e.maxShares-e.playerShares-e.playerShortShares)),T(e,o,r,i,t),Object(E.yesNoTxtInpBoxClose)()}),o.addEventListener("click",()=>{Object(E.yesNoTxtInpBoxClose)()}),Object(E.yesNoTxtInpBoxCreate)("Enter the price for your "+n);break;default:console.log("ERROR: Invalid order type")}return!1}),f.classList.add("stock-market-input"),f.classList.add("a-link-button"),f.innerHTML="Sell ALL",f.addEventListener("click",()=>{var t=u.options[u.selectedIndex].text;switch(t="Long"===t?C.Long:C.Short,h.options[h.selectedIndex].text){case"Market Order":if(t===C.Long){var n=e.playerShares;W(e,n)}else{n=e.playerShortShares;F(e,n,null)}break;case"Limit Order":case"Stop Order":Object(m.dialogBoxCreate)("ERROR: 'Sell All' only works for Market Orders");break;default:console.log("ERROR: Invalid order type")}return!1}),y.setAttribute("id",t+"-position-text"),y.classList.add("stock-market-position-text"),e.posTxtEl=y,b.setAttribute("id",t+"-order-list"),b.classList.add("stock-market-order-list"),o.appendChild(l),o.appendChild(u),o.appendChild(h),o.appendChild(d),o.appendChild(g),o.appendChild(_),o.appendChild(f),o.appendChild(y),o.appendChild(b),n.appendChild(i),n.appendChild(o),document.getElementById("stock-market-list").appendChild(n),Z(e,!0),ee(e),te(e)}else console.log("Invalid stock in createStockSticker()")}function Q(){var e=document.getElementById("stock-market-list").getElementsByClassName("accordion-header");if(null!=e)for(var t=0;t0||e.playerShortShares>0)&&ee(e);var i=document.getElementById(n+"-hdr");if(null==i){if(!q){let t=P.watchlistFilter;""!==t&&t.includes(e.symbol)&&console.log("ERROR: Couldn't find ticker element for stock: "+e.symbol)}return}const r=p.numeralWrapper.format(e.price,"($0.000a)");let o=`${e.name}${" ".repeat(1+x.longestName-e.name.length+(x.longestSymbol-e.symbol.length))}${e.symbol} -${" ".repeat(10-r.length)}${r}`;c.a.has4SData&&(o+=` - Volatility: ${p.numeralWrapper.format(e.mv,"0,0.00")}% - Price Forecast: `,o+=(e.b?"+":"-").repeat(Math.floor(e.otlkMag/10)+1)),i.firstChild.textContent=o,null!=t&&(i.firstChild.style.color=t?"#66ff33":"red")}function ee(e){if(!u.routing.isOn(u.Page.StockMarket))return;if(!(e instanceof a.Stock))return console.log("Invalid stock in updateStockPlayerPosition():"),void console.log(e);var t="stock-market-ticker-"+e.symbol;if(q){if(0===e.playerShares&&0===e.playerShortShares&&P.Orders&&P.Orders[e.symbol]&&0===P.Orders[e.symbol].length)return Object(v.removeElementById)(t+"-hdr"),void Object(v.removeElementById)(t+"-panel");if(null==document.getElementById(t+"-hdr"))return X(e),void Q()}if(e.posTxtEl instanceof Element||(e.posTxtEl=document.getElementById(t+"-position-text")),null==e.posTxtEl)return void console.log("ERROR: Could not find stock position element for: "+e.symbol);const n=e.playerShares*e.playerAvgPx;let i=(e.price-e.playerAvgPx)*e.playerShares,r=i/n;isNaN(r)&&(r=0);const o=e.playerShortShares*e.playerAvgShortPx;let l=(e.playerAvgShortPx-e.price)*e.playerShortShares,m=l/o;isNaN(m)&&(m=0),e.posTxtEl.innerHTML=`Max Shares: ${p.numeralWrapper.format(e.maxShares,"0.000a")}
    `+"

    Long Position: Shares in the long position will increase in value if the price of the corresponding stock increases


    Shares: "+p.numeralWrapper.format(e.playerShares,"0,0")+"
    Average Price: "+p.numeralWrapper.format(e.playerAvgPx,"$0.000a")+" (Total Cost: "+p.numeralWrapper.format(n,"$0.000a")+")
    Profit: "+p.numeralWrapper.format(i,"$0.000a")+" ("+p.numeralWrapper.format(r,"0.00%")+")
    ",(8===c.a.bitNodeN||s.f&&s.h>=2)&&(e.posTxtEl.innerHTML+="

    Short Position: Shares in short position will increase in value if the price of the corresponding stock decreases


    Shares: "+p.numeralWrapper.format(e.playerShortShares,"0,0")+"
    Average Price: "+p.numeralWrapper.formatMoney(e.playerAvgShortPx)+" (Total Cost: "+p.numeralWrapper.formatMoney(o)+")
    Profit: "+p.numeralWrapper.formatMoney(l)+" ("+p.numeralWrapper.format(m,"0.00%")+")

    Orders:

    ")}function te(e){if(u.routing.isOn(u.Page.StockMarket)){var t="stock-market-ticker-"+e.symbol,n=document.getElementById(t+"-order-list");if(null!=n){var a=P.Orders;if(null!=a){var i=a[e.symbol];if(null!=i){if(q){if(0===e.playerShares&&0===e.playerShortShares&&P.Orders&&P.Orders[e.symbol]&&0===P.Orders[e.symbol].length)return Object(v.removeElementById)(t+"-hdr"),void Object(v.removeElementById)(t+"-panel");if(null==document.getElementById(t+"-hdr"))return X(e),void Q()}for(;n.firstChild;)n.removeChild(n.firstChild);for(var r=0;r
    automate [var] [val] [hi/low] Configure simple automation for Bladeburner tasks
    clear/cls Clear the console
    help [cmd] Display this help text, or help text for a specific command
    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
    ",automate:'automate [var] [val] [hi/low]

    A simple way to automate your Bladeburner actions. This console command can be used to automatically start an action when your stamina rises above a certain threshold, and automatically switch to another action when your stamina drops below another threshold.

    automate status - Check the current status of your automation and get a brief description of what it\'ll do
    automate en - Enable the automation feature
    automate dis - Disable the automation feature

    There are four properties that must be set for this automation to work properly. Here is how to set them:

    automate stamina 100 high
    automate contract Tracking high
    automate stamina 50 low
    automate general "Field Analysis" low

    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.',clear:"clear

    Clears the console",cls:"cls

    Clears the console",help:"help [command]

    Running 'help' with no arguments displays the general help text, which lists all console commands and a brief description of what they do. A command can be specified to get more specific help text about that particular command. For example:

    help automate

    will display specific information about using the automate console command",log:"log [en/dis] [type]

    Enable or disable logging. By default, the results of completing actions such as contracts/operations are logged in the console. There are also random events that are logged in the console as well. The five categories of things that get logged are:

    [general, contracts, ops, blackops, events]

    The logging for these categories can be enabled or disabled like so:

    log dis contracts - Disables logging that occurs when contracts are completed
    log en contracts - Enables logging that occurs when contracts are completed
    log dis events - Disables logging for Bladeburner random events

    Logging can be universally enabled/disabled using the 'all' keyword:

    log dis all
    log en all",skill:'skill [action] [name]

    Level or display information about your skills.

    To display information about all of your skills and your multipliers, use:

    skill list

    To display information about a specific skill, specify the name of the skill afterwards. Note that the name of the skill is case-sensitive. Enter it exactly as seen in the UI. If the name of the skill has whitespace, enclose the name of the skill in double quotation marks:

    skill list Reaper
    skill list "Digital Observer"

    This console command can also be used to level up skills:

    skill level [skill name]',start:'start [type] [name]

    Start an action. An action is specified by its type and its name. The name is case-sensitive. It must appear exactly as it does in the UI. If the name of the action has whitespace, enclose it in double quotation marks. Valid action types include:

    [general, contract, op, blackop]

    Examples:

    start contract Tracking
    start op "Undercover Operation"
    ',stop:"stop

    Stop your current action and go idle"};function F(e={}){this.name=e.name?e.name:p.Locations.Sector12,this.pop=e.pop?e.pop:Object(A.getRandomInt)(D,1.5*D),this.popEst=this.pop*(Math.random()+.5),this.comms=e.comms?e.comms:Object(A.getRandomInt)(5,150),this.commsEst=this.comms+Object(A.getRandomInt)(-5,5),this.commsEst<0&&(this.commsEst=0),this.chaos=0}function U(e={name:"foo",desc:"foo"}){if(!e.name)throw new Error("Failed to initialize Bladeburner Skill. No name was specified in ctor");if(this.name=e.name,!e.desc)throw new Error("Failed to initialize Bladeburner Skills. No desc was specified in ctor");this.desc=e.desc,this.baseCost=e.baseCost?e.baseCost:1,this.costInc=e.costInc?e.costInc:1,e.maxLvl&&(this.maxLvl=e.maxLvl),e.successChanceAll&&(this.successChanceAll=e.successChanceAll),e.successChanceStealth&&(this.successChanceStealth=e.successChanceStealth),e.successChanceKill&&(this.successChanceKill=e.successChanceKill),e.successChanceContract&&(this.successChanceContract=e.successChanceContract),e.successChanceOperation&&(this.successChanceOperation=e.successChanceOperation),e.successChanceEstimate&&(this.successChanceEstimate=e.successChanceEstimate),e.actionTime&&(this.actionTime=e.actionTime),e.effHack&&(this.effHack=e.effHack),e.effStr&&(this.effStr=e.effStr),e.effDef&&(this.effDef=e.effDef),e.effDex&&(this.effDex=e.effDex),e.effAgi&&(this.effAgi=e.effAgi),e.effCha&&(this.effCha=e.effCha),e.stamina&&(this.stamina=e.stamina),e.money&&(this.money=e.money),e.expGain&&(this.expGain=e.expGain),e.weaponAbility&&(this.weaponAbility=e.weaponAbility),e.gunAbility&&(this.gunAbility=e.gunAbility)}e(document).keydown(function(e){if(S.routing.isOn(S.Page.Bladeburner)){if(!(m.a.bladeburner instanceof Q))return;let r=m.a.bladeburner.consoleHistory;if(e.keyCode===_.KEY.ENTER){e.preventDefault();var t=Z.consoleInput.value;t.length>0&&(m.a.bladeburner.postToConsole("> "+t),m.a.bladeburner.resetConsoleInput(),m.a.bladeburner.executeConsoleCommands(t))}if(e.keyCode===_.KEY.UPARROW){if(null==Z.consoleInput)return;var n=W;if(0===(i=r.length))return;(n<0||n>i)&&(W=i),0!==n&&--W;var a=r[W];Z.consoleInput.value=a,Object(g.setTimeoutRef)(function(){Z.consoleInput.selectionStart=Z.consoleInput.selectionEnd=1e4},0)}if(e.keyCode===_.KEY.DOWNARROW){if(null==Z.consoleInput)return;var i;n=W;if(0==(i=r.length))return;if((n<0||n>i)&&(W=i),n==i||n==i-1)W=i,Z.consoleInput.value="";else{a=r[++W];Z.consoleInput.value=a}}}}),F.prototype.improvePopulationEstimateByCount=function(e){if(isNaN(e))throw new Error("NaN passeed into City.improvePopulationEstimateByCount()");this.popEstthis.pop&&(this.popEst=this.pop)):this.popEst>this.pop&&(this.popEst-=e,this.popEstthis.pop&&(this.popEst=this.pop)):this.popEst>this.pop&&(this.popEst*=1-e/100,this.popEstthis.comms&&(this.commsEst=this.comms)):this.commsEst>this.comms&&(this.commsEst-=e,this.commsEst0?1:-1),this.pop+=n,t.changeEstEqually&&(this.popEst+=n,this.popEst<0&&(this.popEst=0)),n}},F.prototype.changeChaosByCount=function(e){if(isNaN(e))throw new Error("NaN passed into City.changeChaosByCount()");0!==e&&(this.chaos+=e,this.chaos<0&&(this.chaos=0))},F.prototype.changeChaosByPercentage=function(e){if(isNaN(e))throw new Error("NaN passed into City.chaosChaosByPercentage()");if(0!==e){var t=this.chaos*(e/100);this.chaos+=t,this.chaos<0&&(this.chaos=0)}},F.prototype.toJSON=function(){return Object(v.Generic_toJSON)("City",this)},F.fromJSON=function(e){return Object(v.Generic_fromJSON)(F,e.data)},v.Reviver.constructors.City=F,U.prototype.calculateCost=function(e){return Math.floor((this.baseCost+e*this.costInc)*r.BitNodeMultipliers.BladeburnerSkillCost)};var H={},G={BladesIntuition:"Blade's Intuition",Cloak:"Cloak",Marksman:"Marksman",WeaponProficiency:"Weapon Proficiency",ShortCircuit:"Short-Circuit",DigitalObserver:"Digital Observer",Tracer:"Tracer",Overclock:"Overclock",Reaper:"Reaper",EvasiveSystem:"Evasive System",Datamancer:"Datamancer",CybersEdge:"Cyber's Edge",HandsOfMidas:"Hands of Midas",Hyperdrive:"Hyperdrive"};function K(e={}){this.name=e.name?e.name:"",this.desc=e.desc?e.desc:"",this.level=1,this.maxLevel=1,this.autoLevel=!0,this.baseDifficulty=e.baseDifficulty?Object(E.addOffset)(e.baseDifficulty,10):100,this.difficultyFac=e.difficultyFac?e.difficultyFac:1.01,this.rewardFac=e.rewardFac?e.rewardFac:1.02,this.successes=0,this.failures=0,this.rankGain=e.rankGain?e.rankGain:0,e.rankLoss&&(this.rankLoss=e.rankLoss),e.hpLoss&&(this.hpLoss=e.hpLoss,this.hpLost=0),this.isStealth=!!e.isStealth,this.isKill=!!e.isKill,this.count=e.count?e.count:Object(A.getRandomInt)(1e3,25e3),this.countGrowth=e.countGrowth?e.countGrowth:Object(A.getRandomInt)(1,5);this.weights=e.weights?e.weights:{hack:1/7,str:1/7,def:1/7,dex:1/7,agi:1/7,cha:1/7,int:1/7};var t=0;for(var n in this.weights)this.weights.hasOwnProperty(n)&&(t+=this.weights[n]);if(t-1>=10*Number.EPSILON)throw new Error("Invalid weights when constructing Action "+this.name+". The weights should sum up to 1. They sum up to :1");for(var a in this.decays=e.decays?e.decays:{hack:.9,str:.9,def:.9,dex:.9,agi:.9,cha:.9,int:.9},this.decays)if(this.decays.hasOwnProperty(a)&&this.decays[a]>1)throw new Error("Invalid decays when constructing Action "+this.name+". Decay value cannot be greater than 1")}K.prototype.getDifficulty=function(){var e=this.baseDifficulty*Math.pow(this.difficultyFac,this.level-1);if(isNaN(e))throw new Error("Calculated NaN in Action.getDifficulty()");return e},K.prototype.getSuccessChance=function(e,t={}){if(null==e)throw new Error("Invalid Bladeburner instance passed into Action.getSuccessChance");var n=this.getDifficulty(),a=0;for(var i in this.weights)if(this.weights.hasOwnProperty(i)){var r=m.a.queryStatFromString(i),o="eff"+i.charAt(0).toUpperCase()+i.slice(1),s=e.skillMultipliers[o];null==s&&(console.log("ERROR: Failed to find Bladeburner Skill multiplier for: "+i),s=1),a+=this.weights[i]*Math.pow(s*r,this.decays[i])}(a*=e.calculateStaminaPenalty(),this instanceof V||this instanceof J)&&(this.teamCount&&this.teamCount>0&&(this.teamCount=Math.min(this.teamCount,e.teamSize),a*=Math.pow(this.teamCount,.05)));if(!(this instanceof J)){var l=e.getCurrentCity();if(t.est?a*=Math.pow(l.popEst/D,.7):a*=Math.pow(l.pop/D,.7),l.chaos>50){var c=l.chaos-50+1;n*=Math.pow(c,.1)}if(this instanceof V&&"Raid"===this.name&&l.comms<=0)return 0}if(a*=e.skillMultipliers.successChanceAll,(this instanceof V||this instanceof J)&&(a*=e.skillMultipliers.successChanceOperation),this instanceof z&&(a*=e.skillMultipliers.successChanceContract),this.isStealth&&(a*=e.skillMultipliers.successChanceStealth),this.isKill&&(a*=e.skillMultipliers.successChanceKill),a*=m.a.bladeburner_success_chance_mult,isNaN(a))throw new Error("Competence calculated as NaN in Action.getSuccessChance()");return Math.min(1,a/n)},K.prototype.attempt=function(e){return Math.random()=this.getSuccessesNeededForNextLevel(e)&&++this.maxLevel},K.prototype.toJSON=function(){return Object(v.Generic_toJSON)("Action",this)},K.fromJSON=function(e){return Object(v.Generic_fromJSON)(K,e.data)},v.Reviver.constructors.Action=K;var q={};const $=Object.freeze({Idle:1,Contract:2,Operation:3,BlackOp:4,BlackOperation:4,Training:5,Recruitment:6,FieldAnalysis:7,"Field Analysis":7,Diplomacy:8,"Hyperbolic Regeneration Chamber":9});function Y(e={}){e.name&&(this.name=e.name),e.type&&(this.type=e.type)}function z(e={}){K.call(this,e)}function V(e={}){K.call(this,e),this.reqdRank=e.reqdRank?e.reqdRank:100,this.teamCount=e.teamCount?e.teamCount:0}function J(e={}){V.call(this,e),this.count=1,this.countGrowth=0}Y.prototype.toJSON=function(){return Object(v.Generic_toJSON)("ActionIdentifier",this)},Y.fromJSON=function(e){return Object(v.Generic_fromJSON)(Y,e.data)},v.Reviver.constructors.ActionIdentifier=Y,z.prototype=Object.create(K.prototype),z.prototype.toJSON=function(){return Object(v.Generic_toJSON)("Contract",this)},z.fromJSON=function(e){return Object(v.Generic_fromJSON)(z,e.data)},v.Reviver.constructors.Contract=z,V.prototype=Object.create(K.prototype),V.prototype.toJSON=function(){return Object(v.Generic_toJSON)("Operation",this)},V.fromJSON=function(e){return Object(v.Generic_fromJSON)(V,e.data)},v.Reviver.constructors.Operation=V,J.prototype=Object.create(K.prototype),J.prototype.toJSON=function(){return Object(v.Generic_toJSON)("BlackOperation",this)},J.fromJSON=function(e){return Object(v.Generic_fromJSON)(J,e.data)},v.Reviver.constructors.BlackOperation=J;var X={};function Q(e={}){this.numHosp=0,this.moneyLost=0,this.rank=0,this.maxRank=0,this.skillPoints=0,this.totalSkillPoints=0,this.teamSize=0,this.teamLost=0,this.storedCycles=0,this.randomEventCounter=Object(A.getRandomInt)(240,600),this.actionTimeToComplete=0,this.actionTimeCurrent=0;var t=$.Idle;this.action=new Y({type:t}),this.cities={};for(var n=0;n
    Does NOT require stamina."}),q[e="Recruitment"]=new K({name:e,desc:"Attempt to recruit members for your Bladeburner team. These members can help you conduct operations.

    Does NOT require stamina."}),q[e="Diplomacy"]=new K({name:e,desc:"Improve diplomatic relations with the Synthoid population. Completing this action will reduce the Chaos level in your current city.

    Does NOT require stamina."}),q[e="Hyperbolic Regeneration Chamber"]=new K({name:e,desc:"Enter cryogenic stasis using the Bladeburner division's hi-tech Regeneration Chamber. This will slowly heal your wounds and slightly increase your stamina.

    "}),X["Operation Typhoon"]=new J({name:"Operation Typhoon",desc:"Obadiah Zenyatta is the leader of a RedWater PMC. It has long been known among the intelligence community that Zenyatta, along with the rest of the PMC, is a Synthoid.

    The goal of Operation Typhoon is to find and eliminate Zenyatta and RedWater by any means necessary. After the task is completed, the actions must be covered up from the general public.",baseDifficulty:2e3,reqdRank:2500,rankGain:50,rankLoss:10,hpLoss:100,weights:{hack:.1,str:.2,def:.2,dex:.2,agi:.2,cha:0,int:.1},decays:{hack:.6,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75},isKill:!0}),X["Operation Zero"]=new J({name:"Operation Zero",desc:"AeroCorp is one of the world's largest defense contractors. It's leader, Steve Watataki, is thought to be a supporter of Synthoid rights. He must be removed.

    The goal of Operation Zero is to covertly infiltrate AeroCorp and uncover any incriminating evidence or information against Watataki that will cause him to be removed from his position at AeroCorp. Incriminating evidence can be fabricated as a last resort. Be warned that AeroCorp has some of the most advanced security measures in the world.",baseDifficulty:2500,reqdRank:5e3,rankGain:60,rankLoss:15,hpLoss:50,weights:{hack:.2,str:.15,def:.15,dex:.2,agi:.2,cha:0,int:.1},decays:{hack:.6,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75},isStealth:!0}),X["Operation X"]=new J({name:"Operation X",desc:"We have recently discovered an underground publication group called Samizdat. Even though most of their publications are nonsensical conspiracy theories, the average human is gullible enough to believe them. Many of their works discuss Synthoids and pose a threat to society. The publications are spreading rapidly in China and other Eastern countries.

    Samizdat has done a good job of keeping hidden and anonymous. However, we've just received intelligence that their base of operations is in Ishima's underground sewer systems. Your task is to investigate the sewer systems, and eliminate Samizdat. They must never publish anything again.",baseDifficulty:3e3,reqdRank:7500,rankGain:75,rankLoss:15,hpLoss:100,weights:{hack:.1,str:.2,def:.2,dex:.2,agi:.2,cha:0,int:.1},decays:{hack:.6,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75},isKill:!0}),X["Operation Titan"]=new J({name:"Operation Titan",desc:"Several months ago Titan Laboratories' Bioengineering department was infiltrated by Synthoids. As far as we know, Titan Laboratories' management has no knowledge about this. We don't know what the Synthoids are up to, but the research that they could be conducting using Titan Laboraties' vast resources is potentially very dangerous.

    Your goal is to enter and destroy the Bioengineering department's facility in Aevum. The task is not just to retire the Synthoids there, but also to destroy any information or research at the facility that is relevant to the Synthoids and their goals.",baseDifficulty:4e3,reqdRank:1e4,rankGain:100,rankLoss:20,hpLoss:100,weights:{hack:.1,str:.2,def:.2,dex:.2,agi:.2,cha:0,int:.1},decays:{hack:.6,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75},isKill:!0}),X["Operation Ares"]=new J({name:"Operation Ares",desc:"One of our undercover agents, Agent Carter, has informed us of a massive weapons deal going down in Dubai between rogue Russian militants and a radical Synthoid community. These weapons are next-gen plasma and energy weapons. It is critical for the safety of humanity that this deal does not happen.

    Your task is to intercept the deal. Leave no survivors.",baseDifficulty:5e3,reqdRank:12500,rankGain:125,rankLoss:20,hpLoss:200,weights:{hack:0,str:.25,def:.25,dex:.25,agi:.25,cha:0,int:0},decays:{hack:0,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75},isKill:!0}),X["Operation Archangel"]=new J({name:"Operation Archangel",desc:"Our analysts have discovered that the popular Red Rabbit brothel in Amsterdam is run and 'staffed' by MK-VI Synthoids. Intelligence suggests that the profit from this brothel is used to fund a large black market arms trafficking operation.

    The goal of this operation is to take out the leaders that are running the Red Rabbit brothel. Try to limit the number of other casualties, but do what you must to complete the mission.",baseDifficulty:7500,reqdRank:15e3,rankGain:200,rankLoss:20,hpLoss:25,weights:{hack:0,str:.2,def:.2,dex:.3,agi:.3,cha:0,int:0},decays:{hack:0,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75},isKill:!0}),X["Operation Juggernaut"]=new J({name:"Operation Juggernaut",desc:"The CIA has just encountered a new security threat. A new criminal group, lead by a shadowy operative who calls himself Juggernaut, has been smuggling drugs and weapons (including suspected bioweapons) into Sector-12. We also have reason to believe the tried to break into one of Universal Energy's facilities in order to cause a city-wide blackout. The CIA suspects that Juggernaut is a heavily-augmented Synthoid, and have thus enlisted our help.

    Your mission is to eradicate Juggernaut and his followers.",baseDifficulty:1e4,reqdRank:2e4,rankGain:300,rankLoss:40,hpLoss:300,weights:{hack:0,str:.25,def:.25,dex:.25,agi:.25,cha:0,int:0},decays:{hack:0,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75},isKill:!0}),X["Operation Red Dragon"]=new J({name:"Operation Red Dragon",desc:"The Tetrads criminal organization is suspected of reverse-engineering the MK-VI Synthoid design. We believe they altered and possibly improved the design and began manufacturing their own Synthoid models in order to bolster their criminal activities.

    Your task is to infiltrate and destroy the Tetrads' base of operations in Los Angeles. Intelligence tells us that their base houses one of their Synthoid manufacturing units.",baseDifficulty:12500,reqdRank:25e3,rankGain:500,rankLoss:50,hpLoss:500,weights:{hack:.05,str:.2,def:.2,dex:.25,agi:.25,cha:0,int:.05},decays:{hack:.6,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75},isKill:!0}),X["Operation K"]=new J({name:"Operation K",desc:"CODE RED SITUATION. Our intelligence tells us that VitaLife has discovered a new android cloning technology. This technology is supposedly capable of cloning Synthoid, not only physically but also their advanced AI modules. We do not believe that VitaLife is trying to use this technology illegally or maliciously, but if any Synthoids were able to infiltrate the corporation and take advantage of this technology then the results would be catastrophic.

    We do not have the power or jurisdiction to shutdown this down through legal or political means, so we must resort to a covert operation. Your goal is to destroy this technology and eliminateanyone who was involved in its creation.",baseDifficulty:15e3,reqdRank:3e4,rankGain:750,rankLoss:60,hpLoss:1e3,weights:{hack:.05,str:.2,def:.2,dex:.25,agi:.25,cha:0,int:.05},decays:{hack:.6,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75},isKill:!0}),X["Operation Deckard"]=new J({name:"Operation Deckard",desc:"Despite your success in eliminating VitaLife's new android-replicating technology in Operation K, we've discovered that a small group of MK-VI Synthoids were able to make off with the schematics and design of the technology before the Operation. It is almost a certainty that these Synthoids are some of the rogue MK-VI ones from the Synthoid Uprising.The goal of Operation Deckard is to hunt down these Synthoids and retire them. I don't need to tell you how critical this mission is.",baseDifficulty:2e4,reqdRank:4e4,rankGain:1e3,rankLoss:75,hpLoss:200,weights:{hack:0,str:.24,def:.24,dex:.24,agi:.24,cha:0,int:.04},decays:{hack:0,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75},isKill:!0}),X["Operation Tyrell"]=new J({name:"Operation Tyrell",desc:"A week ago Blade Industries reported a small break-in at one of their Aevum Augmentation storage facitilities. We figured out that The Dark Army was behind the heist, and didn't think any more of it. However, we've just discovered that several known MK-VI Synthoids were part of that break-in group.

    We cannot have Synthoids upgrading their already-enhanced abilities with Augmentations. Your task is to hunt down the associated Dark Army members and eliminate them.",baseDifficulty:25e3,reqdRank:5e4,rankGain:1500,rankLoss:100,hpLoss:500,weights:{hack:.1,str:.2,def:.2,dex:.2,agi:.2,cha:0,int:.1},decays:{hack:.6,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75},isKill:!0}),X["Operation Wallace"]=new J({name:"Operation Wallace",desc:"Based on information gathered from Operation Tyrell, we've discovered that The Dark Army was well aware that there were Synthoids amongst their ranks. Even worse, we believe that The Dark Army is working together with other criminal organizations such as The Syndicate and that they are planning some sort of large-scale takeover of multiple major cities, most notably Aevum. We suspect that Synthoids have infiltrated the ranks of these criminal factions and are trying to stage another Synthoid uprising.

    The best way to deal with this is to prevent it before it even happens. The goal of Operation Wallace is to destroy the Dark Army and Syndicate factions in Aevum immediately. Leave no survivors.",baseDifficulty:3e4,reqdRank:75e3,rankGain:2e3,rankLoss:150,hpLoss:1500,weights:{hack:0,str:.24,def:.24,dex:.24,agi:.24,cha:0,int:.04},decays:{hack:.6,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75},isKill:!0}),X["Operation Shoulder of Orion"]=new J({name:"Operation Shoulder of Orion",desc:"China's Solaris Space Systems is secretly launching the first manned spacecraft in over a decade using Synthoids. We believe China is trying to establish the first off-world colonies.

    The mission is to prevent this launch without instigating an international conflict. When you accept this mission you will be officially disavowed by the NSA and the national government until after you successfully return. In the event of failure, all of the operation's team members must not let themselves be captured alive.",baseDifficulty:35e3,reqdRank:1e5,rankGain:2500,rankLoss:500,hpLoss:1500,weights:{hack:.1,str:.2,def:.2,dex:.2,agi:.2,cha:0,int:.1},decays:{hack:.6,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75},isStealth:!0}),X["Operation Hyron"]=new J({name:"Operation Hyron",desc:"Our intelligence tells us that Fulcrum Technologies is developing a quantum supercomputer using human brains as core processors. This supercomputer is rumored to be able to store vast amounts of data and perform computations unmatched by any other supercomputer on the planet. But more importantly, the use of organic human brains means that the supercomputer may be able to reason abstractly and become self-aware.

    I do not need to remind you why sentient-level AIs pose a serious thread to all of mankind.

    The research for this project is being conducted at one of Fulcrum Technologies secret facilities in Aevum, codenamed 'Alpha Ranch'. Infiltrate the compound, delete and destroy the work, and then find and kill the project lead.",baseDifficulty:4e4,reqdRank:125e3,rankGain:3e3,rankLoss:1e3,hpLoss:500,weights:{hack:.1,str:.2,def:.2,dex:.2,agi:.2,cha:0,int:.1},decays:{hack:.6,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75},isKill:!0}),X["Operation Morpheus"]=new J({name:"Operation Morpheus",desc:"DreamSense Technologies is an advertising company that uses special technology to transmit their ads into the peoples dreams and subconcious. They do this using broadcast transmitter towers. Based on information from our agents and informants in Chonqging, we have reason to believe that one of the broadcast towers there has been compromised by Synthoids and is being used to spread pro-Synthoid propaganda.

    The mission is to destroy this broadcast tower. Speed and stealth are of the upmost important for this.",baseDifficulty:45e3,reqdRank:15e4,rankGain:4e3,rankLoss:1e3,hpLoss:100,weights:{hack:.05,str:.15,def:.15,dex:.3,agi:.3,cha:0,int:.05},decays:{hack:.6,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75},isStealth:!0}),X["Operation Ion Storm"]=new J({name:"Operation Ion Storm",desc:"Our analysts have uncovered a gathering of MK-VI Synthoids that have taken up residence in the Sector-12 Slums. We don't know if they are rogue Synthoids from the Uprising, but we do know that they have been stockpiling weapons, money, and other resources. This makes them dangerous.

    This is a full-scale assault operation to find and retire all of these Synthoids in the Sector-12 Slums.",baseDifficulty:5e4,reqdRank:175e3,rankGain:5e3,rankLoss:1e3,hpLoss:5e3,weights:{hack:0,str:.24,def:.24,dex:.24,agi:.24,cha:0,int:.04},decays:{hack:.6,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75},isKill:!0}),X["Operation Annihilus"]=new J({name:"Operation Annihilus",desc:"Our superiors have ordered us to eradicate everything and everyone in an underground facility located in Aevum. They tell us that the facility houses many dangerous Synthoids and belongs to a terrorist organization called 'The Covenant'. We have no prior intelligence about this organization, so you are going in blind.",baseDifficulty:55e3,reqdRank:2e5,rankGain:7500,rankLoss:1e3,hpLoss:1e4,weights:{hack:0,str:.24,def:.24,dex:.24,agi:.24,cha:0,int:.04},decays:{hack:.6,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75},isKill:!0}),X["Operation Ultron"]=new J({name:"Operation Ultron",desc:"OmniTek Incorporated, the original designer and manufacturer of Synthoids, has notified us of a malfunction in their AI design. This malfunction, when triggered, causes MK-VI Synthoids to become radicalized and seek out the destruction of humanity. They say that this bug affects all MK-VI Synthoids, not just the rogue ones from the Uprising.

    OmniTek has also told us they they believe someone has triggered this malfunction in a large group of MK-VI Synthoids, and that these newly-radicalized Synthoids are now amassing in Volhaven to form a terrorist group called Ultron.

    Intelligence suggests Ultron is heavily armed and that their members are augmented. We believe Ultron is making moves to take control of and weaponize DeltaOne's Tactical High-Energy Satellite Laser Array (THESLA).

    Your task is to find and destroy Ultron.",baseDifficulty:6e4,reqdRank:25e4,rankGain:1e4,rankLoss:2e3,hpLoss:1e4,weights:{hack:.1,str:.2,def:.2,dex:.2,agi:.2,cha:0,int:.1},decays:{hack:.6,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75},isKill:!0}),X["Operation Centurion"]=new J({name:"Operation Centurion",desc:"D)@#)($M)C0293c40($*)@#D0JUMP3Rm0C<*@#)*$)#02c94830c(#$*D)

    Throughout all of humanity's history, we have relied on technology to survive, conquer, and progress. Its advancement became our primary goal. And at the peak of human civilization technology turned into power. Global, absolute power.

    It seems that the universe is not without a sense of irony.

    D)@#)($M)C0293c40($*)@#D0JUMP3Rm0C<*@#)*$)#02c94830c(#$*D)",baseDifficulty:7e4,reqdRank:3e5,rankGain:15e3,rankLoss:5e3,hpLoss:1e4,weights:{hack:.1,str:.2,def:.2,dex:.2,agi:.2,cha:0,int:.1},decays:{hack:.6,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75}}),X["Operation Vindictus"]=new J({name:"Operation Vindictus",desc:"D)@#)($M)C0293c40($*)@#D0JUMP3Rm0C<*@#)*$)#02c94830c(#$*D)

    The bits are all around us. The daemons that hold the Node together can manifest themselves in many different ways.

    D)@#)($M)C0293c40($*)@#D0JUMP3Rm0C<*@#)*$)#02c94830c(#$*D)",baseDifficulty:75e3,reqdRank:35e4,rankGain:2e4,rankLoss:2e4,hpLoss:2e4,weights:{hack:.1,str:.2,def:.2,dex:.2,agi:.2,cha:0,int:.1},decays:{hack:.6,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75}}),X["Operation Daedalus"]=new J({name:"Operation Daedalus",desc:"Yesterday we obeyed kings and bent our neck to emperors. Today we kneel only to truth.",baseDifficulty:8e4,reqdRank:4e5,rankGain:4e4,rankLoss:1e4,hpLoss:1e5,weights:{hack:.1,str:.2,def:.2,dex:.2,agi:.2,cha:0,int:.1},decays:{hack:.6,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75}})}(),this.initializeDomElementRefs(),e.new&&this.create()}Q.prototype.prestige=function(){this.resetAction();var e=c.Factions.Bladeburners;this.rank>=25&&Object(u.c)(e)},Q.prototype.create=function(){this.contracts.Tracking=new z({name:"Tracking",desc:"Identify and locate Synthoids. This contract involves reconnaissance and information-gathering ONLY. Do NOT engage. Stealth is of the utmost importance.

    Successfully completing Tracking contracts will slightly improve your Synthoid population estimate for whatever city you are currently in.",baseDifficulty:125,difficultyFac:1.02,rewardFac:1.041,rankGain:.3,hpLoss:.5,count:Object(A.getRandomInt)(25,150),countGrowth:Object(A.getRandomInt)(5,75)/10,weights:{hack:0,str:.05,def:.05,dex:.35,agi:.35,cha:.1,int:.05},decays:{hack:0,str:.91,def:.91,dex:.91,agi:.91,cha:.9,int:1},isStealth:!0}),this.contracts["Bounty Hunter"]=new z({name:"Bounty Hunter",desc:"Hunt down and capture fugitive Synthoids. These Synthoids are wanted alive.

    Successfully completing a Bounty Hunter contract will lower the population in your current city, and will also increase its chaos level.",baseDifficulty:250,difficultyFac:1.04,rewardFac:1.085,rankGain:.9,hpLoss:1,count:Object(A.getRandomInt)(5,150),countGrowth:Object(A.getRandomInt)(5,75)/10,weights:{hack:0,str:.15,def:.15,dex:.25,agi:.25,cha:.1,int:.1},decays:{hack:0,str:.91,def:.91,dex:.91,agi:.91,cha:.8,int:.9},isKill:!0}),this.contracts.Retirement=new z({name:"Retirement",desc:"Hunt down and retire (kill) rogue Synthoids.

    Successfully copmleting a Retirement contract will lower the population in your current city, and will also increase its chaos level.",baseDifficulty:200,difficultyFac:1.03,rewardFac:1.065,rankGain:.6,hpLoss:1,count:Object(A.getRandomInt)(5,150),countGrowth:Object(A.getRandomInt)(5,75)/10,weights:{hack:0,str:.2,def:.2,dex:.2,agi:.2,cha:.1,int:.1},decays:{hack:0,str:.91,def:.91,dex:.91,agi:.91,cha:.8,int:.9},isKill:!0}),this.operations.Investigation=new V({name:"Investigation",desc:"As a field agent, investigate and identify Synthoid populations, movements, and operations.

    Successful Investigation ops will increase the accuracy of your synthoid data.

    You will NOT lose HP from failed Investigation ops.",baseDifficulty:400,difficultyFac:1.03,rewardFac:1.07,reqdRank:25,rankGain:2.2,rankLoss:.2,count:Object(A.getRandomInt)(1,100),countGrowth:Object(A.getRandomInt)(10,40)/10,weights:{hack:.25,str:.05,def:.05,dex:.2,agi:.1,cha:.25,int:.1},decays:{hack:.85,str:.9,def:.9,dex:.9,agi:.9,cha:.7,int:.9},isStealth:!0}),this.operations["Undercover Operation"]=new V({name:"Undercover Operation",desc:"Conduct undercover operations to identify hidden and underground Synthoid communities and organizations.

    Successful Undercover ops will increase the accuracy of your synthoid data.",baseDifficulty:500,difficultyFac:1.04,rewardFac:1.09,reqdRank:100,rankGain:4.4,rankLoss:.4,hpLoss:2,count:Object(A.getRandomInt)(1,100),countGrowth:Object(A.getRandomInt)(10,40)/10,weights:{hack:.2,str:.05,def:.05,dex:.2,agi:.2,cha:.2,int:.1},decays:{hack:.8,str:.9,def:.9,dex:.9,agi:.9,cha:.7,int:.9},isStealth:!0}),this.operations["Sting Operation"]=new V({name:"Sting Operation",desc:"Conduct a sting operation to bait and capture particularly notorious Synthoid criminals.",baseDifficulty:650,difficultyFac:1.04,rewardFac:1.095,reqdRank:500,rankGain:5.5,rankLoss:.5,hpLoss:2.5,count:Object(A.getRandomInt)(1,150),countGrowth:Object(A.getRandomInt)(3,40)/10,weights:{hack:.25,str:.05,def:.05,dex:.25,agi:.1,cha:.2,int:.1},decays:{hack:.8,str:.85,def:.85,dex:.85,agi:.85,cha:.7,int:.9},isStealth:!0}),this.operations.Raid=new V({name:"Raid",desc:"Lead an assault on a known Synthoid community. Note that there must be an existing Synthoid community in your current city in order for this Operation to be successful",baseDifficulty:800,difficultyFac:1.045,rewardFac:1.1,reqdRank:3e3,rankGain:55,rankLoss:2.5,hpLoss:50,count:Object(A.getRandomInt)(1,150),countGrowth:Object(A.getRandomInt)(2,40)/10,weights:{hack:.1,str:.2,def:.2,dex:.2,agi:.2,cha:0,int:.1},decays:{hack:.7,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.9},isKill:!0}),this.operations["Stealth Retirement Operation"]=new V({name:"Stealth Retirement Operation",desc:"Lead a covert operation to retire Synthoids. The objective is to complete the task without drawing any attention. Stealth and discretion are key.",baseDifficulty:1e3,difficultyFac:1.05,rewardFac:1.11,reqdRank:2e4,rankGain:22,rankLoss:2,hpLoss:10,count:Object(A.getRandomInt)(1,150),countGrowth:Object(A.getRandomInt)(1,20)/10,weights:{hack:.1,str:.1,def:.1,dex:.3,agi:.3,cha:0,int:.1},decays:{hack:.7,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.9},isStealth:!0,isKill:!0}),this.operations.Assassination=new V({name:"Assassination",desc:"Assassinate Synthoids that have been identified as important, high-profile social and political leaders in the Synthoid communities.",baseDifficulty:1500,difficultyFac:1.06,rewardFac:1.14,reqdRank:5e4,rankGain:44,rankLoss:4,hpLoss:5,count:Object(A.getRandomInt)(1,150),countGrowth:Object(A.getRandomInt)(1,20)/10,weights:{hack:.1,str:.1,def:.1,dex:.3,agi:.3,cha:0,int:.1},decays:{hack:.6,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.8},isStealth:!0,isKill:!0})},Q.prototype.storeCycles=function(e=1){this.storedCycles+=e},Q.prototype.process=function(){if(!1===h.b&&this.blackops.hasOwnProperty("Operation Daedalus"))return Object(h.a)(m.a.bitNodeN);if(!1===a.Augmentations[i.AugmentationNames.BladesSimulacrum].owned&&m.a.isWorking){if(this.action.type!==$.Idle){let e="Your Bladeburner action was cancelled because you started doing something else.";this.automateEnabled&&(e+="

    Your automation was disabled as well. You will have to re-enable it through the Bladeburner console",this.automateEnabled=!1),Object(y.dialogBoxCreate)(e)}this.resetAction()}if(this.stamina<=0&&(this.log("Your Bladeburner action was cancelled because your stamina hit 0"),this.resetAction()),this.storedCycles>=5){var e=Math.floor(this.storedCycles/5);for(var t in e=Math.min(e,5),this.storedCycles-=5*e,this.calculateMaxStamina(),this.stamina+=this.calculateStaminaGainPerSecond()*e,this.stamina=Math.min(this.maxStamina,this.stamina),this.contracts)if(this.contracts.hasOwnProperty(t)){var n=this.contracts[t];n.count+=e*n.countGrowth/480}for(var r in this.operations)if(this.operations.hasOwnProperty(r)){var o=this.operations[r];o.count+=e*o.countGrowth/480}for(var s=0;s=this.automateThreshHigh&&(this.action.name===this.automateActionHigh.name&&this.action.type===this.automateActionHigh.type||(this.action=new Y({type:this.automateActionHigh.type,name:this.automateActionHigh.name}),this.startAction(this.action)))),S.routing.isOn(S.Page.Bladeburner)&&this.updateContent()}},Q.prototype.calculateMaxStamina=function(){var e=m.a.agility*this.skillMultipliers.effAgi,t=Math.pow(e,.8)+this.staminaBonus;if(t*=this.skillMultipliers.stamina,t*=m.a.bladeburner_max_stamina_mult,isNaN(t))throw new Error("Max Stamina calculated to be NaN in Bladeburner.calculateMaxStamina()");this.maxStamina=t},Q.prototype.calculateStaminaGainPerSecond=function(){var e=m.a.agility*this.skillMultipliers.effAgi;return(.0085+this.maxStamina/7e4)*Math.pow(e,.17)*(this.skillMultipliers.stamina*m.a.bladeburner_stamina_gain_mult)},Q.prototype.calculateStaminaPenalty=function(){return Math.min(1,this.stamina/(.5*this.maxStamina))},Q.prototype.changeRank=function(e){if(isNaN(e))throw new Error("NaN passed into Bladeburner.changeRank()");this.rank+=e,this.rank<0&&(this.rank=0),this.maxRank=Math.max(this.rank,this.maxRank);if(Object(c.factionExists)("Bladeburners")){var t=c.Factions.Bladeburners;if(!(t instanceof l.Faction))throw new Error("Could not properly get Bladeburner Faction object in Bladeburner UI Overview Faction button");if(t.isMember){var n=1+t.favor/100;t.playerReputation+=2*e*m.a.faction_rep_mult*n}}var a=3*(this.totalSkillPoints+1);if(this.maxRank>=a){var i=Math.floor((this.maxRank-a)/3+1);this.skillPoints+=i,this.totalSkillPoints+=i}},Q.prototype.getCurrentCity=function(){var e=this.cities[this.city];if(!(e instanceof F))throw new Error("Bladeburner.getCurrentCity() did not properly return a City object");return e},Q.prototype.resetSkillMultipliers=function(){this.skillMultipliers={successChanceAll:1,successChanceStealth:1,successChanceKill:1,successChanceContract:1,successChanceOperation:1,successChanceEstimate:1,actionTime:1,effHack:1,effStr:1,effDef:1,effDex:1,effAgi:1,effCha:1,effInt:1,stamina:1,money:1,expGain:1,weaponAbility:1,gunAbility:1}},Q.prototype.updateSkillMultipliers=function(){for(var e in this.resetSkillMultipliers(),this.skills)if(this.skills.hasOwnProperty(e)){var t=H[e];if(null==t)throw new Error("Could not find Skill Object for: "+e);var n=this.skills[e];if(null==n||n<=0)continue;for(var a=Object.keys(this.skillMultipliers),i=0;i=this.actionTimeToComplete?this.completeAction():void 0}},Q.prototype.completeAction=function(){switch(this.action.type){case $.Contract:case $.Operation:try{var e=this.action.type===$.Operation;if(null==(p=this.getActionObject(this.action)))throw new Error("Failed to get Contract/Operation Object for: "+this.action.name);var t=p.getDifficulty(),n=Math.pow(t,.28)+t/650,a=Math.pow(p.rewardFac,p.level-1);if(this.stamina-=.285*n,this.stamina<0&&(this.stamina=0),p.attempt(this)){this.gainActionStats(p,!0),++p.successes,--p.count;var i=0;if(e||(i=25e4*a*this.skillMultipliers.money,m.a.gainMoney(i),m.a.recordMoneySource(i,"bladeburner")),e?p.setMaxLevel(2.5):p.setMaxLevel(3),p.rankGain){var s=Object(E.addOffset)(p.rankGain*a*r.BitNodeMultipliers.BladeburnerRank,10);this.changeRank(s),e&&this.logging.ops?this.log(p.name+" successfully completed! Gained "+Object(P.formatNumber)(s,3)+" rank"):!e&&this.logging.contracts&&this.log(p.name+" contract successfully completed! Gained "+Object(P.formatNumber)(s,3)+" rank and "+d.numeralWrapper.format(i,"$0.000a"))}e?this.completeOperation(!0):this.completeContract(!0)}else{this.gainActionStats(p,!1),++p.failures;var l=0,c=0;p.rankLoss&&(l=Object(E.addOffset)(p.rankLoss*a,10),this.changeRank(-1*l)),p.hpLoss&&(c=p.hpLoss*n,c=Math.ceil(Object(E.addOffset)(c,10)),this.hpLost+=c,m.a.takeDamage(c)&&(++this.numHosp,this.moneyLost+=o.CONSTANTS.HospitalCostPerHp*m.a.max_hp));var u="";l>0&&(u+="Lost "+Object(P.formatNumber)(l,3)+" rank."),c>0&&(u+="Took "+Object(P.formatNumber)(c,0)+" damage."),e&&this.logging.ops?this.log(p.name+" failed! "+u):!e&&this.logging.contracts&&this.log(p.name+" contract failed! "+u),e?this.completeOperation(!1):this.completeContract(!1)}p.autoLevel&&(p.level=p.maxLevel),this.startAction(this.action)}catch(e){Object(M.exceptionAlert)(e)}break;case $.BlackOp:case $.BlackOperation:try{var p;if(null==(p=this.getActionObject(this.action))||!(p instanceof J))throw new Error("Failed to get BlackOperation Object for: "+this.action.name);t=p.getDifficulty(),n=Math.pow(t,.28)+t/650;this.stamina-=.285*n,this.stamina<0&&(this.stamina=0);var g,_=p.teamCount;if(p.attempt(this)){this.gainActionStats(p,!0),p.count=0,this.blackops[p.name]=!0;var f=0;if(p.rankGain&&(f=Object(E.addOffset)(p.rankGain*r.BitNodeMultipliers.BladeburnerRank,10),this.changeRank(f)),g=Math.ceil(_/2),"Operation Daedalus"===p.name)return this.resetAction(),Object(h.a)(m.a.bitNodeN);S.routing.isOn(S.Page.Bladeburner)&&this.createActionAndSkillsContent(),this.logging.blackops&&this.log(p.name+" successful! Gained "+Object(P.formatNumber)(f,1)+" rank")}else{this.gainActionStats(p,!1);var y=0;c=0;p.rankLoss&&(y=Object(E.addOffset)(p.rankLoss,10),this.changeRank(-1*y)),p.hpLoss&&(c=p.hpLoss*n,c=Math.ceil(Object(E.addOffset)(c,10)),m.a.takeDamage(c)&&(++this.numHosp,this.moneyLost+=o.CONSTANTS.HospitalCostPerHp*m.a.max_hp)),g=Math.floor(_),this.logging.blackops&&this.log(p.name+" failed! Lost "+Object(P.formatNumber)(y,1)+" rank and took "+Object(P.formatNumber)(c,0)+" damage")}if(this.resetAction(),_>=1){var b=Object(A.getRandomInt)(1,g);this.teamSize-=b,this.teamLost+=b,this.logging.blackops&&this.log("You lost "+Object(P.formatNumber)(b,0)+" team members during "+p.name)}}catch(e){Object(M.exceptionAlert)(e)}break;case $.Training:this.stamina-=.1425;var v=30*m.a.strength_exp_mult,k=30*m.a.defense_exp_mult,C=30*m.a.dexterity_exp_mult,T=30*m.a.agility_exp_mult,O=.04*this.skillMultipliers.stamina;m.a.gainStrengthExp(v),m.a.gainDefenseExp(k),m.a.gainDexterityExp(C),m.a.gainAgilityExp(T),this.staminaBonus+=O,this.logging.general&&this.log("Training completed. Gained: "+Object(P.formatNumber)(v,1)+" str exp, "+Object(P.formatNumber)(k,1)+" def exp, "+Object(P.formatNumber)(C,1)+" dex exp, "+Object(P.formatNumber)(T,1)+" agi exp, "+Object(P.formatNumber)(O,3)+" max stamina"),this.startAction(this.action);break;case $.FieldAnalysis:case $["Field Analysis"]:var w=.04*Math.pow(m.a.hacking_skill,.3)+.04*Math.pow(m.a.intelligence,.9)+.02*Math.pow(m.a.charisma,.3);if(w*=m.a.bladeburner_analysis_mult,isNaN(w)||w<0)throw new Error("Field Analysis Effectiveness calculated to be NaN or negative");var x=20*m.a.hacking_exp_mult,R=20*m.a.charisma_exp_mult;m.a.gainHackingExp(x),m.a.gainIntelligenceExp(.001),m.a.gainCharismaExp(R),this.changeRank(.1*r.BitNodeMultipliers.BladeburnerRank),this.getCurrentCity().improvePopulationEstimateByPercentage(w*this.skillMultipliers.successChanceEstimate),this.logging.general&&this.log("Field analysis completed. Gained 0.1 rank, "+Object(P.formatNumber)(x,1)+" hacking exp, and "+Object(P.formatNumber)(R,1)+" charisma exp"),this.startAction(this.action);break;case $.Recruitment:var N=this.getRecruitmentSuccessChance();if(Math.random()=1){n=e?Math.ceil(a/2):Math.floor(a);var i=Object(A.getRandomInt)(0,n);this.teamSize-=i,this.teamLost+=i,this.logging.ops&&i>0&&this.log("Lost "+Object(P.formatNumber)(i,0)+" team members during this "+t.name)}var r=this.getCurrentCity();switch(t.name){case"Investigation":e?(r.improvePopulationEstimateByPercentage(.4*this.skillMultipliers.successChanceEstimate),Math.random()<.02*this.skillMultipliers.successChanceEstimate&&r.improveCommunityEstimate(1)):this.triggerPotentialMigration(this.city,.1);break;case"Undercover Operation":e?(r.improvePopulationEstimateByPercentage(.8*this.skillMultipliers.successChanceEstimate),Math.random()<.02*this.skillMultipliers.successChanceEstimate&&r.improveCommunityEstimate(1)):this.triggerPotentialMigration(this.city,.15);break;case"Sting Operation":e&&r.changePopulationByPercentage(-.1,{changeEstEqually:!0,nonZero:!0}),r.changeChaosByCount(.1);break;case"Raid":if(e)r.changePopulationByPercentage(-1,{changeEstEqually:!0,nonZero:!0}),--r.comms,--r.commsEst;else{var o=Object(A.getRandomInt)(-10,-5)/10;r.changePopulationByPercentage(o,{nonZero:!0})}r.changeChaosByPercentage(Object(A.getRandomInt)(1,5));break;case"Stealth Retirement Operation":e&&r.changePopulationByPercentage(-.5,{changeEstEqually:!0,nonZero:!0}),r.changeChaosByPercentage(Object(A.getRandomInt)(-3,-1));break;case"Assassination":e&&r.changePopulationByCount(-1,{estChange:-1}),r.changeChaosByPercentage(Object(A.getRandomInt)(-5,5));break;default:throw new Error("Invalid Action name in completeOperation: "+this.action.name)}},Q.prototype.getRecruitmentTime=function(){var e=m.a.charisma*this.skillMultipliers.effCha,t=Math.pow(e,.81)+e/90;return Math.max(10,Math.round(300-t))},Q.prototype.getRecruitmentSuccessChance=function(){return Math.pow(m.a.charisma,.45)/(this.teamSize+1)},Q.prototype.getDiplomacyEffectiveness=function(){return(100-(Math.pow(m.a.charisma,.045)+m.a.charisma/1e3))/100},Q.prototype.gainActionStats=function(e,t){var n=e.getDifficulty(),a=Math.pow(n,.28)+n/650,i=this.actionTimeToComplete,r=t?1:.5,o=1*i*r*a,s=.001*i*r*a;const l=this.skillMultipliers.expGain;m.a.gainHackingExp(o*e.weights.hack*m.a.hacking_exp_mult*l),m.a.gainStrengthExp(o*e.weights.str*m.a.strength_exp_mult*l),m.a.gainDefenseExp(o*e.weights.def*m.a.defense_exp_mult*l),m.a.gainDexterityExp(o*e.weights.dex*m.a.dexterity_exp_mult*l),m.a.gainAgilityExp(o*e.weights.agi*m.a.agility_exp_mult*l),m.a.gainCharismaExp(o*e.weights.cha*m.a.charisma_exp_mult*l),m.a.gainIntelligenceExp(s*e.weights.int*l)},Q.prototype.randomEvent=function(){var e=Math.random(),t=L[Object(A.getRandomInt)(0,5)],n=this.cities[t];if(!(n instanceof F))throw new Error("sourceCity was not a City object in Bladeburner.randomEvent()");for(var a=L[Object(A.getRandomInt)(0,5)];a===t;)a=L[Object(A.getRandomInt)(0,5)];var i=this.cities[a];if(!(n instanceof F&&i instanceof F))throw new Error("sourceCity/destCity was not a City object in Bladeburner.randomEvent()");if(e<=.05){++n.comms;var r=Object(A.getRandomInt)(10,20)/100,o=Math.round(n.pop*r);n.pop+=o,this.logging.events&&this.log("Intelligence indicates that a new Synthoid community was formed in a city")}else if(e<=.1)if(n.comms<=0){++n.comms;r=Object(A.getRandomInt)(10,20)/100,o=Math.round(n.pop*r);n.pop+=o,this.logging.events&&this.log("Intelligence indicates that a new Synthoid community was formed in a city")}else{--n.comms,++i.comms;r=Object(A.getRandomInt)(10,20)/100,o=Math.round(n.pop*r);n.pop-=o,i.pop+=o,this.logging.events&&this.log("Intelligence indicates that a Synthoid community migrated from "+t+" to some other city")}else if(e<=.3){r=Object(A.getRandomInt)(8,24)/100,o=Math.round(n.pop*r);n.pop+=o,this.logging.events&&this.log("Intelligence indicates that the Synthoid population of "+t+" just changed significantly")}else if(e<=.5)this.triggerMigration(t),this.logging.events&&this.log("Intelligence indicates that a large number of Synthoids migrated from "+t+" to some other city");else if(e<=.7)n.chaos+=1,n.chaos*=1+Object(A.getRandomInt)(5,20)/100,this.logging.events&&this.log("Tensions between Synthoids and humans lead to riots in "+t+"! Chaos increased");else if(e<=.9){r=Object(A.getRandomInt)(8,20)/100,o=Math.round(n.pop*r);n.pop-=o,this.logging.events&&this.log("Intelligence indicates that the Synthoid population of "+t+" just changed significantly")}},Q.prototype.triggerPotentialMigration=function(e,t){(null==t||isNaN(t))&&console.log("ERROR: Invalid 'chance' parameter passed into Bladeburner.triggerPotentialMigration()"),t>1&&(t/=100),Math.random()0&&(r*=Object(A.getRandomInt)(2,4),--a.comms,++n.comms);var o=Math.round(a.pop*r);a.pop-=o,n.pop+=o};var Z={};Q.prototype.initializeDomElementRefs=function(){Z={bladeburnerDiv:null,overviewConsoleParentDiv:null,overviewDiv:null,actionAndSkillsDiv:null,currentTab:null,consoleDiv:null,consoleTable:null,consoleInputRow:null,consoleInputCell:null,consoleInputHeader:null,consoleInput:null,overviewRank:null,overviewStamina:null,overviewStaminaHelpTip:null,overviewGen1:null,overviewEstPop:null,overviewEstPopHelpTip:null,overviewEstComms:null,overviewChaos:null,overviewSkillPoints:null,overviewBonusTime:null,overviewAugSuccessMult:null,overviewAugMaxStaminaMult:null,overviewAugStaminaGainMult:null,overviewAugAnalysisMult:null,actionsAndSkillsDesc:null,actionsAndSkillsList:null,generalActions:{},contracts:{},operations:{},blackops:{},skills:{},skillPointsDisplay:null}},Q.prototype.createContent=function(){Z.bladeburnerDiv=Object(T.createElement)("div",{id:"bladeburner-container",position:"fixed",class:"generic-menupage-container"}),Z.overviewConsoleParentDiv=Object(T.createElement)("div",{height:"60%",display:"block",position:"relative"}),Z.overviewDiv=Object(T.createElement)("div",{width:"30%",display:"inline-block",border:"1px solid white"}),Z.actionAndSkillsDiv=Object(T.createElement)("div",{height:"60%",width:"70%",display:"block",border:"1px solid white",margin:"6px",padding:"6px"}),Z.currentTab="general",this.createOverviewContent(),this.createActionAndSkillsContent(),Z.consoleDiv=Object(T.createElement)("div",{class:"bladeburner-console-div",clickListener:()=>(Z.consoleInput instanceof Element&&Z.consoleInput.focus(),!1)}),Z.consoleTable=Object(T.createElement)("table",{class:"bladeburner-console-table"}),Z.consoleInputRow=Object(T.createElement)("tr",{class:"bladeburner-console-input-row",id:"bladeubrner-console-input-row"}),Z.consoleInputCell=Object(T.createElement)("td",{class:"bladeburner-console-input-cell"}),Z.consoleInputHeader=Object(T.createElement)("pre",{innerText:"> "}),Z.consoleInput=Object(T.createElement)("input",{type:"text",class:"bladeburner-console-input",tabIndex:1,onfocus:()=>{Z.consoleInput.value=Z.consoleInput.value}}),Z.consoleInputCell.appendChild(Z.consoleInputHeader),Z.consoleInputCell.appendChild(Z.consoleInput),Z.consoleInputRow.appendChild(Z.consoleInputCell),Z.consoleTable.appendChild(Z.consoleInputRow),Z.consoleDiv.appendChild(Z.consoleTable),Z.overviewConsoleParentDiv.appendChild(Z.overviewDiv),Z.overviewConsoleParentDiv.appendChild(Z.consoleDiv),Z.bladeburnerDiv.appendChild(Z.overviewConsoleParentDiv),Z.bladeburnerDiv.appendChild(Z.actionAndSkillsDiv);const e=Object(T.createElement)("div");if(e.innerHTML=`${N}= This action requires stealth, ${I} = This action involves retirement`,Z.bladeburnerDiv.appendChild(e),document.getElementById("entire-game-container").appendChild(Z.bladeburnerDiv),0===this.consoleLogs.length)this.postToConsole("Bladeburner Console BETA"),this.postToConsole("Type 'help' to see console commands");else for(let e=0;e{Object(y.dialogBoxCreate)("Performing actions will use up your stamina.

    Your max stamina is determined primarily by your agility stat.

    Your stamina gain rate is determined by both your agility and your max stamina. Higher max stamina leads to a higher gain rate.

    Once your stamina falls below 50% of its max value, it begins to negatively affect the success rate of your contracts/operations. This penalty is shown in the overview panel. If the penalty is 15%, then this means your success rate would be multipled by 85% (100 - 15).

    Your max stamina and stamina gain rate can also be increased by training, or through skills and Augmentation upgrades.")}}),Z.overviewGen1=Object(T.createElement)("p",{display:"block"}),Z.overviewEstPop=Object(T.createElement)("p",{innerText:"Est. Synthoid Population: ",display:"inline-block",tooltip:"This is your Bladeburner division's estimate of how many Synthoids exist in your current city."}),Z.overviewEstPopHelpTip=Object(T.createElement)("div",{innerText:"?",class:"help-tip",clickListener:()=>{Object(y.dialogBoxCreate)("The success rate of your contracts/operations depends on the population of Synthoids in your current city. The success rate that is shown to you is only an estimate, and it is based on your Synthoid population estimate.

    Therefore, it is important that this Synthoid population estimate is accurate so that you have a better idea of your success rate for contracts/operations. Certain actions will increase the accuracy of your population estimate.

    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.")}}),Z.overviewEstComms=Object(T.createElement)("p",{innerText:"Est. Synthoid Communities: ",display:"inline-block",tooltip:"This is your Bladeburner divison's estimate of how many Synthoid communities exist in your current city."}),Z.overviewChaos=Object(T.createElement)("p",{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."}),Z.overviewBonusTime=Object(T.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."}),Z.overviewSkillPoints=Object(T.createElement)("p",{display:"block"}),Z.overviewAugSuccessMult=Object(T.createElement)("p",{display:"block"}),Z.overviewAugMaxStaminaMult=Object(T.createElement)("p",{display:"block"}),Z.overviewAugStaminaGainMult=Object(T.createElement)("p",{display:"block"}),Z.overviewAugAnalysisMult=Object(T.createElement)("p",{display:"block"}),Z.overviewDiv.appendChild(Z.overviewRank),Object(k.appendLineBreaks)(Z.overviewDiv,1),Z.overviewDiv.appendChild(Z.overviewStamina),Z.overviewDiv.appendChild(Z.overviewStaminaHelpTip),Z.overviewDiv.appendChild(Z.overviewGen1),Z.overviewDiv.appendChild(Z.overviewEstPop),Z.overviewDiv.appendChild(Z.overviewEstPopHelpTip),Object(k.appendLineBreaks)(Z.overviewDiv,1),Z.overviewDiv.appendChild(Z.overviewEstComms),Object(k.appendLineBreaks)(Z.overviewDiv,1),Z.overviewDiv.appendChild(Z.overviewChaos),Object(k.appendLineBreaks)(Z.overviewDiv,2),Z.overviewDiv.appendChild(Z.overviewBonusTime),Z.overviewDiv.appendChild(Z.overviewSkillPoints),Object(k.appendLineBreaks)(Z.overviewDiv,1),Z.overviewDiv.appendChild(Z.overviewAugSuccessMult),Z.overviewDiv.appendChild(Z.overviewAugMaxStaminaMult),Z.overviewDiv.appendChild(Z.overviewAugStaminaGainMult),Z.overviewDiv.appendChild(Z.overviewAugAnalysisMult),Object(k.appendLineBreaks)(Z.overviewDiv,1),Z.overviewDiv.appendChild(Object(T.createElement)("a",{innerHTML:"Travel",class:"a-link-button",display:"inline-block",clickListener:()=>{var e="bladeburner-travel-popup-cancel-btn",t=[];t.push(Object(T.createElement)("a",{innerText:"Cancel",class:"a-link-button",clickListener:()=>(Object(R.removeElementById)(e),!1)})),t.push(Object(T.createElement)("p",{innerText:"Travel to a different city for your Bladeburner activities. This does not cost any money. The city you are in for your Bladeburner duties does not affect your location in the game otherwise"}));for(var n=0;n(n.city=L[a],Object(R.removeElementById)(e),n.updateOverviewContent(),!1)}))}(this,n);Object(O.createPopup)(e,t)}}));if(Object(c.factionExists)("Bladeburners")){var e=c.Factions.Bladeburners;if(!(e instanceof l.Faction))throw new Error("Could not properly get Bladeburner Faction object in Bladeburner UI Overview Faction button");Z.overviewDiv.appendChild(Object(T.createElement)("a",{innerText:"Faction",class:"a-link-button",display:"inline-block",tooltip:"Apply to the Bladeburner Faction, or go to the faction page if you are already a member",clickListener:()=>(e.isMember?(s.Engine.loadFactionContent(),Object(u.a)("Bladeburners")):this.rank>=25?(Object(u.c)(e),Object(y.dialogBoxCreate)("Congratulations! You were accepted into the Bladeburners faction"),Object(b.removeChildrenFromElement)(Z.overviewDiv),this.createOverviewContent()):Object(y.dialogBoxCreate)("You need a rank of 25 to join the Bladeburners Faction!"),!1)}))}Z.overviewDiv.appendChild(Object(T.createElement)("br")),Z.overviewDiv.appendChild(Object(T.createElement)("br")),this.updateOverviewContent()},Q.prototype.createActionAndSkillsContent=function(){null==Z.currentTab&&(Z.currentTab="general"),Object(b.removeChildrenFromElement)(Z.actionAndSkillsDiv),Object(C.clearObject)(Z.generalActions),Object(C.clearObject)(Z.contracts),Object(C.clearObject)(Z.operations),Object(C.clearObject)(Z.blackops),Object(C.clearObject)(Z.skills);for(var e=Z.currentTab.toLowerCase(),t=["General","Contracts","Operations","BlackOps","Skills"],n=0;n(Z.currentTab=e[t].toLowerCase(),n.createActionAndSkillsContent(),!1)}))}(t,n,this,e);switch(Z.actionsAndSkillsDesc=Object(T.createElement)("p",{display:"block",margin:"4px",padding:"4px"}),Object(b.removeChildrenFromElement)(Z.actionsAndSkillsList),Z.actionsAndSkillsList=Object(T.createElement)("ul"),e){case"general":this.createGeneralActionsContent();break;case"contracts":this.createContractsContent();break;case"operations":this.createOperationsContent();break;case"blackops":this.createBlackOpsContent();break;case"skills":this.createSkillsContent();break;default:throw new Error("Invalid value for DomElems.currentTab in Bladeburner.createActionAndSkillsContent")}this.updateContent(),Z.actionAndSkillsDiv.appendChild(Z.actionsAndSkillsDesc),Z.actionAndSkillsDiv.appendChild(Z.actionsAndSkillsList)},Q.prototype.createGeneralActionsContent=function(){if(null==Z.actionsAndSkillsList||null==Z.actionsAndSkillsDesc)throw new Error("Bladeburner.createGeneralActionsContent called with either DomElems.actionsAndSkillsList or DomElems.actionsAndSkillsDesc = null");for(var e in Z.actionsAndSkillsDesc.innerText="These are generic actions that will assist you in your Bladeburner duties. They will not affect your Bladeburner rank in any way.",q)q.hasOwnProperty(e)&&(Z.generalActions[e]=Object(T.createElement)("div",{class:"bladeburner-action",name:e}),Z.actionsAndSkillsList.appendChild(Z.generalActions[e]))},Q.prototype.createContractsContent=function(){if(null==Z.actionsAndSkillsList||null==Z.actionsAndSkillsDesc)throw new Error("Bladeburner.createContractsContent called with either DomElems.actionsAndSkillsList or DomElems.actionsAndSkillsDesc = null");for(var e in Z.actionsAndSkillsDesc.innerHTML="Complete contracts in order to increase your Bladeburner rank and earn money. Failing a contract will cause you to lose HP, which can lead to hospitalization.

    You can unlock higher-level contracts by successfully completing them. Higher-level contracts are more difficult, but grant more rank, experience, and money.",this.contracts)this.contracts.hasOwnProperty(e)&&(Z.contracts[e]=Object(T.createElement)("div",{class:"bladeburner-action",name:e}),Z.actionsAndSkillsList.appendChild(Z.contracts[e]))},Q.prototype.createOperationsContent=function(){if(null==Z.actionsAndSkillsList||null==Z.actionsAndSkillsDesc)throw new Error("Bladeburner.createOperationsContent called with either DomElems.actionsAndSkillsList or DomElems.actionsAndSkillsDesc = null");for(var e in Z.actionsAndSkillsDesc.innerHTML="Carry out operations for the Bladeburner division. Failing an operation will reduce your Bladeburner rank. It will also cause you to lose HP, which can lead to hospitalization. In general, operations are harder and more punishing than contracts, but are also more rewarding.

    Operations can affect the chaos level and Synthoid population of your current city. The exact effects vary between different Operations.

    For operations, you can use a team. You must first recruit team members. Having a larger team will improves your chances of success.

    You can unlock higher-level operations by successfully completing them. Higher-level operations are more difficult, but grant more rank and experience.",this.operations)this.operations.hasOwnProperty(e)&&(Z.operations[e]=Object(T.createElement)("div",{class:"bladeburner-action",name:e}),Z.actionsAndSkillsList.appendChild(Z.operations[e]))},Q.prototype.createBlackOpsContent=function(){if(null==Z.actionsAndSkillsList||null==Z.actionsAndSkillsDesc)throw new Error("Bladeburner.createBlackOpsContent called with either DomElems.actionsAndSkillsList or DomElems.actionsAndSkillsDesc = null");Z.actionsAndSkillsDesc.innerHTML="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.";var e=[];for(var t in X)X.hasOwnProperty(t)&&e.push(X[t]);e.sort(function(e,t){return e.reqdRank-t.reqdRank});for(var n=e.length-1;n>=0;--n)null==this.blackops[[e[n].name]]&&0!==n&&null==this.blackops[[e[n-1].name]]||(Z.blackops[e[n].name]=Object(T.createElement)("div",{class:"bladeburner-action",name:e[n].name}),Z.actionsAndSkillsList.appendChild(Z.blackops[e[n].name]))},Q.prototype.createSkillsContent=function(){if(null==Z.actionsAndSkillsList||null==Z.actionsAndSkillsDesc)throw new Error("Bladeburner.createSkillsContent called with either DomElems.actionsAndSkillsList or DomElems.actionsAndSkillsDesc = null");Z.actionsAndSkillsDesc.innerHTML="You will gain one skill point every 3 ranks.

    Note that when upgrading a skill, the benefit for that skill is additive. However, the effects of different skills with each other is multiplicative.

    ";for(var e=Object.keys(this.skillMultipliers),t=0;t";break;case"successChanceStealth":Z.actionsAndSkillsDesc.innerHTML+="Stealth Success Chance: x"+n+"
    ";break;case"successChanceKill":Z.actionsAndSkillsDesc.innerHTML+="Retirement Success Chance: x"+n+"
    ";break;case"successChanceContract":Z.actionsAndSkillsDesc.innerHTML+="Contract Success Chance: x"+n+"
    ";break;case"successChanceOperation":Z.actionsAndSkillsDesc.innerHTML+="Operation Success Chance: x"+n+"
    ";break;case"successChanceEstimate":Z.actionsAndSkillsDesc.innerHTML+="Synthoid Data Estimate: x"+n+"
    ";break;case"actionTime":Z.actionsAndSkillsDesc.innerHTML+="Action Time: x"+n+"
    ";break;case"effHack":Z.actionsAndSkillsDesc.innerHTML+="Hacking Skill: x"+n+"
    ";break;case"effStr":Z.actionsAndSkillsDesc.innerHTML+="Strength: x"+n+"
    ";break;case"effDef":Z.actionsAndSkillsDesc.innerHTML+="Defense: x"+n+"
    ";break;case"effDex":Z.actionsAndSkillsDesc.innerHTML+="Dexterity: x"+n+"
    ";break;case"effAgi":Z.actionsAndSkillsDesc.innerHTML+="Agility: x"+n+"
    ";break;case"effCha":Z.actionsAndSkillsDesc.innerHTML+="Charisma: x"+n+"
    ";break;case"effInt":Z.actionsAndSkillsDesc.innerHTML+="Intelligence: x"+n+"
    ";break;case"stamina":Z.actionsAndSkillsDesc.innerHTML+="Stamina: x"+n+"
    ";break;case"money":Z.actionsAndSkillsDesc.innerHTML+="Contract Money: x"+n+"
    ";break;case"expGain":Z.actionsAndSkillsDesc.innerHTML+="Exp Gain: x"+n+"
    ";break;case"weaponAbility":case"gunAbility":break;default:console.log("Warning: Unrecognized SkillMult Key: "+e[t])}}for(var a in Z.skillPointsDisplay=Object(T.createElement)("p",{innerHTML:"
    Skill Points: "+Object(P.formatNumber)(this.skillPoints,0)+""}),Z.actionAndSkillsDiv.appendChild(Z.skillPointsDisplay),H)H.hasOwnProperty(a)&&(Z.skills[a]=Object(T.createElement)("div",{class:"bladeburner-action",name:a}),Z.actionsAndSkillsList.appendChild(Z.skills[a]))},Q.prototype.updateContent=function(){this.updateOverviewContent(),this.updateActionAndSkillsContent()},Q.prototype.updateOverviewContent=function(){S.routing.isOn(S.Page.Bladeburner)&&(Z.overviewRank.childNodes[0].nodeValue="Rank: "+Object(P.formatNumber)(this.rank,2),Z.overviewStamina.innerText="Stamina: "+Object(P.formatNumber)(this.stamina,3)+" / "+Object(P.formatNumber)(this.maxStamina,3),Z.overviewGen1.innerHTML="Stamina Penalty: "+Object(P.formatNumber)(100*(1-this.calculateStaminaPenalty()),1)+"%

    Team Size: "+Object(P.formatNumber)(this.teamSize,0)+"
    Team Members Lost: "+Object(P.formatNumber)(this.teamLost,0)+"

    Num Times Hospitalized: "+this.numHosp+"
    Money Lost From Hospitalizations: "+d.numeralWrapper.format(this.moneyLost,"$0.000a")+"

    Current City: "+this.city+"
    ",Z.overviewEstPop.childNodes[0].nodeValue="Est. Synthoid Population: "+d.numeralWrapper.format(this.getCurrentCity().popEst,"0.000a"),Z.overviewEstComms.childNodes[0].nodeValue="Est. Synthoid Communities: "+Object(P.formatNumber)(this.getCurrentCity().comms,0),Z.overviewChaos.childNodes[0].nodeValue="City Chaos: "+Object(P.formatNumber)(this.getCurrentCity().chaos),Z.overviewSkillPoints.innerText="Skill Points: "+Object(P.formatNumber)(this.skillPoints,0),Z.overviewBonusTime.childNodes[0].nodeValue="Bonus time: "+this.storedCycles/5,Z.overviewAugSuccessMult.innerText="Aug. Success Chance Mult: "+Object(P.formatNumber)(100*m.a.bladeburner_success_chance_mult,1)+"%",Z.overviewAugMaxStaminaMult.innerText="Aug. Max Stamina Mult: "+Object(P.formatNumber)(100*m.a.bladeburner_max_stamina_mult,1)+"%",Z.overviewAugStaminaGainMult.innerText="Aug. Stamina Gain Mult: "+Object(P.formatNumber)(100*m.a.bladeburner_stamina_gain_mult,1)+"%",Z.overviewAugAnalysisMult.innerText="Aug. Field Analysis Mult: "+Object(P.formatNumber)(100*m.a.bladeburner_analysis_mult,1)+"%")},Q.prototype.updateActionAndSkillsContent=function(){switch(null==Z.currentTab&&(Z.currentTab="general"),Z.currentTab.toLowerCase()){case"general":for(var e=Object.keys(Z.generalActions),t=0;t";var d=Object.keys(Z.skills);for(t=0;t(this.action.type=$[t.name],this.action.name=t.name,this.startAction(this.action),this.updateActionAndSkillsContent(),!1)}));Object(k.appendLineBreaks)(e,2),e.appendChild(Object(T.createElement)("pre",{innerHTML:t.desc,display:"inline-block"}))},Q.prototype.updateContractsUIElement=function(e,t){Object(b.removeChildrenFromElement)(e);var n=e.classList.contains(B),a=t.getSuccessChance(this,{est:!0});if(e.appendChild(Object(T.createElement)("h2",{innerText:n?t.name+" (IN PROGRESS - "+Object(P.formatNumber)(this.actionTimeCurrent,0)+" / "+Object(P.formatNumber)(this.actionTimeToComplete,0)+")":t.name,display:"inline-block"})),n){var i=this.actionTimeCurrent/this.actionTimeToComplete;e.appendChild(Object(T.createElement)("p",{display:"block",innerText:Object(f.createProgressBarText)({progress:i})}))}else e.appendChild(Object(T.createElement)("a",{innerText:"Start",class:"a-link-button",padding:"3px",margin:"3px",clickListener:()=>(this.action.type=$.Contract,this.action.name=t.name,this.startAction(this.action),this.updateActionAndSkillsContent(),!1)}));var r=t.level>=t.maxLevel;Object(k.appendLineBreaks)(e,2),e.appendChild(Object(T.createElement)("pre",{display:"inline-block",innerText:"Level: "+t.level+" / "+t.maxLevel,tooltip:t.getSuccessesNeededForNextLevel(3)+" successes needed for next level"})),e.appendChild(Object(T.createElement)("a",{class:r?"a-link-button-inactive":"a-link-button",innerHTML:"↑",padding:"2px",margin:"2px",tooltip:n?"WARNING: changing the level will restart the contract":"",display:"inline",clickListener:()=>(++t.level,n&&this.startAction(this.action),this.updateContractsUIElement(e,t),!1)})),e.appendChild(Object(T.createElement)("a",{class:t.level<=1?"a-link-button-inactive":"a-link-button",innerHTML:"↓",padding:"2px",margin:"2px",tooltip:n?"WARNING: changing the level will restart the contract":"",display:"inline",clickListener:()=>(--t.level,n&&this.startAction(this.action),this.updateContractsUIElement(e,t),!1)}));var o=t.getActionTime(this);Object(k.appendLineBreaks)(e,2),e.appendChild(Object(T.createElement)("pre",{display:"inline-block",innerHTML:t.desc+"\n\n"+`Estimated success chance: ${Object(P.formatNumber)(100*a,1)}% ${t.isStealth?N:""}${t.isKill?I:""}\n`+"Time Required (s): "+Object(P.formatNumber)(o,0)+"\nContracts remaining: "+Math.floor(t.count)+"\nSuccesses: "+t.successes+"\nFailures: "+t.failures})),e.appendChild(Object(T.createElement)("br"));var s="bladeburner-"+t.name+"-autolevel-checkbox";e.appendChild(Object(T.createElement)("label",{for:s,innerText:"Autolevel",color:"white",tooltip:"Automatically increase contract level when possible"}));const l=Object(T.createElement)("div",{class:"bbcheckbox"}),c=Object(T.createElement)("input",{type:"checkbox",id:s,checked:t.autoLevel,changeListener:()=>{t.autoLevel=c.checked}}),u=Object(T.createElement)("label",{for:s});l.appendChild(c),l.appendChild(u),e.appendChild(l)},Q.prototype.updateOperationsUIElement=function(e,t){Object(b.removeChildrenFromElement)(e);var n=e.classList.contains(B),a=t.getSuccessChance(this,{est:!0});if(e.appendChild(Object(T.createElement)("h2",{innerText:n?t.name+" (IN PROGRESS - "+Object(P.formatNumber)(this.actionTimeCurrent,0)+" / "+Object(P.formatNumber)(this.actionTimeToComplete,0)+")":t.name,display:"inline-block"})),n){var i=this.actionTimeCurrent/this.actionTimeToComplete;e.appendChild(Object(T.createElement)("p",{display:"block",innerText:Object(f.createProgressBarText)({progress:i})}))}else e.appendChild(Object(T.createElement)("a",{innerText:"Start",class:"a-link-button",margin:"3px",padding:"3px",clickListener:()=>(this.action.type=$.Operation,this.action.name=t.name,this.startAction(this.action),this.updateActionAndSkillsContent(),!1)})),e.appendChild(Object(T.createElement)("a",{innerText:"Set Team Size (Curr Size: "+Object(P.formatNumber)(t.teamCount,0)+")",class:"a-link-button",margin:"3px",padding:"3px",clickListener:()=>{var n="bladeburner-operation-set-team-size-popup",a=Object(T.createElement)("p",{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."}),i=Object(T.createElement)("input",{type:"number",placeholder:"Team Members"}),r=Object(T.createElement)("a",{innerText:"Confirm",class:"a-link-button",clickListener:()=>{var a=Math.round(parseFloat(i.value));return isNaN(a)?Object(y.dialogBoxCreate)("Invalid value entered for number of Team Members (must be numeric)"):(t.teamCount=a,this.updateOperationsUIElement(e,t)),Object(R.removeElementById)(n),!1}}),o=Object(T.createElement)("a",{innerText:"Cancel",class:"a-link-button",clickListener:()=>(Object(R.removeElementById)(n),!1)});Object(O.createPopup)(n,[a,i,r,o])}}));var r=t.level>=t.maxLevel;Object(k.appendLineBreaks)(e,2),e.appendChild(Object(T.createElement)("pre",{display:"inline-block",innerText:"Level: "+t.level+" / "+t.maxLevel,tooltip:t.getSuccessesNeededForNextLevel(2.5)+" successes needed for next level"})),e.appendChild(Object(T.createElement)("a",{class:r?"a-link-button-inactive":"a-link-button",innerHTML:"↑",padding:"2px",margin:"2px",tooltip:n?"WARNING: changing the level will restart the Operation":"",display:"inline",clickListener:()=>(++t.level,n&&this.startAction(this.action),this.updateOperationsUIElement(e,t),!1)})),e.appendChild(Object(T.createElement)("a",{class:t.level<=1?"a-link-button-inactive":"a-link-button",innerHTML:"↓",padding:"2px",margin:"2px",tooltip:n?"WARNING: changing the level will restart the Operation":"",display:"inline",clickListener:()=>(--t.level,n&&this.startAction(this.action),this.updateOperationsUIElement(e,t),!1)}));t.getDifficulty();var o=t.getActionTime(this);Object(k.appendLineBreaks)(e,2),e.appendChild(Object(T.createElement)("pre",{display:"inline-block",innerHTML:t.desc+"\n\n"+`Estimated success chance: ${Object(P.formatNumber)(100*a,1)}% ${t.isStealth?N:""}${t.isKill?I:""}\n`+"Time Required(s): "+Object(P.formatNumber)(o,0)+"\nOperations remaining: "+Math.floor(t.count)+"\nSuccesses: "+t.successes+"\nFailures: "+t.failures})),e.appendChild(Object(T.createElement)("br"));var s="bladeburner-"+t.name+"-autolevel-checkbox";e.appendChild(Object(T.createElement)("label",{for:s,innerText:"Autolevel",color:"white",tooltip:"Automatically increase operation level when possible"}));const l=Object(T.createElement)("div",{class:"bbcheckbox"}),c=Object(T.createElement)("input",{type:"checkbox",id:s,checked:t.autoLevel,changeListener:()=>{t.autoLevel=c.checked}}),u=Object(T.createElement)("label",{for:s});l.appendChild(c),l.appendChild(u),e.appendChild(l)},Q.prototype.updateBlackOpsUIElement=function(e,t){Object(b.removeChildrenFromElement)(e);var n=e.classList.contains(B),a=null!=this.blackops[t.name],i=t.getSuccessChance(this,{est:!0}),r=(t.getDifficulty(),t.getActionTime(this)),o=this.rank>=t.reqdRank;if(a)e.appendChild(Object(T.createElement)("h2",{innerText:t.name+" (COMPLETED)",display:"block"}));else{if(e.appendChild(Object(T.createElement)("h2",{innerText:n?t.name+" (IN PROGRESS - "+Object(P.formatNumber)(this.actionTimeCurrent,0)+" / "+Object(P.formatNumber)(this.actionTimeToComplete,0)+")":t.name,display:"inline-block"})),n){var s=this.actionTimeCurrent/this.actionTimeToComplete;e.appendChild(Object(T.createElement)("p",{display:"block",innerText:Object(f.createProgressBarText)({progress:s})}))}else e.appendChild(Object(T.createElement)("a",{innerText:"Start",margin:"3px",padding:"3px",class:o?"a-link-button":"a-link-button-inactive",clickListener:()=>(this.action.type=$.BlackOperation,this.action.name=t.name,this.startAction(this.action),this.updateActionAndSkillsContent(),!1)})),e.appendChild(Object(T.createElement)("a",{innerText:"Set Team Size (Curr Size: "+Object(P.formatNumber)(t.teamCount,0)+")",class:"a-link-button",margin:"3px",padding:"3px",clickListener:()=>{var n="bladeburner-operation-set-team-size-popup",a=Object(T.createElement)("p",{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."}),i=Object(T.createElement)("input",{type:"number",placeholder:"Team Members"}),r=Object(T.createElement)("a",{innerText:"Confirm",class:"a-link-button",clickListener:()=>{var a=Math.round(parseFloat(i.value));return isNaN(a)?Object(y.dialogBoxCreate)("Invalid value entered for number of Team Members (must be numeric)"):(t.teamCount=a,this.updateBlackOpsUIElement(e,t)),Object(R.removeElementById)(n),!1}}),o=Object(T.createElement)("a",{innerText:"Cancel",class:"a-link-button",clickListener:()=>(Object(R.removeElementById)(n),!1)});Object(O.createPopup)(n,[a,i,r,o])}}));Object(k.appendLineBreaks)(e,2),e.appendChild(Object(T.createElement)("p",{display:"inline-block",innerHTML:"
    "+t.desc+"

    "})),e.appendChild(Object(T.createElement)("p",{display:"block",color:o?"white":"red",innerHTML:"Required Rank: "+Object(P.formatNumber)(t.reqdRank,0)+"
    "})),e.appendChild(Object(T.createElement)("p",{display:"inline-block",innerHTML:`Estimated Success Chance: ${Object(P.formatNumber)(100*i,1)}% ${t.isStealth?N:""}${t.isKill?I:""}\n`+"Time Required(s): "+Object(P.formatNumber)(r,0)}))}},Q.prototype.updateSkillsUIElement=function(e,t){Object(b.removeChildrenFromElement)(e);var n=t.name,a=0;this.skills[n]&&!isNaN(this.skills[n])&&(a=this.skills[n]);var i=t.calculateCost(a);e.appendChild(Object(T.createElement)("h2",{innerText:t.name+" (Lvl "+a+")",display:"inline-block"}));var r=this.skillPoints>=i,o=!!t.maxLvl&&a>=t.maxLvl;e.appendChild(Object(T.createElement)("a",{innerText:"Level",display:"inline-block",class:r&&!o?"a-link-button":"a-link-button-inactive",margin:"3px",padding:"3px",clickListener:()=>{if(!(this.skillPoints100&&this.consoleLogs.shift()),null!=t&&null!=Z.consoleDiv&&(e("#bladeubrner-console-input-row").before(''+t+""),Z.consoleTable.childNodes.length>100&&Z.consoleTable.removeChild(Z.consoleTable.firstChild),this.updateConsoleScroll())},Q.prototype.updateConsoleScroll=function(){Z.consoleDiv.scrollTop=Z.consoleDiv.scrollHeight},Q.prototype.resetConsoleInput=function(){Z.consoleInput.value=""},Q.prototype.clearConsole=function(){for(;Z.consoleTable.childNodes.length>1;)Z.consoleTable.removeChild(Z.consoleTable.firstChild);this.consoleLogs.length=0},Q.prototype.log=function(e){this.postToConsole(`[${Object(w.getTimestamp)()}] ${e}`)},Q.prototype.executeConsoleCommands=function(e){try{this.consoleHistory[this.consoleHistory.length-1]!=e&&(this.consoleHistory.push(e),this.consoleHistory.length>50&&this.consoleHistory.splice(0,1)),W=this.consoleHistory.length;for(var t=e.split(";"),n=0;n"))}},Q.prototype.executeLogConsoleCommand=function(e){if(e.length<3)return this.postToConsole("Invalid usage of log command: log [enable/disable] [action/event]"),void this.postToConsole("Use 'help log' for more details and examples");var t=!0;switch(e[1].toLowerCase().includes("d")&&(t=!1),e[2].toLowerCase()){case"general":case"gen":this.logging.general=t,this.log("Logging "+(t?"enabled":"disabled")+" for general actions");break;case"contract":case"contracts":this.logging.contracts=t,this.log("Logging "+(t?"enabled":"disabled")+" for Contracts");break;case"ops":case"op":case"operations":case"operation":this.logging.ops=t,this.log("Logging "+(t?"enabled":"disabled")+" for Operations");break;case"blackops":case"blackop":case"black operations":case"black operation":this.logging.blackops=t,this.log("Logging "+(t?"enabled":"disabled")+" for BlackOps");break;case"event":case"events":this.logging.events=t,this.log("Logging "+(t?"enabled":"disabled")+" for events");break;case"all":this.logging.general=t,this.logging.contracts=t,this.logging.ops=t,this.logging.blackops=t,this.logging.events=t,this.log("Logging "+(t?"enabled":"disabled")+" for everything");break;default:this.postToConsole("Invalid action/event type specified: "+e[2]),this.postToConsole("Examples of valid action/event identifiers are: [general, contracts, ops, blackops, events]")}},Q.prototype.executeSkillConsoleCommand=function(e){switch(e.length){case 1:this.postToConsole("Invalid usage of 'skill' console command: skill [action] [name]"),this.postToConsole("Use 'help skill' for more info");break;case 2:if("list"===e[1].toLowerCase()){this.postToConsole("Skills: ");for(var t=Object.keys(H),n=0;n=c?(this.skillPoints-=c,this.upgradeSkill(a),this.log(a.name+" upgraded to Level "+this.skills[s]),this.createActionAndSkillsContent()):this.postToConsole("You do not have enough Skill Points to upgrade this. You need "+Object(P.formatNumber)(c,0))}else this.postToConsole("Invalid usage of 'skill' console command: skill [action] [name]"),this.postToConsole("Use 'help skill' for more info");break;default:this.postToConsole("Invalid usage of 'skill' console command: skill [action] [name]"),this.postToConsole("Use 'help skill' for more info")}},Q.prototype.executeStartConsoleCommand=function(e){if(3!==e.length)return this.postToConsole("Invalid usage of 'start' console command: start [type] [name]"),void this.postToConsole("Use 'help start' for more info");var t=e[2];switch(e[1].toLowerCase()){case"general":case"gen":null!=q[t]?(this.action.type=$[t],this.action.name=t,this.startAction(this.action),this.updateActionAndSkillsContent()):this.postToConsole("Invalid action name specified: "+e[2]);break;case"contract":case"contracts":null!=this.contracts[t]?(this.action.type=$.Contract,this.action.name=t,this.startAction(this.action),this.updateActionAndSkillsContent()):this.postToConsole("Invalid contract name specified: "+e[2]);break;case"ops":case"op":case"operations":case"operation":null!=this.operations[t]?(this.action.type=$.Operation,this.action.name=t,this.startAction(this.action),this.updateActionAndSkillsContent()):this.postToConsole("Invalid Operation name specified: "+e[2]);break;case"blackops":case"blackop":case"black operations":case"black operation":null!=X[t]?(this.action.type=$.BlackOperation,this.action.name=t,this.startAction(this.action),this.updateActionAndSkillsContent()):this.postToConsole("Invalid BlackOp name specified: "+e[2]);break;default:this.postToConsole("Invalid action/event type specified: "+e[1]),this.postToConsole("Examples of valid action/event identifiers are: [general, contract, op, blackop]")}},Q.prototype.getActionIdFromTypeAndName=function(e="",t=""){if(""===e||""===t)return null;var n=new Y,a=e.toLowerCase().trim(),i=t.toLowerCase().trim();switch(a){case"contract":case"contracts":case"contr":return n.type=$.Contract,this.contracts.hasOwnProperty(t)?(n.name=t,n):null;case"operation":case"operations":case"op":case"ops":return n.type=$.Operation,this.operations.hasOwnProperty(t)?(n.name=t,n):null;case"blackoperation":case"black operation":case"black operations":case"black op":case"black ops":case"blackop":case"blackops":return n.type=$.BlackOp,X.hasOwnProperty(t)?(n.name=t,n):null;case"general":case"general action":case"gen":break;default:return null}if(a.startsWith("gen")){switch(i){case"training":n.type=$.Training,n.name="Training";break;case"recruitment":case"recruit":n.type=$.Recruitment,n.name="Recruitment";break;case"field analysis":case"fieldanalysis":n.type=$["Field Analysis"],n.name="Field Analysis";break;case"diplomacy":n.type=$.Diplomacy,n.name="Diplomacy";break;case"hyperbolic regeneration chamber":n.type=$["Hyperbolic Regeneration Chamber"],n.name="Hyperbolic Regeneration Chamber";break;default:return null}return n}},Q.prototype.getTypeAndNameFromActionId=function(e){var t={};let n=Object.keys($);for(let a=0;athis.rank)return n.log(`Failed to start Black Op ${i.name} due to insufficient rank`),!1;if(null!=this.blackops[i.name])return n.log(`Failed to start Black Op ${i.name} because its already been completed`),!1;var r=[];for(const e in X)X.hasOwnProperty(e)&&r.push(e);r.sort(function(e,t){return X[e].reqdRank-X[t].reqdRank});let e=r.indexOf(i.name);if(-1===e)return n.log("ERROR: Invalid Black Operation name passed into bladeburner.startAction(). Note that this name is case-sensitive & whitespace-sensitive"),!1;if(e>0&&null==this.blackops[r[e-1]])return n.log(`ERROR: Cannot attempt Black Operation ${i.name} because you have not done the preceding one`),!1}try{return this.startAction(i),n.shouldLog("startAction")&&n.log("Starting bladeburner action with type "+e+" and name "+t),!0}catch(a){return this.resetAction(),n.log("ERROR: bladeburner.startAction() failed to start action of type "+e+" due to invalid name: "+t+"Note that this name is case-sensitive and whitespace-sensitive"),!1}},Q.prototype.getActionTimeNetscriptFn=function(e,t,n){var a="ERROR: bladeburner.getActionTime() failed due to an invalid action specified. Type: "+e+", Name: "+t+". Note that for contracts and operations, the name of the operation is case-sensitive.",i=this.getActionIdFromTypeAndName(e,t);if(null==i)return n.log(a),-1;var r=this.getActionObject(i);if(null==r)return n.log(a),-1;switch(i.type){case $.Contract:case $.Operation:case $.BlackOp:case $.BlackOperation:return r.getActionTime(this);case $.Training:case $["Field Analysis"]:case $.FieldAnalysis:return 30;case $.Recruitment:return this.getRecruitmentTime();default:return n.log(a),-1}},Q.prototype.getActionEstimatedSuccessChanceNetscriptFn=function(e,t,n){var a="ERROR: bladeburner.getActionEstimatedSuccessChance() failed due to an invalid action specified. Type: "+e+", Name: "+t+". Note that for contracts and operations, the name of the operation is case-sensitive.",i=this.getActionIdFromTypeAndName(e,t);if(null==i)return n.log(a),-1;var r=this.getActionObject(i);if(null==r)return n.log(a),-1;switch(i.type){case $.Contract:case $.Operation:case $.BlackOp:case $.BlackOperation:return r.getSuccessChance(this,{est:!0});case $.Training:case $["Field Analysis"]:case $.FieldAnalysis:return 1;case $.Recruitment:return this.getRecruitmentSuccessChance();default:return n.log(a),-1}},Q.prototype.getActionCountRemainingNetscriptFn=function(e,t,n){var a="ERROR: bladeburner.getActionCountRemaining() failed due to an invalid action specified. Type: "+e+", Name: "+t+". Note that for contracts and operations, the name of the operation is case-sensitive.",i=this.getActionIdFromTypeAndName(e,t);if(null==i)return n.log(a),-1;var r=this.getActionObject(i);if(null==r)return n.log(a),-1;switch(i.type){case $.Contract:case $.Operation:return Math.floor(r.count);case $.BlackOp:case $.BlackOperation:return null!=this.blackops[t]?0:1;case $.Training:case $["Field Analysis"]:case $.FieldAnalysis:return 1/0;default:return n.log(a),-1}},Q.prototype.getSkillLevelNetscriptFn=function(e,t){var n="ERROR: bladeburner.getSkillLevel() failed due to an invalid skill specified: "+e+". Note that the name of the skill is case-sensitive";return""===e?-1:H.hasOwnProperty(e)?null==this.skills[e]?0:this.skills[e]:(t.log(n),-1)},Q.prototype.getSkillUpgradeCostNetscriptFn=function(e,t){var n="ERROR: bladeburner.getSkillUpgradeCostNetscriptFn() failed due to an invalid skill specified: "+e+". Note that the name of the skill is case-sensitive";if(""===e)return-1;if(!H.hasOwnProperty(e))return t.log(n),-1;var a=H[e];return null==this.skills[e]?a.calculateCost(0):a.calculateCost(this.skills[e])},Q.prototype.upgradeSkillNetscriptFn=function(e,t){var n="ERROR: bladeburner.upgradeSkill() failed due to an invalid skill specified: "+e+". Note that the name of the skill is case-sensitive";if(!H.hasOwnProperty(e))return t.log(n),!1;var a=H[e],i=0;this.skills[e]&&!isNaN(this.skills[e])&&(i=this.skills[e]);var r=a.calculateCost(i);return a.maxLvl&&i>=a.maxLvl?(t.shouldLog("upgradeSkill")&&t.log(`bladeburner.upgradeSkill() failed because ${e} is already maxed`),!1):this.skillPoints=25?(Object(u.c)(t),e.shouldLog("joinBladeburnerFaction")&&e.log("Joined Bladeburners Faction"),S.routing.isOn(S.Page.Bladeburner)&&(Object(b.removeChildrenFromElement)(Z.overviewDiv),this.createOverviewContent()),!0):(e.shouldLog("joinBladeburnerFaction")&&e.log("Failed to join Bladeburners Faction because you do not have the required 25 rank"),!1))},Q.prototype.toJSON=function(){return Object(v.Generic_toJSON)("Bladeburner",this)},Q.fromJSON=function(e){return Object(v.Generic_fromJSON)(Q,e.data)},v.Reviver.constructors.Bladeburner=Q}).call(this,n(79))},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const a=n(4),i=n(68);t.createPopup=function(e,t,n={}){const r=a.createElement("div",{class:"popup-box-container",display:"flex",id:e}),o=a.createElement("div",{class:"popup-box-content",id:`${e}-content`});for(const e of t)o.appendChild(e);return n.backgroundColor&&(o.style.backgroundColor=n.backgroundColor),r.appendChild(o),i.getElementById("entire-game-container").appendChild(r),r}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const a=n(295),i=n(121);t.CompanyPositions={},a.companyPositionMetadata.forEach(e=>{!function(e){null!=t.CompanyPositions[e.name]&&console.warn(`Duplicate Company Position being defined: ${e.name}`),t.CompanyPositions[e.name]=new i.CompanyPosition(e)}(e)})},function(e,t,n){"use strict";n.d(t,"b",function(){return C}),n.d(t,"h",function(){return T}),n.d(t,"a",function(){return O}),n.d(t,"f",function(){return w}),n.d(t,"d",function(){return x}),n.d(t,"c",function(){return R}),n.d(t,"g",function(){return N}),n.d(t,"e",function(){return M});var a=n(85),i=n(1),r=n(11),o=n(174),s=n(152),l=n(8),c=n(50),u=n(155),p=n(93),m=n(23),h=n(19),d=n(64),g=n(144),_=n(61),f=n(9),y=n(126),b=n(70),v=n(117),E=n(7);const k=n(205);function C(e){this.name=e.filename,this.running=!1,this.serverIp=e.server,this.code=e.getCode(),this.env=new s.a(this),this.env.set("args",e.args.slice()),this.output="",this.ramUsage=0,this.scriptRef=e,this.errorMessage="",this.args=e.args.slice(),this.delay=null,this.fnWorker=null,this.checkingRam=!1,this.loadedFns={},this.disableLogs={},this.dynamicRamUsage=i.CONSTANTS.ScriptBaseRamCost,this.dynamicLoadedFns={}}C.prototype.getServer=function(){return m.AllServers[this.serverIp]},C.prototype.getScript=function(){let e=this.getServer();for(let t=0;t{if(t instanceof Error)throw e.errorMessage=Object(l.d)(e,t.message+(t.stack&&"\nstack:\n"+t.stack.toString()||"")),e;if(Object(l.b)(t))throw e.errorMessage=t,e;throw t})}function A(e){var t,n,a=e.code;e.running=!0;try{let i=function(e,t){var n=Object(_.parse)(e,{ecmaVersion:6,allowReserved:!0,sourceType:"module"}),a=t.getServer();if(null==a)throw new Error("Failed to find underlying Server object for script");var i="",r=!1;if(k.simple(n,{ImportDeclaration:e=>{r=!0;let t=e.source.value;t.startsWith("./")&&(t=t.slice(2));let n=function(e){for(let t=0;t{n.push(e.id.name),a.push(e)}}),i="var "+t+";\n(function (namespace) {\n",a.forEach(e=>{i+=Object(g.generate)(e),i+="\n"}),n.forEach(e=>{i+="namespace."+e+" = "+e,i+="\n"}),i+="})("+t+" || ("+t+" = {}));\n"}else{let t=[];e.specifiers.forEach(e=>{t.push(e.local.name)});let n=[];k.simple(o,{FunctionDeclaration:e=>{t.includes(e.id.name)&&n.push(e)}}),n.forEach(e=>{i+=Object(g.generate)(e),i+="\n"})}}}),!r)return{code:e,lineOffset:0};var o=0;if("Program"!==n.type||null==n.body)throw new Error("Code could not be properly parsed");for(let e=n.body.length-1;e>=0;--e)"ImportDeclaration"===n.body[e].type&&(n.body.splice(e,1),++o);var s=(i.match(/\n/g)||[]).length-o;return e=Object(g.generate)(n),{code:e=i+e,lineOffset:s}}(a,e);t=i.code,n=i.lineOffset}catch(t){return Object(f.dialogBoxCreate)("Error processing Imports in "+e.name+":
    "+t),e.env.stopFlag=!0,void(e.running=!1)}var i;try{i=new o.a(t,function(t,n){var a=Object(c.a)(e);for(let e in a){let i=a[e];if("function"==typeof i)if("hack"===e||"grow"===e||"weaken"===e||"sleep"===e||"prompt"===e||"run"===e||"exec"===e){let a=function(){let e=[];for(let t=0;t"+t),e.env.stopFlag=!0,void(e.running=!1)}return new Promise(function(t,n){try{!function a(){try{if(e.env.stopFlag)return n(e);i.step()?Object(d.setTimeoutRef)(a,h.Settings.CodeInstructionRunTime):t(e)}catch(t){return t=t.toString(),Object(l.b)(t)||(t=Object(l.d)(e,t)),e.errorMessage=t,n(e)}}()}catch(t){return Object(E.isString)(t)?(e.errorMessage=t,n(e)):n(t instanceof C?t:e)}})}function w(){for(var e=!1,t=T.length-1;t>=0;t--)if(0==T[t].running&&1==T[t].env.stopFlag){e=!0;var n=T[t].serverIp,i=T[t].name;m.AllServers[n].ramUsed=0;for(let e=0;eServer Ip: "+n+"
    Script name: "+a+"
    Args:"+Object(b.arrayToString)(e.args)+"
    "+i),e.scriptRef.log("Script crashed with runtime error")}else e.scriptRef.log("Script killed");e.running=!1,e.env.stopFlag=!0}else{if(Object(l.b)(e))return Object(f.dialogBoxCreate)("Script runtime unknown error. This is a bug please contact game developer"),void console.log("ERROR: Evaluating workerscript returns only error message rather than WorkerScript object. THIS SHOULDN'T HAPPEN: "+e.toString());Object(f.dialogBoxCreate)("An unknown script died for an unknown reason. This is a bug please contact game dev"),console.log(e)}else console.log("Script returning with value: "+e[1])})}Object(d.setTimeoutRef)(w,6e3)}function x(e,t){for(var n=0;nt.maxRam-t.ramUsed)Object(f.dialogBoxCreate)("Not enough RAM to run script "+e.filename+" with args "+Object(b.arrayToString)(e.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.)");else{t.ramUsed=Object(v.roundToTwo)(t.ramUsed+i);var r=new C(e);r.ramUsage=i,Object(a.a)(r),T.push(r)}}function N(e=1){for(var t=e*r.Engine._idleSpeed/1e3,n=0;nh.Start&&(d.currStep-=1);_()}(),!1}),Object(l.clearEventListeners)("interactive-tutorial-next").addEventListener("click",function(){return f(),!1}),_()}function _(){if(d.isRunning){var e=Object(l.clearEventListeners)("terminal-menu-link"),t=Object(l.clearEventListeners)("stats-menu-link"),n=Object(l.clearEventListeners)("active-scripts-menu-link"),i=Object(l.clearEventListeners)("hacknet-nodes-menu-link"),r=Object(l.clearEventListeners)("city-menu-link"),o=Object(l.clearEventListeners)("tutorial-menu-link");e.removeAttribute("class"),t.removeAttribute("class"),n.removeAttribute("class"),i.removeAttribute("class"),r.removeAttribute("class"),o.removeAttribute("class");var s=document.getElementById("interactive-tutorial-next");switch(d.currStep){case h.Start:a.Engine.loadTerminalContent(),b("Welcome to Bitburner, a cyberpunk-themed incremental RPG! The game takes place in a dark, dystopian future...The year is 2077...

    This tutorial will show you the basics of the game. You may skip the tutorial at any time."),s.style.display="inline-block";break;case h.GoToCharacterPage:a.Engine.loadTerminalContent(),b("Let's start by heading to the Stats page. Click the 'Stats' tab on the main navigation menu (left-hand side of the screen)"),s.style.display="none",t.setAttribute("class","flashing-button"),t.addEventListener("click",function(){return a.Engine.loadCharacterContent(),f(),!1});break;case h.CharacterPage:a.Engine.loadCharacterContent(),b("The Stats page shows a lot of important information about your progress, such as your skills, money, and bonuses/multipliers. "),s.style.display="inline-block";break;case h.CharacterGoToTerminalPage:a.Engine.loadCharacterContent(),b("Let's head to your computer's terminal by clicking the 'Terminal' tab on the main navigation menu."),s.style.display="none",e.setAttribute("class","flashing-button"),e.addEventListener("click",function(){return a.Engine.loadTerminalContent(),f(),!1});break;case h.TerminalIntro:a.Engine.loadTerminalContent(),b("The Terminal is used to interface with your home computer as well as all of the other machines around the world."),s.style.display="inline-block";break;case h.TerminalHelp:a.Engine.loadTerminalContent(),b("Let's try it out. Start by entering the 'help' command into the Terminal (Don't forget to press Enter after typing the command)"),s.style.display="none";break;case h.TerminalLs:a.Engine.loadTerminalContent(),b("The 'help' command displays a list of all available Terminal commands, how to use them, and a description of what they do.

    Let's try another command. Enter the 'ls' command"),s.style.display="none";break;case h.TerminalScan:a.Engine.loadTerminalContent(),b("'ls' is a basic command that shows all of the contents (programs/scripts) on the computer. Right now, it shows that you have a program called 'NUKE.exe' on your computer. We'll get to what this does later.

    Using your home computer's terminal, you can connect to other machines throughout the world. Let's do that now by first entering the 'scan' command."),s.style.display="none";break;case h.TerminalScanAnalyze1:a.Engine.loadTerminalContent(),b("The 'scan' command shows all available network connections. In other words, it displays a list of all servers that can be connected to from your current machine. A server is identified by either its IP or its hostname.

    That's great and all, but there's so many servers. Which one should you go to? The 'scan-analyze' command gives some more detailed information about servers on the network. Try it now"),s.style.display="none";break;case h.TerminalScanAnalyze2:a.Engine.loadTerminalContent(),b("You just ran 'scan-analyze' with a depth of one. This command shows more detailed information about each server that you can connect to (servers that are a distance of one node away).

    It is also possible to run 'scan-analyze' with a higher depth. Let's try a depth of two with the following command: 'scan-analyze 2'."),s.style.display="none";break;case h.TerminalConnect:a.Engine.loadTerminalContent(),b("Now you can see information about all servers that are up to two nodes away, as well as figure out how to navigate to those servers through the network. You can only connect to a server that is one node away. To connect to a machine, use the 'connect [ip/hostname]' command. You can type in the ip or the hostname, but dont use both.

    From the results of the 'scan-analyze' command, we can see that the 'foodnstuff' server is only one node away. Let's connect so it now using: 'connect foodnstuff'"),s.style.display="none";break;case h.TerminalAnalyze:a.Engine.loadTerminalContent(),b("You are now connected to another machine! What can you do now? You can hack it!

    In the year 2077, currency has become digital and decentralized. People and corporations store their money on servers and computers. Using your hacking abilities, you can hack servers to steal money and gain experience.

    Before you try to hack a server, you should run diagnostics using the 'analyze' command"),s.style.display="none";break;case h.TerminalNuke:a.Engine.loadTerminalContent(),b("When the 'analyze' command finishes running it will show useful information about hacking the server.

    For this server, the required hacking skill is only 1, which means you can hack it right now. However, in order to hack a server you must first gain root access. The 'NUKE.exe' program that we saw earlier on your home computer is a virus that will grant you root access to a machine if there are enough open ports.

    The 'analyze' results shows that there do not need to be any open ports on this machine for the NUKE virus to work, so go ahead and run the virus using the 'run NUKE.exe' command."),s.style.display="none";break;case h.TerminalManualHack:a.Engine.loadTerminalContent(),b("You now have root access! You can hack the server using the 'hack' command. Try doing that now."),s.style.display="none";break;case h.TerminalHackingMechanics:a.Engine.loadTerminalContent(),b("You are now attempting to hack the server. Note that performing a hack takes time and only has a certain percentage chance of success. This time and success chance is determined by a variety of factors, including your hacking skill and the server's security level.

    If your attempt to hack the server is successful, you will steal a certain percentage of the server's total money. This percentage is affected by your hacking skill and the server's security level.

    The amount of money on a server is not limitless. So, if you constantly hack a server and deplete its money, then you will encounter diminishing returns in your hacking."),s.style.display="inline-block";break;case h.TerminalCreateScript:a.Engine.loadTerminalContent(),b("Hacking is the core mechanic of the game and is necessary for progressing. However, you don't want to be hacking manually the entire time. You can automate your hacking by writing scripts!

    To create a new script or edit an existing one, you can use the 'nano' command. Scripts must end with the '.script' extension. Let's make a script now by entering 'nano foodnstuff.script' after the hack command finishes running (Sidenote: Pressing ctrl + c will end a command like hack early)"),s.style.display="none";break;case h.TerminalTypeScript:a.Engine.loadScriptEditorContent("foodnstuff.script",""),b("This is the script editor. You can use it to program your scripts. Scripts are written in the Netscript language, a programming language created for this game. There are details about the Netscript language in the documentation, which can be accessed in the 'Tutorial' tab on the main navigation menu. I highly suggest you check it out after this tutorial. For now, just copy and paste the following code into the script editor:

    while(true) {
      hack('foodnstuff');
    }

    For anyone with basic programming experience, this code should be straightforward. This script will continuously hack the 'foodnstuff' server.

    To save and close the script editor, press the button in the bottom left, or press ctrl + b."),s.style.display="none";break;case h.TerminalFree:a.Engine.loadTerminalContent(),b("Now we'll run the script. Scripts require a certain amount of RAM to run, and can be run on any machine which you have root access to. Different servers have different amounts of RAM. You can also purchase more RAM for your home server.

    To check how much RAM is available on this machine, enter the 'free' command."),s.style.display="none";break;case h.TerminalRunScript:a.Engine.loadTerminalContent(),b("We have 16GB of free RAM on this machine, which is enough to run our script. Let's run our script using 'run foodnstuff.script'."),s.style.display="none";break;case h.TerminalGoToActiveScriptsPage:a.Engine.loadTerminalContent(),b("Your script is now running! The script might take a few seconds to 'fully start up'. Your scripts will continuously run in the background and will automatically stop if the code ever completes (the 'foodnstuff.script' will never complete because it runs an infinite loop).

    These scripts can passively earn you income and hacking experience. Your scripts will also earn money and experience while you are offline, although at a much slower rate.

    Let's check out some statistics for our running scripts by clicking the 'Active Scripts' link in the main navigation menu."),s.style.display="none",n.setAttribute("class","flashing-button"),n.addEventListener("click",function(){return a.Engine.loadActiveScriptsContent(),f(),!1});break;case h.ActiveScriptsPage:a.Engine.loadActiveScriptsContent(),b("This page displays stats/information about all of your scripts that are running across every existing server. You can use this to gauge how well your scripts are doing. Let's go back to the Terminal now using the 'Terminal'link."),s.style.display="none",e.setAttribute("class","flashing-button"),e.addEventListener("click",function(){return a.Engine.loadTerminalContent(),f(),!1});break;case h.ActiveScriptsToTerminal:a.Engine.loadTerminalContent(),b("One last thing about scripts, each active script contains logs that detail what it's doing. We can check these logs using the 'tail' command. Do that now for the script we just ran by typing 'tail foodnstuff.script'"),s.style.display="none";break;case h.TerminalTailScript:a.Engine.loadTerminalContent(),b("The log for this script won't show much right now (it might show nothing at all) because it just started running...but check back again in a few minutes!

    This pretty much covers the basics of hacking. To learn more about writing scripts using the Netscript language, select the 'Tutorial' link in the main navigation menu to look at the documentation. If you are an experienced JavaScript developer, I would highly suggest you check out the section on NetscriptJS/Netscript 2.0.

    For now, let's move on to something else!"),s.style.display="inline-block";break;case h.GoToHacknetNodesPage:a.Engine.loadTerminalContent(),b("Hacking is not the only way to earn money. One other way to passively earn money is by purchasing and upgrading Hacknet Nodes. Let's go to the 'Hacknet Nodes' page through the main navigation menu now."),s.style.display="none",i.setAttribute("class","flashing-button"),i.addEventListener("click",function(){return a.Engine.loadHacknetNodesContent(),f(),!1});break;case h.HacknetNodesIntroduction:a.Engine.loadHacknetNodesContent(),b("From this page you can purchase new Hacknet Nodes and upgrade your existing ones. Let's purchase a new one now."),s.style.display="none";break;case h.HacknetNodesGoToWorldPage:a.Engine.loadHacknetNodesContent(),b("You just purchased a Hacknet Node! This Hacknet Node will passively earn you money over time, both online and offline. When you get enough money, you can upgrade your newly-purchased Hacknet Node below.

    Let's go to the 'City' page through the main navigation menu."),s.style.display="none",r.setAttribute("class","flashing-button"),r.addEventListener("click",function(){return a.Engine.loadWorldContent(),f(),!1});break;case h.WorldDescription:a.Engine.loadWorldContent(),b("This page lists all of the different locations you can currently travel to. Each location has something that you can do. There's a lot of content out in the world, make sure you explore and discover!

    Lastly, click on the 'Tutorial' link in the main navigation menu."),s.style.display="none",o.setAttribute("class","flashing-button"),o.addEventListener("click",function(){return a.Engine.loadTutorialContent(),f(),!1});break;case h.TutorialPageInfo:a.Engine.loadTutorialContent(),b("This page contains a lot of different documentation about the game's content and mechanics. I know it's a lot, but I highly suggest you read (or at least skim) through this before you start playing. That's the end of the tutorial. Hope you enjoy the game!"),s.style.display="inline-block",s.innerHTML="Finish Tutorial";break;case h.End:y();break;default:throw new Error("Invalid tutorial step")}!0===d.stepIsDone[d.currStep]&&(s.style.display="inline-block")}else console.log("Interactive Tutorial not running")}function f(){d.currStep===h.GoToCharacterPage&&document.getElementById("stats-menu-link").removeAttribute("class"),d.currStep===h.CharacterGoToTerminalPage&&document.getElementById("terminal-menu-link").removeAttribute("class"),d.currStep===h.TerminalGoToActiveScriptsPage&&document.getElementById("active-scripts-menu-link").removeAttribute("class"),d.currStep===h.ActiveScriptsPage&&document.getElementById("terminal-menu-link").removeAttribute("class"),d.currStep===h.GoToHacknetNodesPage&&document.getElementById("hacknet-nodes-menu-link").removeAttribute("class"),d.currStep===h.HacknetNodesGoToWorldPage&&document.getElementById("city-menu-link").removeAttribute("class"),d.currStep===h.WorldDescription&&document.getElementById("tutorial-menu-link").removeAttribute("class"),d.stepIsDone[d.currStep]=!0,d.currStep
    Getting Started GuideDocumentation

    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 hackers-starting-handbook.lit"}),n=Object(c.createElement)("a",{class:"a-link-button",float:"right",padding:"6px",innerText:"Got it!",clickListener:()=>{Object(p.removeElementById)(e)}});Object(u.createPopup)(e,[t,n]),i.a.getHomeComputer().messages.push("hackers-starting-handbook.lit")}function b(e){var t=document.getElementById("interactive-tutorial-text");if(null==t)throw new Error("Could not find text box");t.innerHTML=e,t.parentElement.scrollTop=0}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.SoftwareCompanyPositions=["Software Engineering Intern","Junior Software Engineer","Senior Software Engineer","Lead Software Developer","Head of Software","Head of Engineering","Vice President of Technology","Chief Technology Officer"],t.ITCompanyPositions=["IT Intern","IT Analyst","IT Manager","Systems Administrator"],t.SecurityEngineerCompanyPositions=["Security Engineer"],t.NetworkEngineerCompanyPositions=["Network Engineer","Network Administrator"],t.BusinessCompanyPositions=["Business Intern","Business Analyst","Business Manager","Operations Manager","Chief Financial Officer","Chief Executive Officer"],t.SecurityCompanyPositions=["Police Officer","Police Chief","Security Guard","Security Officer","Security Supervisor","Head of Security"],t.AgentCompanyPositions=["Field Agent","Secret Agent","Special Operative"],t.MiscCompanyPositions=["Waiter","Employee"],t.SoftwareConsultantCompanyPositions=["Software Consultant","Senior Software Consultant"],t.BusinessConsultantCompanyPositions=["Business Consultant","Senior Business Consultant"],t.PartTimeCompanyPositions=["Part-time Waiter","Part-time Employee"]},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const a=n(9);t.exceptionAlert=function(e){console.error(e),a.dialogBoxCreate("Caught an exception: "+e+"

    Filename: "+(e.fileName||"UNKNOWN FILE NAME")+"

    Line Number: "+(e.lineNumber||"UNKNOWN LINE NUMBER")+"

    This is a bug, please report to game developer with this message as well as details about how to reproduce the bug.

    If you want to be safe, I suggest refreshing the game WITHOUT saving so that your safe doesn't get corrupted",!1)}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.isString=function(e){return"string"==typeof e||e instanceof String}},function(e,t,n){"use strict";n.d(t,"b",function(){return o}),n.d(t,"a",function(){return s});var a=n(0),i=n(66),r=n(8);function o(e,t){return`gang.${e}() failed with exception: `+t}function s(e,t){const n=`gang.${t}() failed because you do not currently have a Gang`;if(!(a.a.gang instanceof i.b))throw Object(r.d)(e,n)}},,function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e){e.Ace="ace",e.Emacs="emacs",e.Vim="vim"}(t.AceKeybindingSetting||(t.AceKeybindingSetting={})),function(e){e.Default="default",e.Emacs="emacs",e.Sublime="sublime",e.Vim="vim"}(t.CodeMirrorKeybindingSetting||(t.CodeMirrorKeybindingSetting={})),function(e){e.Monokai="monokai",e.Day_3024="3024-day",e.Night_3024="3024-night",e.abcdef="abcdef",e.Ambiance_mobile="ambiance-mobile",e.Ambiance="ambiance",e.Base16_dark="base16-dark",e.Base16_light="base16-light",e.Bespin="bespin",e.Blackboard="blackboard",e.Cobalt="cobalt",e.Colorforth="colorforth",e.Darcula="darcula",e.Dracula="dracula",e.Duotone_dark="duotone-dark",e.Duotone_light="duotone-light",e.Eclipse="eclipse",e.Elegant="elegant",e.Erlang_dark="erlang-dark",e.Gruvbox_dark="gruvbox-dark",e.Hopscotch="hopscotch",e.Icecoder="icecoder",e.Idea="idea",e.Isotope="isotope",e.Lesser_dark="lesser-dark",e.Liquibyte="liquibyte",e.Lucario="lucario",e.Material="material",e.Mbo="mbo",e.Mdn_like="mdn-like",e.Midnight="midnight",e.Neat="neat",e.Neo="neo",e.Night="night",e.Oceanic_next="oceanic-next",e.Panda_syntax="panda-syntax",e.Paraiso_dark="paraiso-dark",e.Paraiso_light="paraiso-light",e.Pastel_on_dark="pastel-on-dark",e.Railscasts="railscasts",e.Rubyblue="rubyblue",e.Seti="seti",e.Shadowfox="shadowfox",e.Solarized="solarized",e.ssms="ssms",e.The_matrix="the-matrix",e.Tomorrow_night_bright="tomorrow-night-bright",e.Tomorrow_night_eighties="tomorrow-night-eighties",e.Ttcn="ttcn",e.Twilight="twilight",e.Vibrant_ink="vibrant-ink",e.xq_dark="xq-dark",e.xq_light="xq-light",e.Yeti="yeti",e.Zenburn="zenburn"}(t.CodeMirrorThemeSetting||(t.CodeMirrorThemeSetting={})),function(e){e.Ace="Ace",e.CodeMirror="CodeMirror"}(t.EditorSetting||(t.EditorSetting={})),function(e){e[e.Cost=0]="Cost",e[e.Default=1]="Default",e[e.Reputation=2]="Reputation"}(t.PurchaseAugmentationsOrderSetting||(t.PurchaseAugmentationsOrderSetting={})),function(e){e[e.Alphabetically=0]="Alphabetically",e[e.AcquirementTime=1]="AcquirementTime"}(t.OwnedAugmentationsOrderSetting||(t.OwnedAugmentationsOrderSetting={}))},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const a=n(169),i=n(1);t.Crimes={Shoplift:new a.Crime("Shoplift",i.CONSTANTS.CrimeShoplift,2e3,15e3,.05,.1,{dexterity_success_weight:1,agility_success_weight:1,dexterity_exp:2,agility_exp:2}),RobStore:new a.Crime("Rob Store",i.CONSTANTS.CrimeRobStore,6e4,4e5,.2,.5,{hacking_exp:30,dexterity_exp:45,agility_exp:45,hacking_success_weight:.5,dexterity_success_weight:2,agility_success_weight:1,intelligence_exp:.25*i.CONSTANTS.IntelligenceCrimeBaseExpGain}),Mug:new a.Crime("Mug",i.CONSTANTS.CrimeMug,4e3,36e3,.2,.25,{strength_exp:3,defense_exp:3,dexterity_exp:3,agility_exp:3,strength_success_weight:1.5,defense_success_weight:.5,dexterity_success_weight:1.5,agility_success_weight:.5}),Larceny:new a.Crime("Larceny",i.CONSTANTS.CrimeLarceny,9e4,8e5,1/3,1.5,{hacking_exp:45,dexterity_exp:60,agility_exp:60,hacking_success_weight:.5,dexterity_success_weight:1,agility_success_weight:1,intelligence_exp:.5*i.CONSTANTS.IntelligenceCrimeBaseExpGain}),DealDrugs:new a.Crime("Deal Drugs",i.CONSTANTS.CrimeDrugs,1e4,12e4,1,.5,{dexterity_exp:5,agility_exp:5,charisma_exp:10,charisma_success_weight:3,dexterity_success_weight:2,agility_success_weight:1}),BondForgery:new a.Crime("Bond Forgery",i.CONSTANTS.CrimeBondForgery,3e5,45e5,.5,.1,{hacking_exp:100,dexterity_exp:150,charisma_exp:15,hacking_success_weight:.05,dexterity_success_weight:1.25,intelligence_exp:2*i.CONSTANTS.IntelligenceCrimeBaseExpGain}),TraffickArms:new a.Crime("Traffick Arms",i.CONSTANTS.CrimeTraffickArms,4e4,6e5,2,1,{strength_exp:20,defense_exp:20,dexterity_exp:20,agility_exp:20,charisma_exp:40,charisma_success_weight:1,strength_success_weight:1,defense_success_weight:1,dexterity_success_weight:1,agility_success_weight:1}),Homicide:new a.Crime("Homicide",i.CONSTANTS.CrimeHomicide,3e3,45e3,1,3,{strength_exp:2,defense_exp:2,dexterity_exp:2,agility_exp:2,strength_success_weight:2,defense_success_weight:2,dexterity_success_weight:.5,agility_success_weight:.5,kills:1}),GrandTheftAuto:new a.Crime("Grand Theft Auto",i.CONSTANTS.CrimeGrandTheftAuto,8e4,16e5,8,5,{strength_exp:20,defense_exp:20,dexterity_exp:20,agility_exp:80,charisma_exp:40,hacking_success_weight:1,strength_success_weight:1,dexterity_success_weight:4,agility_success_weight:2,charisma_success_weight:2,intelligence_exp:i.CONSTANTS.IntelligenceCrimeBaseExpGain}),Kidnap:new a.Crime("Kidnap",i.CONSTANTS.CrimeKidnap,12e4,36e5,5,6,{strength_exp:80,defense_exp:80,dexterity_exp:80,agility_exp:80,charisma_exp:80,charisma_success_weight:1,strength_success_weight:1,dexterity_success_weight:1,agility_success_weight:1,intelligence_exp:2*i.CONSTANTS.IntelligenceCrimeBaseExpGain}),Assassination:new a.Crime("Assassination",i.CONSTANTS.CrimeAssassination,3e5,12e6,8,10,{strength_exp:300,defense_exp:300,dexterity_exp:300,agility_exp:300,strength_success_weight:1,dexterity_success_weight:2,agility_success_weight:1,intelligence_exp:5*i.CONSTANTS.IntelligenceCrimeBaseExpGain,kills:1}),Heist:new a.Crime("Heist",i.CONSTANTS.CrimeHeist,6e5,12e7,18,15,{hacking_exp:450,strength_exp:450,defense_exp:450,dexterity_exp:450,agility_exp:450,charisma_exp:450,hacking_success_weight:1,strength_success_weight:1,defense_success_weight:1,dexterity_success_weight:1,agility_success_weight:1,charisma_success_weight:1,intelligence_exp:10*i.CONSTANTS.IntelligenceCrimeBaseExpGain})}},function(e,t,n){"use strict";var a=this&&this.__awaiter||function(e,t,n,a){return new(n||(n=Promise))(function(i,r){function o(e){try{l(a.next(e))}catch(e){r(e)}}function s(e){try{l(a.throw(e))}catch(e){r(e)}}function l(e){e.done?i(e.value):new n(function(t){t(e.value)}).then(o,s)}l((a=a.apply(e,t||[])).next())})};Object.defineProperty(t,"__esModule",{value:!0});const i=n(285),r=n(17),o=n(31),s=n(4),l=n(37),c=n(26);class u{constructor(e,t,n,a,i,r){this.name=e,this.desc=t,this.generate=n,this.solver=a,this.difficulty=i,this.numTries=r}}t.CodingContractType=u,t.CodingContractTypes={};for(const e of i.codingContractTypesMetadata)t.CodingContractTypes[e.name]=new u(e.name,e.desc,e.gen,e.solver,e.difficulty,e.numTries);var p;console.info(`${Object.keys(t.CodingContractTypes).length} Coding Contract Types loaded`),function(e){e[e.FactionReputation=0]="FactionReputation",e[e.FactionReputationAll=1]="FactionReputationAll",e[e.CompanyReputation=2]="CompanyReputation",e[e.Money=3]="Money"}(t.CodingContractRewardType||(t.CodingContractRewardType={})),function(e){e[e.Success=0]="Success",e[e.Failure=1]="Failure",e[e.Cancelled=2]="Cancelled"}(p=t.CodingContractResult||(t.CodingContractResult={}));class m{constructor(e="",n="Find Largest Prime Factor",a=null){if(this.tries=0,this.fn=e,this.fn.endsWith(".cct")||(this.fn+=".cct"),null==t.CodingContractTypes[n])throw new Error(`Error: invalid contract type: ${n} please contact developer`);this.type=n,this.data=t.CodingContractTypes[n].generate(),this.reward=a}static fromJSON(e){return r.Generic_fromJSON(m,e.data)}getData(){return this.data}getDescription(){return t.CodingContractTypes[this.type].desc(this.data)}getDifficulty(){return t.CodingContractTypes[this.type].difficulty}getMaxNumTries(){return t.CodingContractTypes[this.type].numTries}getType(){return t.CodingContractTypes[this.type].name}isSolution(e){return t.CodingContractTypes[this.type].solver(this.data,e)}prompt(){return a(this,void 0,void 0,function*(){return new Promise((e,n)=>{const a=t.CodingContractTypes[this.type],i=`coding-contract-prompt-popup-${this.fn}`,r=s.createElement("p",{innerHTML:["You are attempting to solve a Coding Contract. You have",`${this.getMaxNumTries()-this.tries} tries remaining,`,"after which the contract will self-destruct.

    ",`${a.desc(this.data).replace(/\n/g,"
    ")}`].join(" ")});let u,m,h;u=s.createElement("input",{onkeydown:e=>{e.keyCode===o.KEY.ENTER&&""!==u.value?(e.preventDefault(),m.click()):e.keyCode===o.KEY.ESC&&(e.preventDefault(),h.click())},placeholder:"Enter Solution here"}),m=s.createElement("a",{class:"a-link-button",clickListener:()=>{const t=u.value;this.isSolution(t)?e(p.Success):e(p.Failure),c.removeElementById(i)},innerText:"Solve"}),h=s.createElement("a",{class:"a-link-button",clickListener:()=>{e(p.Cancelled),c.removeElementById(i)},innerText:"Cancel"});const d=s.createElement("br");l.createPopup(i,[r,d,d,u,m,h]),u.focus()})})}toJSON(){return r.Generic_toJSON("CodingContract",this)}}t.CodingContract=m,r.Reviver.constructors.CodingContract=m},function(e,t,n){"use strict";(function(e){n.d(t,"a",function(){return ye}),n.d(t,"g",function(){return fe}),n.d(t,"d",function(){return he}),n.d(t,"f",function(){return me}),n.d(t,"h",function(){return ge}),n.d(t,"e",function(){return se}),n.d(t,"b",function(){return ce}),n.d(t,"c",function(){return ue});var a=n(85),i=n(16),r=n(13),o=n(73),s=n(5),l=n(20),c=n(129),u=n(36),p=n(80),m=n(18),h=n(121),d=n(38),g=n(1),_=n(92),f=n(56),y=n(66),b=n(69),v=n(14),E=n(53),k=n(132),C=n(84),T=n(6),O=n(54),S=(n(65),n(72)),M=n(0),P=n(30),A=n(98),w=n(59),x=n(62),R=n(23),N=n(74),I=n(21),L=n(63),D=(n(19),n(40)),B=(n(35),n(29)),W=n(86),j=n(57),F=n(83),U=n(67),H=n(45),G=n(39),K=n(8),q=n(93),$=n(116),Y=n(12),z=n(3),V=n(10),J=n(64),X=n(175),Q=(n(9),n(151),n(70)),Z=n(90),ee=n(7),te=n(44),ne=n(4),ae=n(37),ie=n(26),re=n(206).sprintf,oe=n(206).vsprintf,se=!1,le=!1,ce=!1,ue=!1,pe=!1,me=!1,he=!1,de=1,ge=1,_e={ALL:!0,scan:!0,hack:!0,sleep:!0,disableLog:!0,enableLog:!0,grow:!0,weaken:!0,nuke:!0,brutessh:!0,ftpcrack:!0,relaysmtp:!0,httpworm:!0,sqlinject:!0,run:!0,exec:!0,spawn:!0,kill:!0,killall:!0,scp:!0,getHackingLevel:!0,getServerMoneyAvailable:!0,getServerSecurityLevel:!0,getServerBaseSecurityLevel:!0,getServerMinSecurityLevel:!0,getServerRequiredHackingLevel:!0,getServerMaxMoney:!0,getServerGrowth:!0,getServerNumPortsRequired:!0,getServerRam:!0,buyStock:!0,sellStock:!0,shortStock:!0,sellShort:!0,purchase4SMarketData:!0,purchase4SMarketDataTixApi:!0,purchaseServer:!0,deleteServer:!0,universityCourse:!0,gymWorkout:!0,travelToCity:!0,purchaseTor:!0,purchaseProgram:!0,stopAction:!0,upgradeHomeRam:!0,workForCompany:!0,applyToCompany:!0,joinFaction:!0,workForFaction:!0,donateToFaction:!0,createProgram:!0,commitCrime:!0,startAction:!0,upgradeSkill:!0,setTeamSize:!0,joinBladeburnerFaction:!0,recruitMember:!0,setMemberTask:!0,purchaseEquipment:!0,setTerritoryWarfare:!0};function fe(){for(var e=0;e1.01*t.ramUsage)throw Object(K.d)(t,"Dynamic RAM usage calculated to be greater than initial RAM usage on fn: "+e+". This is probably because you somehow circumvented the static RAM calculation.

    Please don't do that :(

    Dynamic RAM Usage: "+t.dynamicRamUsage+"
    Static RAM Usage: "+t.ramUsage)},se=function(e,n){return t.loadedFns[e]?0:(t.loadedFns[e]=!0,n)},ue=function(e,n=""){var a=Object(I.getServer)(e);if(null==a)throw Object(K.d)(t,`Invalid IP or hostname passed into ${n}() function`);return a},he=function(e){if(isNaN(e))throw Object(K.d)(t,"Invalid index specified for Hacknet Node: "+e);if(e<0||e>=M.a.hacknetNodes.length)throw Object(K.d)(t,"Index specified for Hacknet Node is out-of-bounds: "+e);return M.a.hacknetNodes[e]},fe=function(e,t){return ue(t,"getCodingContract").getContract(e)};return{hacknet:{numNodes:function(){return M.a.hacknetNodes.length},purchaseNode:function(){return Object(C.e)()},getPurchaseNodeCost:function(){return Object(C.c)()},getNodeStats:function(e){var t=he(e);return{name:t.name,level:t.level,ram:t.ram,cores:t.cores,production:t.moneyGainRatePerSecond,timeOnline:t.onlineTimeSeconds,totalProduction:t.totalMoneyGenerated}},upgradeLevel:function(e,t){return he(e).purchaseLevelUpgrade(t)},upgradeRam:function(e,t){return he(e).purchaseRamUpgrade(t)},upgradeCore:function(e,t){return he(e).purchaseCoreUpgrade(t)},getLevelUpgradeCost:function(e,t){return he(e).calculateLevelUpgradeCost(t)},getRamUpgradeCost:function(e,t){return he(e).calculateRamUpgradeCost(t)},getCoreUpgradeCost:function(e,t){return he(e).calculateCoreUpgradeCost(t)}},sprintf:re,vsprintf:oe,scan:function(e=t.serverIp,a=!0){if(t.checkingRam)return se("scan",g.CONSTANTS.ScriptScanRamCost);n("scan",g.CONSTANTS.ScriptScanRamCost);var i=Object(I.getServer)(e);if(null==i)throw Object(K.d)(t,"Invalid IP or hostname passed into scan() command");for(var r=[],o=0;oM.a.hacking_skill)throw t.scriptRef.log("Cannot hack this server ("+i.hostname+") because user's hacking skill is not high enough"),Object(K.d)(t,"Cannot hack this server ("+i.hostname+") because user's hacking skill is not high enough");return null==t.disableLogs.ALL&&null==t.disableLogs.hack&&t.scriptRef.log("Attempting to hack "+e+" in "+r.toFixed(3)+" seconds (t="+a+")"),Object(K.e)(1e3*r,t).then(function(){if(t.env.stopFlag)return Promise.reject(t);var e=Object(f.b)(i),n=Math.random(),r=Object(f.c)(i)*a,o=r/4;if(ni.moneyAvailable&&(s=i.moneyAvailable),i.moneyAvailable-=s,i.moneyAvailable<0&&(i.moneyAvailable=0),M.a.gainMoney(s),t.scriptRef.onlineMoneyMade+=s,M.a.scriptProdSinceLastAug+=s,M.a.recordMoneySource(s,"hacking"),t.scriptRef.recordHack(i.ip,s,a),M.a.gainHackingExp(r),t.scriptRef.onlineExpGained+=r,null==t.disableLogs.ALL&&null==t.disableLogs.hack&&t.scriptRef.log("Script SUCCESSFULLY hacked "+i.hostname+" for $"+Object(ee.formatNumber)(s,2)+" and "+Object(ee.formatNumber)(r,4)+" exp (t="+a+")"),i.fortify(g.CONSTANTS.ServerFortifyAmount*Math.min(a,n)),Promise.resolve(s)}return M.a.gainHackingExp(o),t.scriptRef.onlineExpGained+=o,null==t.disableLogs.ALL&&null==t.disableLogs.hack&&t.scriptRef.log("Script FAILED to hack "+i.hostname+". Gained "+Object(ee.formatNumber)(o,4)+" exp (t="+a+")"),Promise.resolve(0)})},hackAnalyzeThreads:function(e,a){if(t.checkingRam)return se("hackAnalyzeThreads",g.CONSTANTS.ScriptHackAnalyzeRamCost);n("hackAnalyzeThreads",g.CONSTANTS.ScriptHackAnalyzeRamCost);const i=ue(e,"hackAnalyzeThreads");if(isNaN(a))throw Object(K.d)(t,`Invalid growth argument passed into hackAnalyzeThreads: ${a}. Must be numeric`);if(a<0||a>i.moneyAvailable)return-1;const r=Object(f.e)(i);return a/Math.floor(i.moneyAvailable*r)},hackAnalyzePercent:function(e){if(t.checkingRam)return se("hackAnalyzePercent",g.CONSTANTS.ScriptHackAnalyzeRamCost);n("hackAnalyzePercent",g.CONSTANTS.ScriptHackAnalyzeRamCost);const a=ue(e,"hackAnalyzePercent");return 100*Object(f.e)(a)},hackChance:function(e){if(t.checkingRam)return se("hackChance",g.CONSTANTS.ScriptHackAnalyzeRamCost);n("hackChance",g.CONSTANTS.ScriptHackAnalyzeRamCost);const a=ue(e,"hackChance");return Object(f.b)(a)},sleep:function(e){if(t.checkingRam)return 0;if(void 0===e)throw Object(K.d)(t,"sleep() call has incorrect number of arguments. Takes 1 argument");return null==t.disableLogs.ALL&&null==t.disableLogs.sleep&&t.scriptRef.log("Sleeping for "+e+" milliseconds"),Object(K.e)(e,t).then(function(){return Promise.resolve(!0)})},grow:function(e){if(t.checkingRam)return se("grow",g.CONSTANTS.ScriptGrowRamCost);n("grow",g.CONSTANTS.ScriptGrowRamCost);var a=t.scriptRef.threads;if((isNaN(a)||a<1)&&(a=1),void 0===e)throw Object(K.d)(t,"grow() call has incorrect number of arguments. Takes 1 argument");var i=Object(I.getServer)(e);if(null==i)throw t.scriptRef.log("Cannot grow(). Invalid IP or hostname passed in: "+e),Object(K.d)(t,"Cannot grow(). Invalid IP or hostname passed in: "+e);if(0==i.hasAdminRights)throw t.scriptRef.log("Cannot grow this server ("+i.hostname+") because user does not have root access"),Object(K.d)(t,"Cannot grow this server ("+i.hostname+") because user does not have root access");var r=Object(f.a)(i);return null==t.disableLogs.ALL&&null==t.disableLogs.grow&&t.scriptRef.log("Executing grow() on server "+i.hostname+" in "+Object(ee.formatNumber)(r,3)+" seconds (t="+a+")"),Object(K.e)(1e3*r,t).then(function(){if(t.env.stopFlag)return Promise.reject(t);const e=i.moneyAvailable<=0?1:i.moneyAvailable;i.moneyAvailable+=1*a;var n=Object(I.processSingleServerGrowth)(i,450*a,M.a);const r=i.moneyAvailable;t.scriptRef.recordGrow(i.ip,a);var o=Object(f.c)(i)*a;return 1==n&&(o=0),null==t.disableLogs.ALL&&null==t.disableLogs.grow&&t.scriptRef.log("Available money on "+i.hostname+" grown by "+Object(ee.formatNumber)(r/e*100-100,6)+"%. Gained "+Object(ee.formatNumber)(o,4)+" hacking exp (t="+a+")"),t.scriptRef.onlineExpGained+=o,M.a.gainHackingExp(o),Promise.resolve(r/e)})},growthAnalyze:function(e,a){if(t.checkingRam)return se("growthAnalyze",g.CONSTANTS.ScriptGrowthAnalyzeRamCost);n("growthAnalyze",g.CONSTANTS.ScriptGrowthAnalyzeRamCost);const i=ue(e,"growthAnalyze");if(isNaN(a))throw Object(K.d)(t,`Invalid growth argument passed into growthAnalyze: ${a}. Must be numeric`);return Object(I.numCycleForGrowth)(i,Number(a),M.a)},weaken:function(e){if(t.checkingRam)return se("weaken",g.CONSTANTS.ScriptWeakenRamCost);n("weaken",g.CONSTANTS.ScriptWeakenRamCost);var a=t.scriptRef.threads;if((isNaN(a)||a<1)&&(a=1),void 0===e)throw Object(K.d)(t,"weaken() call has incorrect number of arguments. Takes 1 argument");var i=Object(I.getServer)(e);if(null==i)throw t.scriptRef.log("Cannot weaken(). Invalid IP or hostname passed in: "+e),Object(K.d)(t,"Cannot weaken(). Invalid IP or hostname passed in: "+e);if(0==i.hasAdminRights)throw t.scriptRef.log("Cannot weaken this server ("+i.hostname+") because user does not have root access"),Object(K.d)(t,"Cannot weaken this server ("+i.hostname+") because user does not have root access");var r=Object(f.f)(i);return null==t.disableLogs.ALL&&null==t.disableLogs.weaken&&t.scriptRef.log("Executing weaken() on server "+i.hostname+" in "+Object(ee.formatNumber)(r,3)+" seconds (t="+a+")"),Object(K.e)(1e3*r,t).then(function(){if(t.env.stopFlag)return Promise.reject(t);i.weaken(g.CONSTANTS.ServerWeakenAmount*a),t.scriptRef.recordWeaken(i.ip,a);var e=Object(f.c)(i)*a;return null==t.disableLogs.ALL&&null==t.disableLogs.weaken&&t.scriptRef.log("Server security level on "+i.hostname+" weakened to "+i.hackDifficulty+". Gained "+Object(ee.formatNumber)(e,4)+" hacking exp (t="+a+")"),t.scriptRef.onlineExpGained+=e,M.a.gainHackingExp(e),Promise.resolve(g.CONSTANTS.ServerWeakenAmount*a)})},print:function(e){if(t.checkingRam)return 0;if(void 0===e)throw Object(K.d)(t,"print() call has incorrect number of arguments. Takes 1 argument");t.scriptRef.log(e.toString())},tprint:function(e){if(t.checkingRam)return 0;if(void 0===e||null==e)throw Object(K.d)(t,"tprint() call has incorrect number of arguments. Takes 1 argument");e.toString();Object(V.post)(t.scriptRef.filename+": "+e.toString())},clearLog:function(){if(t.checkingRam)return 0;t.scriptRef.clearLog()},disableLog:function(e){if(t.checkingRam)return 0;if(void 0===_e[e])throw Object(K.d)(t,"Invalid argument to disableLog: "+e);t.disableLogs[e]=!0,null==t.disableLogs.ALL&&null==t.disableLogs.disableLog&&t.scriptRef.log("Disabled logging for "+e)},enableLog:function(e){if(t.checkingRam)return 0;if(void 0===_e[e])throw Object(K.d)(t,"Invalid argument to enableLog: "+e);delete t.disableLogs[e],null==t.disableLogs.ALL&&null==t.disableLogs.enableLog&&t.scriptRef.log("Enabled logging for "+e)},isLogEnabled:function(e){if(t.checkingRam)return 0;if(void 0===_e[e])throw Object(K.d)(t,"Invalid argument to isLogEnabled: "+e);return!t.disableLogs[e]},getScriptLogs:function(e,n){if(t.checkingRam)return 0;if(null!=e&&"string"==typeof e){null==n&&(n=t.serverIp);const a=Object(I.getServer)(n);if(null==a)throw t.log(`getScriptLogs() failed. Invalid IP or hostname passed in: ${n}`),Object(K.d)(t,`getScriptLogs() failed. Invalid IP or hostname passed in: ${n}`);let i=[];for(let e=2;e{if(void 0===e)throw Object(K.d)(t,"spawn() call has incorrect number of arguments. Usage: spawn(scriptname, numThreads, [arg1], [arg2]...)");if(isNaN(a)||a<0)throw Object(K.d)(t,"Invalid argument for thread count passed into run(). Must be numeric and greater than 0");for(var n=[],i=2;i0,r=a.runningScripts.length-1;r>=0;--r)Object(G.d)(a.runningScripts[r],a.ip);return null==t.disableLogs.ALL&&null==t.disableLogs.killall&&t.scriptRef.log("killall(): Killing all scripts on "+a.hostname+". May take a few minutes for the scripts to die"),i},exit:function(){if(t.checkingRam)return 0;var e=Object(I.getServer)(t.serverIp);if(null==e)throw Object(K.d)(t,"Error getting Server for this script in exit(). This is a bug please contact game dev");Object(G.d)(t.scriptRef,e.ip)?t.scriptRef.log("Exiting..."):t.scriptRef.log("Exit failed(). This is a bug please contact game developer")},scp:function(e,a,i){if(t.checkingRam)return se("scp",g.CONSTANTS.ScriptScpRamCost);if(n("scp",g.CONSTANTS.ScriptScpRamCost),2!==arguments.length&&3!==arguments.length)throw Object(K.d)(t,"ERROR: scp() call has incorrect number of arguments. Takes 2 or 3 arguments");if(e&&e.constructor===Array){var r=!1;return e.forEach(function(e){ye(t).scp(e,a,i)&&(r=!0)}),r}if(!e.endsWith(".lit")&&!Object(x.isScriptFilename)(e)&&!e.endsWith("txt"))throw Object(K.d)(t,"ERROR: scp() does not work with this file type. It only works for .script, .lit, and .txt files");var o,s;if(null!=i){if(void 0===e||void 0===a||void 0===i)throw Object(K.d)(t,"ERROR: scp() call has incorrect number of arguments. Takes 2 or 3 arguments");if(null==(o=Object(I.getServer)(i)))throw Object(K.d)(t,`ERROR: Invalid hostname/ip passed into scp() command: ${i}`);if(null==(s=Object(I.getServer)(a)))throw Object(K.d)(t,`ERROR: Invalid hostname/ip passed into scp() command: ${a}`)}else{if(null==a)throw Object(K.d)(t,"ERROR: scp() call has incorrect number of arguments. Takes 2 or 3 arguments");if(void 0===e||void 0===a)throw Object(K.d)(t,"ERROR: scp() call has incorrect number of arguments. Takes 2 or 3 arguments");if(null==(o=Object(I.getServer)(a)))throw Object(K.d)(t,`ERROR: Invalid hostname/ip passed into scp() command: ${a}`);if(null==(s=Object(I.getServer)(t.serverIp)))throw Object(K.d)(t,"Could not find server ip for this script. This is a bug please contact game developer")}if(e.endsWith(".lit")){for(var l=!1,c=0;c=2&&(r=a.toString());for(var o=[],s=0;si.maxShares)return t.scriptRef.log(`You cannot purchase this many shares. ${i.symbol} has a maximum of `+`${i.maxShares} shares.`),0;var o=i.playerShares*i.playerAvgPx;M.a.loseMoney(r+g.CONSTANTS.StockMarketCommission);var s=o+r;return i.playerShares+=a,i.playerAvgPx=s/i.playerShares,Y.routing.isOn(Y.Page.StockMarket)&&Object(B.r)(i),null==t.disableLogs.ALL&&null==t.disableLogs.buyStock&&t.scriptRef.log("Bought "+Object(ee.formatNumber)(a,0)+" shares of "+i.symbol+" at $"+Object(ee.formatNumber)(i.price,2)+" per share"),i.price},sellStock:function(e,a){if(t.checkingRam)return se("sellStock",g.CONSTANTS.ScriptBuySellStockRamCost);if(n("sellStock",g.CONSTANTS.ScriptBuySellStockRamCost),!M.a.hasTixApiAccess)throw Object(K.d)(t,"You don't have TIX API Access! Cannot use sellStock()");var i=B.e[e];if(null==i)throw Object(K.d)(t,"Invalid stock symbol passed into sellStock()");if(a<0||isNaN(a))return t.scriptRef.log("ERROR: Invalid 'shares' argument passed to sellStock()"),0;if((a=Math.round(a))>i.playerShares&&(a=i.playerShares),0===a)return 0;var r=i.price*a-g.CONSTANTS.StockMarketCommission;M.a.gainMoney(r);var o=(i.price-i.playerAvgPx)*a-g.CONSTANTS.StockMarketCommission;return isNaN(o)&&(o=0),t.scriptRef.onlineMoneyMade+=o,M.a.scriptProdSinceLastAug+=o,M.a.recordMoneySource(o,"stock"),i.playerShares-=a,0==i.playerShares&&(i.playerAvgPx=0),Y.routing.isOn(Y.Page.StockMarket)&&Object(B.r)(i),null==t.disableLogs.ALL&&null==t.disableLogs.sellStock&&t.scriptRef.log("Sold "+Object(ee.formatNumber)(a,0)+" shares of "+i.symbol+" at $"+Object(ee.formatNumber)(i.price,2)+" per share. Gained $"+Object(ee.formatNumber)(r,2)),i.price},shortStock(e,a){if(t.checkingRam)return se("shortStock",g.CONSTANTS.ScriptBuySellStockRamCost);if(n("shortStock",g.CONSTANTS.ScriptBuySellStockRamCost),!M.a.hasTixApiAccess)throw Object(K.d)(t,"You don't have TIX API Access! Cannot use shortStock()");if(8!==M.a.bitNodeN&&!(me&&ge>=2))throw Object(K.d)(t,"ERROR: Cannot use shortStock(). You must either be in BitNode-8 or you must have Level 2 of Source-File 8");var i=B.e[e];if(null==i)throw Object(K.d)(t,"ERROR: Invalid stock symbol passed into shortStock()");return Object(B.p)(i,a,t)?i.price:0},sellShort(e,a){if(t.checkingRam)return se("sellShort",g.CONSTANTS.ScriptBuySellStockRamCost);if(n("sellShort",g.CONSTANTS.ScriptBuySellStockRamCost),!M.a.hasTixApiAccess)throw Object(K.d)(t,"You don't have TIX API Access! Cannot use sellShort()");if(8!==M.a.bitNodeN&&!(me&&ge>=2))throw Object(K.d)(t,"ERROR: Cannot use sellShort(). You must either be in BitNode-8 or you must have Level 2 of Source-File 8");var i=B.e[e];if(null==i)throw Object(K.d)(t,"ERROR: Invalid stock symbol passed into sellShort()");return Object(B.n)(i,a,t)?i.price:0},placeOrder(e,a,i,r,o){if(t.checkingRam)return se("placeOrder",g.CONSTANTS.ScriptBuySellStockRamCost);if(n("placeOrder",g.CONSTANTS.ScriptBuySellStockRamCost),!M.a.hasTixApiAccess)throw Object(K.d)(t,"You don't have TIX API Access! Cannot use placeOrder()");if(8!==M.a.bitNodeN&&!(me&&ge>=3))throw Object(K.d)(t,"ERROR: Cannot use placeOrder(). You must either be in BitNode-8 or have Level 3 of Source-File 8");var s,l,c=B.e[e];if(null==c)throw Object(K.d)(t,"ERROR: Invalid stock symbol passed into placeOrder()");if((r=r.toLowerCase()).includes("limit")&&r.includes("buy"))s=B.a.LimitBuy;else if(r.includes("limit")&&r.includes("sell"))s=B.a.LimitSell;else if(r.includes("stop")&&r.includes("buy"))s=B.a.StopBuy;else{if(!r.includes("stop")||!r.includes("sell"))throw Object(K.d)(t,"ERROR: Invalid Order Type passed into placeOrder()");s=B.a.StopSell}if((o=o.toLowerCase()).includes("l"))l=B.b.Long;else{if(!o.includes("s"))throw Object(K.d)(t,"ERROR: Invalid Position Type passed into placeOrder()");l=B.b.Short}return Object(B.l)(c,a,i,s,l,t)},cancelOrder(e,a,i,r,o){if(t.checkingRam)return se("cancelOrder",g.CONSTANTS.ScriptBuySellStockRamCost);if(n("cancelOrder",g.CONSTANTS.ScriptBuySellStockRamCost),!M.a.hasTixApiAccess)throw Object(K.d)(t,"You don't have TIX API Access! Cannot use cancelOrder()");if(8!==M.a.bitNodeN&&!(me&&ge>=3))throw Object(K.d)(t,"ERROR: Cannot use cancelOrder(). You must either be in BitNode-8 or have Level 3 of Source-File 8");var s,l,c=B.e[e];if(null==c)throw Object(K.d)(t,"ERROR: Invalid stock symbol passed into cancelOrder()");if(isNaN(a)||isNaN(i))throw Object(K.d)(t,"ERROR: Invalid shares or price argument passed into cancelOrder(). Must be numeric");if((r=r.toLowerCase()).includes("limit")&&r.includes("buy"))s=B.a.LimitBuy;else if(r.includes("limit")&&r.includes("sell"))s=B.a.LimitSell;else if(r.includes("stop")&&r.includes("buy"))s=B.a.StopBuy;else{if(!r.includes("stop")||!r.includes("sell"))throw Object(K.d)(t,"ERROR: Invalid Order Type passed into placeOrder()");s=B.a.StopSell}if((o=o.toLowerCase()).includes("l"))l=B.b.Long;else{if(!o.includes("s"))throw Object(K.d)(t,"ERROR: Invalid Position Type passed into placeOrder()");l=B.b.Short}var u={stock:c,shares:a,price:i,type:s,pos:l};return Object(B.f)(u,t)},getOrders:function(){if(t.checkingRam)return se("getOrders",g.CONSTANTS.ScriptBuySellStockRamCost);if(n("getOrders",g.CONSTANTS.ScriptBuySellStockRamCost),!M.a.hasTixApiAccess)throw Object(K.d)(t,"You don't have TIX API Access! Cannot use getOrders()");if(8!==M.a.bitNodeN&&!(me&&ge>=3))throw Object(K.d)(t,"ERROR: Cannot use getOrders(). You must either be in BitNode-8 or have Level 3 of Source-File 8");const e={},a=B.c.Orders;for(let t in a){const n=a[t];if(n.constructor===Array&&n.length>0){e[t]=[];for(let a=0;a=Object(L.b)())return t.log(`ERROR: You have reached the maximum limit of ${Object(L.b)()} servers. You cannot purchase any more.`),"";const r=Object(L.a)(a);if(r===1/0)return t.log("ERROR: 'purchaseServer()' failed due to an invalid 'ram' argument"),1/0;if(M.a.money.lt(r))return t.log("ERROR: Not enough money to purchase server. Need $"+Object(ee.formatNumber)(r,2)),"";var o=new N.Server({ip:Object(Z.createRandomIp)(),hostname:i,organizationName:"",isConnectedTo:!1,adminRights:!0,purchasedByPlayer:!0,maxRam:a});Object(R.AddToAllServers)(o),M.a.purchasedServers.push(o.ip);var s=M.a.getHomeComputer();return s.serversOnNetwork.push(o.ip),o.serversOnNetwork.push(s.ip),M.a.loseMoney(r),null==t.disableLogs.ALL&&null==t.disableLogs.purchaseServer&&t.scriptRef.log("Purchased new server with hostname "+o.hostname+" for $"+Object(ee.formatNumber)(r,2)),o.hostname},deleteServer:function(e){if(t.checkingRam)return se("deleteServer",g.CONSTANTS.ScriptPurchaseServerRamCost);n("deleteServer",g.CONSTANTS.ScriptPurchaseServerRamCost);var a=String(e);a=a.replace(/\s\s+/g,"");var i=Object(I.GetServerByHostname)(a);if(null==i)return t.scriptRef.log("ERROR: Could not find server with hostname "+a+". deleteServer() failed"),!1;if(!i.purchasedByPlayer||"home"===i.hostname)return t.scriptRef.log("ERROR: Server "+i.hostname+" is not a purchased server. Cannot be deleted. deleteServer() failed"),!1;var r=i.ip;if(i.isConnectedTo)return t.scriptRef.log("ERROR: deleteServer() failed because you are currently connected to the server you are trying to delete"),!1;if(r===t.serverIp)return t.scriptRef.log("ERROR: Cannot call deleteServer() on self. deleteServer() failed"),!1;if(i.runningScripts.length>0)return t.scriptRef.log("ERROR: Cannot delete server "+i.hostname+" because it still has scripts running."),!1;for(var o=!1,s=0;sg.CONSTANTS.NumNetscriptPorts)throw Object(K.d)(t,"ERROR: Trying to write to invalid port: "+e+". Only ports 1-"+g.CONSTANTS.NumNetscriptPorts+" are valid.");if(null==(e=G.a[e-1])||!(e instanceof q.a))throw Object(K.d)(t,"Could not find port: "+e+". This is a bug contact the game developer");return e.write(a)},tryWrite:function(e,a=""){if(t.checkingRam)return se("tryWrite",g.CONSTANTS.ScriptReadWriteRamCost);if(n("tryWrite",g.CONSTANTS.ScriptReadWriteRamCost),isNaN(e))throw Object(K.d)(t,"Invalid argument passed in for tryWrite: "+e);if((e=Math.round(e))<1||e>g.CONSTANTS.NumNetscriptPorts)throw Object(K.d)(t,"ERROR: tryWrite() called on invalid port: "+e+". Only ports 1-"+g.CONSTANTS.NumNetscriptPorts+" are valid.");if(null==(e=G.a[e-1])||!(e instanceof q.a))throw Object(K.d)(t,"Could not find port: "+e+". This is a bug contact the game developer");return e.tryWrite(a)},read:function(e){if(t.checkingRam)return se("read",g.CONSTANTS.ScriptReadWriteRamCost);if(n("read",g.CONSTANTS.ScriptReadWriteRamCost),isNaN(e)){if(Object(te.isString)(e)){let n=e,a=Object(I.getServer)(t.serverIp);if(null==a)throw Object(K.d)(t,"Error getting Server for this script in read(). This is a bug please contact game dev");if(Object(x.isScriptFilename)(n)){let e=t.getScriptOnServer(n);return null==e?"":e.code}{let e=Object(F.getTextFile)(n,a);return null!==e?e.text:""}}throw Object(K.d)(t,"Invalid argument passed in for read(): "+e)}if((e=Math.round(e))<1||e>g.CONSTANTS.NumNetscriptPorts)throw Object(K.d)(t,"ERROR: Trying to read from invalid port: "+e+". Only ports 1-"+g.CONSTANTS.NumNetscriptPorts+" are valid.");if(null==(e=G.a[e-1])||!(e instanceof q.a))throw Object(K.d)(t,"ERROR: Could not find port: "+e+". This is a bug contact the game developer");return e.read()},peek:function(e){if(t.checkingRam)return se("peek",g.CONSTANTS.ScriptReadWriteRamCost);if(n("peek",g.CONSTANTS.ScriptReadWriteRamCost),isNaN(e))throw Object(K.d)(t,"ERROR: peek() called with invalid argument. Must be a port number between 1 and "+g.CONSTANTS.NumNetscriptPorts);if((e=Math.round(e))<1||e>g.CONSTANTS.NumNetscriptPorts)throw Object(K.d)(t,"ERROR: peek() called with invalid argument. Must be a port number between 1 and "+g.CONSTANTS.NumNetscriptPorts);if(null==(e=G.a[e-1])||!(e instanceof q.a))throw Object(K.d)(t,"ERROR: Could not find port: "+e+". This is a bug contact the game developer");return e.peek()},clear:function(e){if(t.checkingRam)return se("clear",g.CONSTANTS.ScriptReadWriteRamCost);if(n("clear",g.CONSTANTS.ScriptReadWriteRamCost),!isNaN(e)){if((e=Math.round(e))<1||e>g.CONSTANTS.NumNetscriptPorts)throw Object(K.d)(t,"ERROR: Trying to clear invalid port: "+e+". Only ports 1-"+g.CONSTANTS.NumNetscriptPorts+" are valid");if(null==(e=G.a[e-1])||!(e instanceof q.a))throw Object(K.d)(t,"ERROR: Could not find port: "+e+". This is a bug contact the game developer");return e.clear()}if(!Object(te.isString)(e))throw Object(K.d)(t,"Invalid argument passed in for clear(): "+e);var a=e,i=Object(I.getServer)(t.serverIp);if(null==i)throw Object(K.d)(t,"Error getting Server for this script in clear(). This is a bug please contact game dev");var r=Object(F.getTextFile)(a,i);return null!=r&&r.write(""),0},getPortHandle:function(e){if(t.checkingRam)return se("getPortHandle",10*g.CONSTANTS.ScriptReadWriteRamCost);if(n("getPortHandle",10*g.CONSTANTS.ScriptReadWriteRamCost),isNaN(e))throw Object(K.d)(t,"ERROR: Invalid argument passed into getPortHandle(). Must be an integer between 1 and "+g.CONSTANTS.NumNetscriptPorts);if((e=Math.round(e))<1||e>g.CONSTANTS.NumNetscriptPorts)throw Object(K.d)(t,"ERROR: getPortHandle() called with invalid port number: "+e+". Only ports 1-"+g.CONSTANTS.NumNetscriptPorts+" are valid");if(null==(e=G.a[e-1])||!(e instanceof q.a))throw Object(K.d)(t,"ERROR: Could not find port: "+e+". This is a bug contact the game developer");return e},rm:function(e,a){if(t.checkingRam)return se("rm",g.CONSTANTS.ScriptReadWriteRamCost);n("rm",g.CONSTANTS.ScriptReadWriteRamCost),null!=a&&""!==a||(a=t.serverIp);var i=Object(I.getServer)(a);if(null==i)throw Object(K.d)(t,`Invalid server specified for rm(): ${a}`);if(e.endsWith(".exe")){for(var r=0;r{Object(ie.removeElementById)(n),e(!0)}}),r=Object(ne.createElement)("button",{class:"popup-box-button",innerText:"No",clickListener:()=>{Object(ie.removeElementById)(n),e(!1)}});Object(ae.createPopup)(n,[a,i,r])})},wget:async function(n,a,i=t.serverIp){if(t.checkingRam)return 0;if(!Object(x.isScriptFilename)(a)&&!a.endsWith(".txt"))return workerSript.log(`ERROR: wget() failed because of an invalid target file: ${a}. Target file must be a script or text file`),Promise.resolve(!1);var r=ue(i,"wget");return new Promise(function(o,s){e.get(n,function(e){let n;return(n=Object(x.isScriptFilename)(a)?r.writeToScriptFile(a,e):r.writeToTextFile(a,e)).success?n.overwritten?(t.log(`wget() successfully retrieved content and overwrote ${a} on ${i}`),o(!0)):(t.log(`wget successfully retrieved content to new file ${a} on ${i}`),o(!0)):(t.log("ERROR: wget() failed"),o(!1))},"text").fail(function(e){return t.log(`ERROR: wget() failed: ${JSON.stringify(e)}`),o(!1)})})},getFavorToDonate:function(){return t.checkingRam?se("getFavorToDonate",g.CONSTANTS.ScriptGetFavorToDonate):(n("getFavorToDonate",g.CONSTANTS.ScriptGetFavorToDonate),Math.floor(g.CONSTANTS.BaseFavorToDonate*l.BitNodeMultipliers.RepToDonateToFaction))},universityCourse:function(e,a){var i=g.CONSTANTS.ScriptSingularityFn1RamCost;if(4!==M.a.bitNodeN&&(i*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return se("universityCourse",i);if(n("universityCourse",i),4!=M.a.bitNodeN&&!(le&&de>=1))throw Object(K.d)(t,"Cannot run universityCourse(). It is a Singularity Function and requires SourceFile-4 (level 1) to run.");if(!S.c){if(M.a.isWorking){var r=M.a.singularityStopWork();null==t.disableLogs.ALL&&null==t.disableLogs.universityCourse&&t.scriptRef.log(r)}var o,s,l;switch(e.toLowerCase()){case T.Locations.AevumSummitUniversity.toLowerCase():if(M.a.city!=T.Locations.Aevum)return t.scriptRef.log("ERROR: You cannot study at Summit University because you are not in Aevum. universityCourse() failed"),!1;M.a.location=T.Locations.AevumSummitUniversity,o=4,s=3;break;case T.Locations.Sector12RothmanUniversity.toLowerCase():if(M.a.city!=T.Locations.Sector12)return t.scriptRef.log("ERROR: You cannot study at Rothman University because you are not in Sector-12. universityCourse() failed"),!1;M.a.location=T.Locations.Sector12RothmanUniversity,o=3,s=2;break;case T.Locations.VolhavenZBInstituteOfTechnology.toLowerCase():if(M.a.city!=T.Locations.Volhaven)return t.scriptRef.log("ERROR: You cannot study at ZB Institute of Technology because you are not in Volhaven. universityCourse() failed"),!1;M.a.location=T.Locations.VolhavenZBInstituteOfTechnology,o=5,s=4;break;default:return t.scriptRef.log("Invalid university name: "+e+". universityCourse() failed"),!1}switch(a.toLowerCase()){case"Study Computer Science".toLowerCase():l=g.CONSTANTS.ClassStudyComputerScience;break;case"Data Structures".toLowerCase():l=g.CONSTANTS.ClassDataStructures;break;case"Networks".toLowerCase():l=g.CONSTANTS.ClassNetworks;break;case"Algorithms".toLowerCase():l=g.CONSTANTS.ClassAlgorithms;break;case"Management".toLowerCase():l=g.CONSTANTS.ClassManagement;break;case"Leadership".toLowerCase():l=g.CONSTANTS.ClassLeadership;break;default:return t.scriptRef.log("Invalid class name: "+a+". universityCourse() failed"),!1}return M.a.startClass(o,s,l),null==t.disableLogs.ALL&&null==t.disableLogs.universityCourse&&t.scriptRef.log("Started "+l+" at "+e),!0}t.scriptRef.log("ERROR: universityCourse() failed because you are in the middle of a mission.")},gymWorkout:function(e,a){var i=g.CONSTANTS.ScriptSingularityFn1RamCost;if(4!==M.a.bitNodeN&&(i*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return se("gymWorkout",i);if(n("gymWorkout",i),4!=M.a.bitNodeN&&!(le&&de>=1))throw Object(K.d)(t,"Cannot run gymWorkout(). It is a Singularity Function and requires SourceFile-4 (level 1) to run.");if(!S.c){if(M.a.isWorking){var r=M.a.singularityStopWork();null==t.disableLogs.ALL&&null==t.disableLogs.gymWorkout&&t.scriptRef.log(r)}var o,s;switch(e.toLowerCase()){case T.Locations.AevumCrushFitnessGym.toLowerCase():if(M.a.city!=T.Locations.Aevum)return t.scriptRef.log("ERROR: You cannot workout at Crush Fitness because you are not in Aevum. gymWorkout() failed"),!1;M.a.location=T.Locations.AevumCrushFitnessGym,o=3,s=2;break;case T.Locations.AevumSnapFitnessGym.toLowerCase():if(M.a.city!=T.Locations.Aevum)return t.scriptRef.log("ERROR: You cannot workout at Snap Fitness because you are not in Aevum. gymWorkout() failed"),!1;M.a.location=T.Locations.AevumSnapFitnessGym,o=10,s=5;break;case T.Locations.Sector12IronGym.toLowerCase():if(M.a.city!=T.Locations.Sector12)return t.scriptRef.log("ERROR: You cannot workout at Iron Gym because you are not in Sector-12. gymWorkout() failed"),!1;M.a.location=T.Locations.Sector12IronGym,o=1,s=1;break;case T.Locations.Sector12PowerhouseGym.toLowerCase():if(M.a.city!=T.Locations.Sector12)return t.scriptRef.log("ERROR: You cannot workout at Powerhouse Gym because you are not in Sector-12. gymWorkout() failed"),!1;M.a.location=T.Locations.Sector12PowerhouseGym,o=20,s=10;break;case T.Locations.VolhavenMilleniumFitnessGym.toLowerCase():if(M.a.city!=T.Locations.Volhaven)return t.scriptRef.log("ERROR: You cannot workout at Millenium Fitness Gym because you are not in Volhaven. gymWorkout() failed"),!1;M.a.location=T.Locations.VolhavenMilleniumFitnessGym,o=7,s=4;break;default:return t.scriptRef.log("Invalid gym name: "+e+". gymWorkout() failed"),!1}switch(a.toLowerCase()){case"strength".toLowerCase():case"str".toLowerCase():M.a.startClass(o,s,g.CONSTANTS.ClassGymStrength);break;case"defense".toLowerCase():case"def".toLowerCase():M.a.startClass(o,s,g.CONSTANTS.ClassGymDefense);break;case"dexterity".toLowerCase():case"dex".toLowerCase():M.a.startClass(o,s,g.CONSTANTS.ClassGymDexterity);break;case"agility".toLowerCase():case"agi".toLowerCase():M.a.startClass(o,s,g.CONSTANTS.ClassGymAgility);break;default:return t.scriptRef.log("Invalid stat: "+a+". gymWorkout() failed"),!1}return null==t.disableLogs.ALL&&null==t.disableLogs.gymWorkout&&t.scriptRef.log("Started training "+a+" at "+e),!0}t.scriptRef.log("ERROR: gymWorkout() failed because you are in the middle of a mission.")},travelToCity(e){var a=g.CONSTANTS.ScriptSingularityFn1RamCost;if(4!==M.a.bitNodeN&&(a*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return se("travelToCity",a);if(n("travelToCity",a),4!=M.a.bitNodeN&&!(le&&de>=1))throw Object(K.d)(t,"Cannot run travelToCity(). It is a Singularity Function and requires SourceFile-4 (level 1) to run.");switch(e){case T.Locations.Aevum:case T.Locations.Chongqing:case T.Locations.Sector12:case T.Locations.NewTokyo:case T.Locations.Ishima:case T.Locations.Volhaven:if(M.a.money.lt(g.CONSTANTS.TravelCost))throw t.scriptRef.log("ERROR: not enough money to travel with travelToCity()."),Object(K.d)(t,"ERROR: not enough money to travel with travelToCity().");return M.a.loseMoney(g.CONSTANTS.TravelCost),M.a.city=e,null==t.disableLogs.ALL&&null==t.disableLogs.travelToCity&&t.scriptRef.log("Traveled to "+e),!0;default:return t.scriptRef.log("ERROR: Invalid city name passed into travelToCity()."),!1}},purchaseTor(){var e=g.CONSTANTS.ScriptSingularityFn1RamCost;if(4!==M.a.bitNodeN&&(e*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return se("purchaseTor",e);if(n("purchaseTor",e),4!=M.a.bitNodeN&&!(le&&de>=1))throw Object(K.d)(t,"Cannot run purchaseTor(). It is a Singularity Function and requires SourceFile-4 (level 1) to run.");if(null!=D.SpecialServerIps["Darkweb Server"])return t.scriptRef.log("You already have a TOR router! purchaseTor() failed"),!1;if(M.a.money.lt(g.CONSTANTS.TorRouterCost))return t.scriptRef.log("ERROR: You cannot afford to purchase a Tor router. purchaseTor() failed"),!1;M.a.loseMoney(g.CONSTANTS.TorRouterCost);var a=new N.Server({ip:Object(Z.createRandomIp)(),hostname:"darkweb",organizationName:"",isConnectedTo:!1,adminRights:!1,purchasedByPlayer:!1,maxRam:1});Object(R.AddToAllServers)(a),D.SpecialServerIps.addIp("Darkweb Server",a.ip);const i=document.getElementById("location-purchase-tor");return i.setAttribute("class","a-link-button-bought"),i.innerHTML="TOR Router - Purchased",M.a.getHomeComputer().serversOnNetwork.push(a.ip),a.serversOnNetwork.push(M.a.getHomeComputer().ip),M.a.gainIntelligenceExp(g.CONSTANTS.IntelligenceSingFnBaseExpGain),null==t.disableLogs.ALL&&null==t.disableLogs.purchaseTor&&t.scriptRef.log("You have purchased a Tor router!"),!0},purchaseProgram(e){var a=g.CONSTANTS.ScriptSingularityFn1RamCost;if(4!==M.a.bitNodeN&&(a*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return se("purchaseProgram",a);if(n("purchaseProgram",a),4!=M.a.bitNodeN&&!(le&&de>=1))throw Object(K.d)(t,"Cannot run purchaseProgram(). It is a Singularity Function and requires SourceFile-4 (level 1) to run.");if(null==D.SpecialServerIps["Darkweb Server"])return t.scriptRef.log("ERROR: You do not have the TOR router. purchaseProgram() failed."),!1;e=e.toLowerCase();let i=null;for(const t in _.DarkWebItems){const n=_.DarkWebItems[t];n.program.toLowerCase()==e&&(i=n)}return null==i?(t.scriptRef.log("ERROR: Invalid program name passed into purchaseProgram()."),!1):M.a.money.lt(i.price)?(t.scriptRef.log("Not enough money to purchase "+i.program),!1):M.a.hasProgram(i.program)?(t.scriptRef.log("You already have the "+i.program+" program"),!0):(M.a.loseMoney(i.price),M.a.getHomeComputer().programs.push(i.program),null==t.disableLogs.ALL&&null==t.disableLogs.purchaseProgram&&t.scriptRef.log("You have purchased the "+i.program+" program. The new program can be found on your home computer."),!0)},getStats:function(){var e=g.CONSTANTS.ScriptSingularityFn1RamCost/4;if(4!==M.a.bitNodeN&&(e*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return se("getStats",e);if(n("getStats",e),4!=M.a.bitNodeN&&!(le&&de>=1))throw Object(K.d)(t,"Cannot run getStats(). It is a Singularity Function and requires SourceFile-4 (level 1) to run.");return{hacking:M.a.hacking_skill,strength:M.a.strength,defense:M.a.defense,dexterity:M.a.dexterity,agility:M.a.agility,charisma:M.a.charisma,intelligence:M.a.intelligence}},getCharacterInformation:function(){var e=g.CONSTANTS.ScriptSingularityFn1RamCost/4;if(4!==M.a.bitNodeN&&(e*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return se("getCharacterInformation",e);if(n("getCharacterInformation",e),4!=M.a.bitNodeN&&!(le&&de>=1))throw Object(K.d)(t,"Cannot run getCharacterInformation(). It is a Singularity Function and requires SourceFile-4 (level 1) to run.");return{bitnode:M.a.bitNodeN,city:M.a.city,factions:M.a.factions.slice(),hp:M.a.hp,jobs:Object.keys(M.a.jobs),jobTitles:Object.values(M.a.jobs),maxHp:M.a.max_hp,mult:{agility:M.a.agility_mult,agilityExp:M.a.agility_exp_mult,companyRep:M.a.company_rep_mult,crimeMoney:M.a.crime_money_mult,crimeSuccess:M.a.crime_success_mult,defense:M.a.defense_mult,defenseExp:M.a.defense_exp_mult,dexterity:M.a.dexterity_mult,dexterityExp:M.a.dexterity_exp_mult,factionRep:M.a.faction_rep_mult,hacking:M.a.hacking_mult,hackingExp:M.a.hacking_exp_mult,strength:M.a.strength_mult,strengthExp:M.a.strength_exp_mult,workMoney:M.a.work_money_mult},timeWorked:M.a.timeWorked,tor:D.SpecialServerIps.hasOwnProperty("Darkweb Server"),workHackExpGain:M.a.workHackExpGained,workStrExpGain:M.a.workStrExpGained,workDefExpGain:M.a.workDefExpGained,workDexExpGain:M.a.workDexExpGained,workAgiExpGain:M.a.workAgiExpGained,workChaExpGain:M.a.workChaExpGained,workRepGain:M.a.workRepGained,workMoneyGain:M.a.workMoneyGained}},isBusy:function(){var e=g.CONSTANTS.ScriptSingularityFn1RamCost/4;if(4!==M.a.bitNodeN&&(e*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return se("isBusy",e);if(n("isBusy",e),4!=M.a.bitNodeN&&!(le&&de>=1))throw Object(K.d)(t,"Cannot run isBusy(). It is a Singularity Function and requires SourceFile-4 (level 1) to run.");return M.a.isWorking},stopAction:function(){var e=g.CONSTANTS.ScriptSingularityFn1RamCost/2;if(4!==M.a.bitNodeN&&(e*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return se("stopAction",e);if(n("stopAction",e),4!=M.a.bitNodeN&&!(le&&de>=1))throw Object(K.d)(t,"Cannot run stopAction(). It is a Singularity Function and requires SourceFile-4 (level 1) to run.");if(M.a.isWorking){var a=M.a.singularityStopWork();return null==t.disableLogs.ALL&&null==t.disableLogs.stopAction&&t.scriptRef.log(a),!0}return!1},upgradeHomeRam:function(){var e=g.CONSTANTS.ScriptSingularityFn2RamCost;if(4!==M.a.bitNodeN&&(e*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return se("upgradeHomeRam",e);if(n("upgradeHomeRam",e),4!=M.a.bitNodeN&&!(le&&de>=2))throw Object(K.d)(t,"Cannot run upgradeHomeRam(). It is a Singularity Function and requires SourceFile-4 (level 2) to run.");const a=M.a.getHomeComputer();if(a.maxRam>=g.CONSTANTS.HomeComputerMaxRam)return t.log("ERROR: upgradeHomeRam() failed because your home computer is at max RAM"),!1;const i=M.a.getUpgradeHomeRamCost();return M.a.money.lt(i)?(t.scriptRef.log("ERROR: upgradeHomeRam() failed because you don't have enough money"),!1):(a.maxRam*=2,M.a.loseMoney(i),M.a.gainIntelligenceExp(g.CONSTANTS.IntelligenceSingFnBaseExpGain),null==t.disableLogs.ALL&&null==t.disableLogs.upgradeHomeRam&&t.scriptRef.log("Purchased additional RAM for home computer! It now has "+a.maxRam+"GB of RAM."),!0)},getUpgradeHomeRamCost:function(){var e=g.CONSTANTS.ScriptSingularityFn2RamCost/2;if(4!==M.a.bitNodeN&&(e*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return se("getUpgradeHomeRamCost",e);if(n("getUpgradeHomeRamCost",e),4!=M.a.bitNodeN&&!(le&&de>=2))throw Object(K.d)(t,"Cannot run getUpgradeHomeRamCost(). It is a Singularity Function and requires SourceFile-4 (level 2) to run.");return M.a.getUpgradeHomeRamCost()},workForCompany:function(e){var a=g.CONSTANTS.ScriptSingularityFn2RamCost;if(4!==M.a.bitNodeN&&(a*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return se("workForCompany",a);if(n("workForCompany",a),4!=M.a.bitNodeN&&!(le&&de>=2))throw Object(K.d)(t,"Cannot run workForCompany(). It is a Singularity Function and requires SourceFile-4 (level 2) to run.");if(null==e&&(e=M.a.companyName),null==e||""===e||!(m.Companies[e]instanceof p.Company))return t.scriptRef.log(`ERROR: workForCompany() failed because of an invalid company specified: ${e}`),!1;if(!Object.keys(M.a.jobs).includes(e))return t.scriptRef.log(`ERROR: workForCompany() failed because you do not have a job at ${e}`),!1;if(S.c)return t.scriptRef.log("ERROR: workForCompany() failed because you are in the middle of a mission."),!1;const i=M.a.jobs[e],r=d.CompanyPositions[i];if(""===i||!(r instanceof h.CompanyPosition))return t.scriptRef.log("ERROR: workForCompany() failed because you do not have a job"),!1;if(M.a.isWorking){var o=M.a.singularityStopWork();null==t.disableLogs.ALL&&null==t.disableLogs.workForCompany&&t.scriptRef.log(o)}return r.isPartTimeJob()?M.a.startWorkPartTime(e):M.a.startWork(e),null==t.disableLogs.ALL&&null==t.disableLogs.workForCompany&&t.log(`Began working at ${M.a.companyName} as a ${i}`),!0},applyToCompany:function(e,a){var i,r=g.CONSTANTS.ScriptSingularityFn2RamCost;if(4!==M.a.bitNodeN&&(r*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return se("applyToCompany",r);if(n("applyToCompany",r),4!=M.a.bitNodeN&&!(le&&de>=2))throw Object(K.d)(t,"Cannot run applyToCompany(). It is a Singularity Function and requires SourceFile-4 (level 2) to run.");if(!Object(m.companyExists)(e))return t.scriptRef.log("ERROR: applyToCompany() failed because specified company "+e+" does not exist."),!1;switch(M.a.location=e,a.toLowerCase()){case"software":i=M.a.applyForSoftwareJob(!0);break;case"software consultant":i=M.a.applyForSoftwareConsultantJob(!0);break;case"it":i=M.a.applyForItJob(!0);break;case"security engineer":i=M.a.applyForSecurityEngineerJob(!0);break;case"network engineer":i=M.a.applyForNetworkEngineerJob(!0);break;case"business":i=M.a.applyForBusinessJob(!0);break;case"business consultant":i=M.a.applyForBusinessConsultantJob(!0);break;case"security":i=M.a.applyForSecurityJob(!0);break;case"agent":i=M.a.applyForAgentJob(!0);break;case"employee":i=M.a.applyForEmployeeJob(!0);break;case"part-time employee":i=M.a.applyForPartTimeEmployeeJob(!0);break;case"waiter":i=M.a.applyForWaiterJob(!0);break;case"part-time waiter":i=M.a.applyForPartTimeWaiterJob(!0);break;default:return t.scriptRef.log("ERROR: Invalid job passed into applyToCompany: "+a+". applyToCompany() failed"),!1}return Object(te.isString)(i)?(t.scriptRef.log(i),!1):(i?null==t.disableLogs.ALL&&null==t.disableLogs.applyToCompany&&t.log(`You were offered a new job at ${e} as a ${M.a.jobs[e]}`):null==t.disableLogs.ALL&&null==t.disableLogs.applyToCompany&&t.log(`You failed to get a new job/promotion at ${e} in the ${a} field.`),i)},getCompanyRep:function(e){var a=g.CONSTANTS.ScriptSingularityFn2RamCost/2;if(4!==M.a.bitNodeN&&(a*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return se("getCompanyRep",a);if(n("getCompanyRep",a),4!=M.a.bitNodeN&&!(le&&de>=2))throw Object(K.d)(t,"Cannot run getCompanyRep(). It is a Singularity Function and requires SourceFile-4 (level 2) to run.");var i=m.Companies[e];return null!=i&&i instanceof p.Company?i.playerReputation:(t.scriptRef.log("ERROR: Invalid companyName passed into getCompanyRep(): "+e),-1)},getCompanyFavor:function(e){var a=g.CONSTANTS.ScriptSingularityFn2RamCost/4;if(4!==M.a.bitNodeN&&(a*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return se("getCompanyFavor",a);if(n("getCompanyFavor",a),4!=M.a.bitNodeN&&!(le&&de>=2))throw Object(K.d)(t,"Cannot run getCompanyFavor(). It is a Singularity Function and requires SourceFile-4 (level 2) to run.");var i=m.Companies[e];return null!=i&&i instanceof p.Company?i.favor:(t.scriptRef.log("ERROR: Invalid companyName passed into getCompanyFavor(): "+e),-1)},getCompanyFavorGain:function(e){var a=g.CONSTANTS.ScriptSingularityFn2RamCost/4;if(4!==M.a.bitNodeN&&(a*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return se("getCompanyFavorGain",a);if(n("getCompanyFavorGain",a),4!=M.a.bitNodeN&&!(le&&de>=2))throw Object(K.d)(t,"Cannot run getCompanyFavorGain(). It is a Singularity Function and requires SourceFile-4 (level 2) to run.");var i=m.Companies[e];return null!=i&&i instanceof p.Company?i.getFavorGain()[0]:(t.scriptRef.log("ERROR: Invalid companyName passed into getCompanyFavorGain(): "+e),-1)},checkFactionInvitations:function(){var e=g.CONSTANTS.ScriptSingularityFn2RamCost;if(4!==M.a.bitNodeN&&(e*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return se("checkFactionInvitations",e);if(n("checkFactionInvitations",e),4!=M.a.bitNodeN&&!(le&&de>=2))throw Object(K.d)(t,"Cannot run checkFactionInvitations(). It is a Singularity Function and requires SourceFile-4 (level 2) to run.");return M.a.factionInvitations.slice()},joinFaction:function(e){var a=g.CONSTANTS.ScriptSingularityFn2RamCost;if(4!==M.a.bitNodeN&&(a*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return se("joinFaction",a);if(n("joinFaction",a),4!=M.a.bitNodeN&&!(le&&de>=2))throw Object(K.d)(t,"Cannot run joinFaction(). It is a Singularity Function and requires SourceFile-4 (level 2) to run.");if(!Object(v.factionExists)(e))return t.scriptRef.log("ERROR: Faction specified in joinFaction() does not exist."),!1;if(!M.a.factionInvitations.includes(e))return t.scriptRef.log("ERROR: Cannot join "+e+" Faction because you have not been invited. joinFaction() failed"),!1;var i=v.Factions[e];Object(E.c)(i);for(var r=0;r=2))throw Object(K.d)(t,"Cannot run workForFaction(). It is a Singularity Function and requires SourceFile-4 (level 2) to run.");if(M.a.inGang()&&void 0!==y.a[e])t.scriptRef.log("ERROR: Faction specified in workForFaction() does not offer work at the moment.");else{if(!S.c){if(!Object(v.factionExists)(e))return t.scriptRef.log("ERROR: Faction specified in workForFaction() does not exist."),!1;if(!M.a.factions.includes(e))return t.scriptRef.log("ERROR: workForFaction() failed because you are not a member of "+e),!1;if(M.a.isWorking){var r=M.a.singularityStopWork();null==t.disableLogs.ALL&&null==t.disableLogs.workForFaction&&t.scriptRef.log(r)}var o=v.Factions[e];switch(a.toLowerCase()){case"hacking":case"hacking contracts":case"hackingcontracts":return["Illuminati","Daedalus","The Covenant","ECorp","MegaCorp","Bachman & Associates","Blade Industries","NWO","Clarke Incorporated","OmniTek Incorporated","Four Sigma","KuaiGong International","Fulcrum Secret Technologies","BitRunners","The Black Hand","NiteSec","Chongqing","Sector-12","New Tokyo","Aevum","Ishima","Volhaven","Speakers for the Dead","The Dark Army","The Syndicate","Silhouette","Netburners","Tian Di Hui","CyberSec"].includes(o.name)?(M.a.startFactionHackWork(o),t.scriptRef.log("Started carrying out hacking contracts for "+o.name),!0):(t.scriptRef.log("ERROR: Cannot carry out hacking contracts for "+o.name+". workForFaction() failed"),!1);case"field":case"fieldwork":case"field work":return["Illuminati","Daedalus","The Covenant","ECorp","MegaCorp","Bachman & Associates","Blade Industries","NWO","Clarke Incorporated","OmniTek Incorporated","Four Sigma","KuaiGong International","The Black Hand","Chongqing","Sector-12","New Tokyo","Aevum","Ishima","Volhaven","Speakers for the Dead","The Dark Army","The Syndicate","Silhouette","Tetrads","Slum Snakes"].includes(o.name)?(M.a.startFactionFieldWork(o),t.scriptRef.log("Started carrying out field missions for "+o.name),!0):(t.scriptRef.log("ERROR: Cannot carry out field missions for "+o.name+". workForFaction() failed"),!1);case"security":case"securitywork":case"security work":return["ECorp","MegaCorp","Bachman & Associates","Blade Industries","NWO","Clarke Incorporated","OmniTek Incorporated","Four Sigma","KuaiGong International","Fulcrum Secret Technologies","Chongqing","Sector-12","New Tokyo","Aevum","Ishima","Volhaven","Speakers for the Dead","The Syndicate","Tetrads","Slum Snakes","Tian Di Hui"].includes(o.name)?(M.a.startFactionSecurityWork(o),t.scriptRef.log("Started serving as security details for "+o.name),!0):(t.scriptRef.log("ERROR: Cannot serve as security detail for "+o.name+". workForFaction() failed"),!1);default:t.scriptRef.log("ERROR: Invalid work type passed into workForFaction(): "+a)}return!0}t.scriptRef.log("ERROR: workForFaction() failed because you are in the middle of a mission.")}},getFactionRep:function(e){var a=g.CONSTANTS.ScriptSingularityFn2RamCost/4;if(4!==M.a.bitNodeN&&(a*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return se("getFactionRep",a);if(n("getFactionRep",a),4!=M.a.bitNodeN&&!(le&&de>=2))throw Object(K.d)(t,"Cannot run getFactionRep(). It is a Singularity Function and requires SourceFile-4 (level 2) to run.");return Object(v.factionExists)(e)?v.Factions[e].playerReputation:(t.scriptRef.log("ERROR: Faction specified in getFactionRep() does not exist."),-1)},getFactionFavor:function(e){var a=g.CONSTANTS.ScriptSingularityFn2RamCost;if(4!==M.a.bitNodeN&&(a*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return se("getFactionFavor",a);if(n("getFactionFavor",a),4!=M.a.bitNodeN&&!(le&&de>=2))throw Object(K.d)(t,"Cannot run getFactionFavor(). It is a Singularity Function and requires SourceFile-4 (level 2) to run.");return Object(v.factionExists)(e)?v.Factions[e].favor:(t.scriptRef.log("ERROR: Faction specified in getFactionFavor() does not exist."),-1)},getFactionFavorGain:function(e){var a=g.CONSTANTS.ScriptSingularityFn2RamCost;if(4!==M.a.bitNodeN&&(a*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return se("getFactionFavorGain",a);if(n("getFactionFavorGain",a),4!=M.a.bitNodeN&&!(le&&de>=2))throw Object(K.d)(t,"Cannot run getFactionFavorGain(). It is a Singularity Function and requires SourceFile-4 (level 2) to run.");return Object(v.factionExists)(e)?v.Factions[e].getFavorGain()[0]:(t.scriptRef.log("ERROR: Faction specified in getFactionFavorGain() does not exist."),-1)},donateToFaction:function(e,a){var i=g.CONSTANTS.ScriptSingularityFn3RamCost;if(4!==M.a.bitNodeN&&(i*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return se("donateToFaction",i);if(n("donateToFaction",i),4!=M.a.bitNodeN&&!(le&&de>=3))throw Object(K.d)(t,"Cannot run donateToFaction(). It is a Singularity Function and requires SourceFile-4 (level 3) to run.");if(!Object(v.factionExists)(e))return t.log(`ERROR: Faction specified in donateToFaction() does not exist: ${e}`),!1;if("number"!=typeof a||a<=0)return t.log(`ERROR: Invalid donation amount specified in donateToFaction(): ${a}. Must be numeric and positive`),!1;if(M.a.money.lt(a))return t.log(`ERROR: You do not have enough money to donate $${a} to ${e}`),!1;var r=Math.round(g.CONSTANTS.BaseFavorToDonate*l.BitNodeMultipliers.RepToDonateToFaction);if(v.Factions[e].favor=3))throw Object(K.d)(t,"Cannot run createProgram(). It is a Singularity Function and requires SourceFile-4 (level 3) to run.");if(S.c)return void t.scriptRef.log("ERROR: createProgram() failed because you are in the middle of a mission.");if(M.a.isWorking){var i=M.a.singularityStopWork();null==t.disableLogs.ALL&&null==t.disableLogs.createProgram&&t.scriptRef.log(i)}e=e.toLowerCase();let r=null;for(const t in P.Programs)P.Programs[t].name.toLowerCase()==e&&(r=P.Programs[t]);return null==r?(t.scriptRef.log("ERROR: createProgram() failed because the specified program does not exist: "+e),!1):M.a.hasProgram(r.name)?(t.scriptRef.log("ERROR: createProgram() failed because you already have the "+r.name+" program"),!1):r.create.req(M.a)?(M.a.startCreateProgramWork(r.name,r.create.time,r.create.level),null==t.disableLogs.ALL&&null==t.disableLogs.createProgram&&t.scriptRef.log("Began creating program: "+e),!0):(t.scriptRef.log("ERROR: createProgram() failed because hacking level is too low to create "+r.name+" (level "+r.create.level+" req)"),!1)},commitCrime:function(e){var a=g.CONSTANTS.ScriptSingularityFn3RamCost;if(4!==M.a.bitNodeN&&(a*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return se("commitCrime",a);if(n("commitCrime",a),4!=M.a.bitNodeN&&!(le&&de>=3))throw Object(K.d)(t,"Cannot run commitCrime(). It is a Singularity Function and requires SourceFile-4 (level 3) to run.");if(S.c)return void t.scriptRef.log("ERROR: commitCrime() failed because you are in the middle of a mission.");if(M.a.isWorking){var i=M.a.singularityStopWork();null==t.disableLogs.ALL&&null==t.disableLogs.commitCrime&&t.scriptRef.log(i)}switch(M.a.city){case T.Locations.Aevum:M.a.location=T.Locations.AevumSlums;break;case T.Locations.Chongqing:M.a.location=T.Locations.ChongqingSlums;break;case T.Locations.Sector12:M.a.location=T.Locations.Sector12Slums;break;case T.Locations.NewTokyo:M.a.location=T.Locations.NewTokyoSlums;break;case T.Locations.Ishima:M.a.location=T.Locations.IshimaSlums;break;case T.Locations.Volhaven:M.a.location=T.Locations.VolhavenSlums;break;default:console.log("Invalid Player.city value")}const r=Object(c.findCrime)(e.toLowerCase());if(null==r)throw Object(K.d)(t,"Invalid crime passed into commitCrime(): "+e);return null==t.disableLogs.ALL&&null==t.disableLogs.commitCrime&&t.scriptRef.log("Attempting to commit crime: "+r.name+"..."),r.commit(M.a,1,{workerscript:t})},getCrimeChance:function(e){var a=g.CONSTANTS.ScriptSingularityFn3RamCost;if(4!==M.a.bitNodeN&&(a*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return se("getCrimeChance",a);if(n("getCrimeChance",a),4!=M.a.bitNodeN&&!(le&&de>=3))throw Object(K.d)(t,"Cannot run getCrimeChance(). It is a Singularity Function and requires SourceFile-4 (level 3) to run.");const i=Object(c.findCrime)(e.toLowerCase());if(null==i)throw Object(K.d)(t,"Invalid crime passed into getCrimeChance(): "+i);return i.successRate(M.a)},getOwnedAugmentations:function(e=!1){var a=g.CONSTANTS.ScriptSingularityFn3RamCost;if(4!==M.a.bitNodeN&&(a*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return se("getOwnedAugmentations",a);if(n("getOwnedAugmentations",a),4!=M.a.bitNodeN&&!(le&&de>=3))throw Object(K.d)(t,"Cannot run getOwnedAugmentations(). It is a Singularity Function and requires SourceFile-4 (level 3) to run.");for(var i=[],r=0;r=3))throw Object(K.d)(t,"Cannot run getOwnedSourceFiles(). It is a Singularity Function and requires SourceFile-4 (level 3) to run.");let a=[];for(let e=0;e=3))throw Object(K.d)(t,"Cannot run getAugmentationsFromFaction(). It is a Singularity Function and requires SourceFile-4 (level 3) to run.");if(!Object(v.factionExists)(e))return t.scriptRef.log("ERROR: getAugmentationsFromFaction() failed. Invalid faction name passed in (this is case-sensitive): "+e),[];for(var i=v.Factions[e],r=[],o=0;o=3))throw Object(K.d)(t,"Cannot run getAugmentationPrereq(). It is a Singularity Function and requires SourceFile-4 (level 3) to run.");return Object(o.b)(e)?r.Augmentations[e].prereqs.slice():(t.scriptRef.log("ERROR: getAugmentationPrereq() failed. Invalid Augmentation name passed in (note: this is case-sensitive): "+e),[])},getAugmentationCost:function(e){var a=g.CONSTANTS.ScriptSingularityFn3RamCost;if(4!==M.a.bitNodeN&&(a*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return se("getAugmentationCost",a);if(n("getAugmentationCost",a),4!=M.a.bitNodeN&&!(le&&de>=3))throw Object(K.d)(t,"Cannot run getAugmentationCost(). It is a Singularity Function and requires SourceFile-4 (level 3) to run.");if(!Object(o.b)(e))return t.scriptRef.log("ERROR: getAugmentationCost() failed. Invalid Augmentation name passed in (note: this is case-sensitive): "+e),[-1,-1];var i=r.Augmentations[e];return[i.baseRepRequirement,i.baseCost]},purchaseAugmentation:function(e,a){var o=g.CONSTANTS.ScriptSingularityFn3RamCost;if(4!==M.a.bitNodeN&&(o*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return se("purchaseAugmentation",o);if(n("purchaseAugmentation",o),4!=M.a.bitNodeN&&!(le&&de>=3))throw Object(K.d)(t,"Cannot run purchaseAugmentation(). It is a Singularity Function and requires SourceFile-4 (level 3) to run.");var l=v.Factions[e];if(null==l||!(l instanceof b.Faction))return t.scriptRef.log("ERROR: purchaseAugmentation() failed because of invalid faction name: "+e),!1;if(!l.augmentations.includes(a))return t.scriptRef.log("ERROR: purchaseAugmentation() failed because the faction "+e+" does not contain the "+a+" augmentation"),!1;var c=r.Augmentations[a];if(null==c||!(c instanceof i.Augmentation))return t.scriptRef.log("ERROR: purchaseAugmentation() failed because of invalid augmentation name: "+a),!1;var u=!1;if(c.name===s.AugmentationNames.NeuroFluxGovernor&&(u=!0),!u){for(var p=0;p=3))throw Object(K.d)(t,"Cannot run installAugmentations(). It is a Singularity Function and requires SourceFile-4 (level 3) to run.");return 0===M.a.queuedAugmentations.length?(t.scriptRef.log("ERROR: installAugmentations() failed because you do not have any Augmentations to be installed"),!1):(M.a.gainIntelligenceExp(g.CONSTANTS.IntelligenceSingFnBaseExpGain),t.scriptRef.log("Installing Augmentations. This will cause this script to be killed"),Object(o.e)(e),!0)},gang:{getMemberNames:function(){if(t.checkingRam)return se("getMemberNames",g.CONSTANTS.ScriptGangApiBaseRamCost/4);n("getMemberNames",g.CONSTANTS.ScriptGangApiBaseRamCost/4),H.a(t,"getMemberNames");try{const e=[];for(const t of M.a.gang.members)e.push(t.name);return e}catch(e){throw Object(K.d)(t,H.b("getMemberNames",e))}},getGangInformation:function(){if(t.checkingRam)return se("getGangInformation",g.CONSTANTS.ScriptGangApiBaseRamCost/2);n("getGangInformation",g.CONSTANTS.ScriptGangApiBaseRamCost/2),H.a(t,"getGangInformation");try{return{faction:M.a.gang.facName,isHacking:M.a.gang.isHackingGang,moneyGainRate:M.a.gang.moneyGainRate,power:M.a.gang.getPower(),respect:M.a.gang.respect,respectGainRate:M.a.gang.respectGainRate,territory:M.a.gang.getTerritory(),territoryClashChance:M.a.gang.territoryClashChance,territoryWarfareEngaged:M.a.gang.territoryWarfareEngaged,wantedLevel:M.a.gang.wanted,wantedLevelGainRate:M.a.gang.wantedGainRate}}catch(e){throw Object(K.d)(t,H.b("getGangInformation",e))}},getOtherGangInformation:function(){if(t.checkingRam)return se("getOtherGangInformation",g.CONSTANTS.ScriptGangApiBaseRamCost/2);n("getOtherGangInformation",g.CONSTANTS.ScriptGangApiBaseRamCost/2),H.a(t,"getOtherGangInformation");try{return Object.assign(y.a)}catch(e){throw Object(K.d)(t,H.b("getOtherGangInformation",e))}},getMemberInformation:function(e){if(t.checkingRam)return se("getMemberInformation",g.CONSTANTS.ScriptGangApiBaseRamCost/2);n("getMemberInformation",g.CONSTANTS.ScriptGangApiBaseRamCost/2),H.a(t,"getMemberInformation");try{for(const t of M.a.gang.members)if(t.name===e)return{agility:t.agi,agilityEquipMult:t.agi_mult,agilityAscensionMult:t.agi_asc_mult,augmentations:t.augmentations.slice(),charisma:t.cha,charismaEquipMult:t.cha_mult,charismaAscensionMult:t.cha_asc_mult,defense:t.def,defenseEquipMult:t.def_mult,defenseAscensionMult:t.def_asc_mult,dexterity:t.dex,dexterityEquipMult:t.dex_mult,dexterityAscensionMult:t.dex_asc_mult,equipment:t.upgrades.slice(),hacking:t.hack,hackingEquipMult:t.hack_mult,hackingAscensionMult:t.hack_asc_mult,strength:t.str,strengthEquipMult:t.str_mult,strengthAscensionMult:t.str_asc_mult,task:t.task};return t.log(`Invalid argument passed to gang.getMemberInformation(). No gang member could be found with name ${e}`),{}}catch(e){throw Object(K.d)(t,H.b("getMemberInformation",e))}},canRecruitMember:function(){if(t.checkingRam)return se("canRecruitMember",g.CONSTANTS.ScriptGangApiBaseRamCost/4);n("canRecruitMember",g.CONSTANTS.ScriptGangApiBaseRamCost/4),H.a(t,"canRecruitMember");try{return M.a.gang.canRecruitMember()}catch(e){throw Object(K.d)(t,H.b("canRecruitMember",e))}},recruitMember:function(e){if(t.checkingRam)return se("recruitMember",g.CONSTANTS.ScriptGangApiBaseRamCost/2);n("recruitMember",g.CONSTANTS.ScriptGangApiBaseRamCost/2),H.a(t,"recruitMember");try{const n=M.a.gang.recruitMember(e);return t.shouldLog("recruitMember")&&(n?t.log(`Successfully recruited Gang Member ${e}`):t.log(`Failed to recruit Gang Member ${e}`)),n}catch(e){throw Object(K.d)(t,H.b("recruitMember",e))}},getTaskNames:function(){if(t.checkingRam)return se("getTaskNames",g.CONSTANTS.ScriptGangApiBaseRamCost/4);n("getTaskNames",g.CONSTANTS.ScriptGangApiBaseRamCost/4),H.a(t,"getTaskNames");try{const e=M.a.gang.getAllTaskNames();return e.unshift("Unassigned"),e}catch(e){throw Object(K.d)(t,H.b("getTaskNames",e))}},setMemberTask:function(e,a){if(t.checkingRam)return se("setMemberTask",g.CONSTANTS.ScriptGangApiBaseRamCost/2);n("setMemberTask",g.CONSTANTS.ScriptGangApiBaseRamCost/2),H.a(t,"setMemberTask");try{for(const n of M.a.gang.members)if(n.name===e){const i=n.assignToTask(a);return t.shouldLog("setMemberTask")&&(i?t.log(`Successfully assigned Gang Member ${e} to ${a} task`):t.log(`Failed to assign Gang Member ${e} to ${a} task. ${e} is now Unassigned`)),i}return t.log(`Invalid argument passed to gang.setMemberTask(). No gang member could be found with name ${e}`),!1}catch(e){throw Object(K.d)(t,H.b("setMemberTask",e))}},getEquipmentNames:function(){if(t.checkingRam)return se("getEquipmentNames",g.CONSTANTS.ScriptGangApiBaseRamCost/4);n("getEquipmentNames",g.CONSTANTS.ScriptGangApiBaseRamCost/4),H.a(t,"getEquipmentNames");try{return M.a.gang.getAllUpgradeNames()}catch(e){throw Object(K.d)(t,H.b("getEquipmentNames",e))}},getEquipmentCost:function(e){if(t.checkingRam)return se("getEquipmentCost",g.CONSTANTS.ScriptGangApiBaseRamCost/2);n("getEquipmentCost",g.CONSTANTS.ScriptGangApiBaseRamCost/2),H.a(t,"getEquipmentCost");try{return M.a.gang.getUpgradeCost(e)}catch(e){throw Object(K.d)(t,H.b("getEquipmentCost",e))}},getEquipmentType:function(e){if(t.checkingRam)return se("getEquipmentType",g.CONSTANTS.ScriptGangApiBaseRamCost/2);n("getEquipmentType",g.CONSTANTS.ScriptGangApiBaseRamCost/2),H.a(t,"getEquipmentType");try{return M.a.gang.getUpgradeType(e)}catch(e){throw Object(K.d)(t,H.b("getEquipmentType",e))}},purchaseEquipment:function(e,a){if(t.checkingRam)return se("purchaseEquipment",g.CONSTANTS.ScriptGangApiBaseRamCost);n("purchaseEquipment",g.CONSTANTS.ScriptGangApiBaseRamCost),H.a(t,"purchaseEquipment");try{for(const n of M.a.gang.members)if(n.name===e){const i=n.buyUpgrade(a,M.a,M.a.gang);return t.shouldLog("purchaseEquipment")&&(i?t.log(`Purchased ${a} for Gang member ${e}`):t.log(`Failed to purchase ${a} for Gang member ${e}`)),i}return t.log(`Invalid argument passed to gang.purchaseEquipment(). No gang member could be found with name ${e}`),!1}catch(e){throw Object(K.d)(t,H.b("purchaseEquipment",e))}},ascendMember:function(e){if(t.checkingRam)return se("ascendMember",g.CONSTANTS.ScriptGangApiBaseRamCost);n("ascendMember",g.CONSTANTS.ScriptGangApiBaseRamCost),H.a(t,"ascendMember");try{for(const n of M.a.gang.members)if(n.name===e)return M.a.gang.ascendMember(n,t);return t.log(`Invalid argument passed to gang.ascendMember(). No gang member could be found with name ${e}`),!1}catch(e){throw Object(K.d)(t,H.b("ascendMember",e))}},setTerritoryWarfare:function(e){if(t.checkingRam)return se("setTerritoryWarfare",g.CONSTANTS.ScriptGangApiBaseRamCost/2);n("setTerritoryWarfare",g.CONSTANTS.ScriptGangApiBaseRamCost/2),H.a(t,"setTerritoryWarfare");try{e?(M.a.gang.territoryWarfareEngaged=!0,t.shouldLog("setTerritoryWarfare")&&t.log("Engaging in Gang Territory Warfare")):(M.a.gang.territoryWarfareEngaged=!1,t.shouldLog("setTerritoryWarfare")&&t.log("Disengaging in Gang Territory Warfare"))}catch(e){throw Object(K.d)(t,H.b("setTerritoryWarfare",e))}},getChanceToWinClash:function(e){if(t.checkingRam)return se("getChanceToWinClash",g.CONSTANTS.ScriptGangApiBaseRamCost);n("getChanceToWinClash",g.CONSTANTS.ScriptGangApiBaseRamCost),H.a(t,"getChanceToWinClash");try{if(null==y.a[e])return t.log(`Invalid gang specified in gang.getChanceToWinClash() : ${e}`),0;const n=y.a[M.a.gang.facName].power;return n/(y.a[e].power+n)}catch(e){throw Object(K.d)(t,H.b("getChanceToWinClash",e))}},getBonusTime:function(){if(t.checkingRam)return 0;H.a(t,"getBonusTime");try{return Math.round(M.a.gang.storedCycles/5)}catch(e){throw Object(K.d)(t,H.b("getBonusTime",e))}}},bladeburner:{getContractNames:function(){if(t.checkingRam)return se("getContractNames",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost/10);if(n("getContractNames",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost/10),M.a.bladeburner instanceof u.a&&(7===M.a.bitNodeN||pe))return M.a.bladeburner.getContractNamesNetscriptFn();throw Object(K.d)(t,"getContractNames() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed at the Bladeburner division or because you do not have Source-File 7")},getOperationNames:function(){if(t.checkingRam)return se("getOperationNames",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost/10);if(n("getOperationNames",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost/10),M.a.bladeburner instanceof u.a&&(7===M.a.bitNodeN||pe))return M.a.bladeburner.getOperationNamesNetscriptFn();throw Object(K.d)(t,"getOperationNames() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed at the Bladeburner division or because you do not have Source-File 7")},getBlackOpNames:function(){if(t.checkingRam)return se("getBlackOpNames",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost/10);if(n("getBlackOpNames",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost/10),M.a.bladeburner instanceof u.a&&(7===M.a.bitNodeN||pe))return M.a.bladeburner.getBlackOpNamesNetscriptFn();throw Object(K.d)(t,"getBlackOpNames() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed at the Bladeburner division or because you do not have Source-File 7")},getBlackOpRank:function(e=""){if(t.checkingRam)return se("getBlackOpRank",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost/2);if(n("getBlackOpRank",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost/2),M.a.bladeburner instanceof u.a&&(7===M.a.bitNodeN||pe)){const t=M.a.bladeburner.getActionIdFromTypeAndName("blackops",e);if(!t)return-1;const n=M.a.bladeburner.getActionObject(t);return n?n.reqdRank:-1}throw Object(K.d)(t,"getBlackOpRank() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed at the Bladeburner division or because you do not have Source-File 7")},getGeneralActionNames:function(){if(t.checkingRam)return se("getGeneralActionNames",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost/10);if(n("getGeneralActionNames",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost/10),M.a.bladeburner instanceof u.a&&(7===M.a.bitNodeN||pe))return M.a.bladeburner.getGeneralActionNamesNetscriptFn();throw Object(K.d)(t,"getGeneralActionNames() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed at the Bladeburner division or because you do not have Source-File 7")},getSkillNames:function(){if(t.checkingRam)return se("getSkillNames",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost/10);if(n("getSkillNames",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost/10),M.a.bladeburner instanceof u.a&&(7===M.a.bitNodeN||pe))return M.a.bladeburner.getSkillNamesNetscriptFn();throw Object(K.d)(t,"getSkillNames() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed at the Bladeburner division or because you do not have Source-File 7")},startAction:function(e="",a=""){if(t.checkingRam)return se("startAction",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);if(n("startAction",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),M.a.bladeburner instanceof u.a&&(7===M.a.bitNodeN||pe))try{return M.a.bladeburner.startActionNetscriptFn(e,a,t)}catch(e){throw Object(K.d)(t,"Bladeburner.startAction() failed with exception: "+e)}throw Object(K.d)(t,"startAction() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed at the Bladeburner division or because you do not have Source-File 7")},stopBladeburnerAction:function(){if(t.checkingRam)return se("stopBladeburnerAction",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost/2);if(n("stopBladeburnerAction",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost/2),M.a.bladeburner instanceof u.a&&(7===M.a.bitNodeN||pe))return M.a.bladeburner.resetAction();throw Object(K.d)(t,"stopBladeburnerAction() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed at the Bladeburner division or because you do not have Source-File 7")},getCurrentAction:function(){if(t.checkingRam)return se("getCurrentAction",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost/4);if(n("getCurrentAction",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost/4),M.a.bladeburner instanceof u.a&&(7===M.a.bitNodeN||pe))return M.a.bladeburner.getTypeAndNameFromActionId(M.a.bladeburner.action);throw Object(K.d)(t,"getCurrentAction() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed at the Bladeburner division or because you do not have Source-File 7")},getActionTime:function(e="",a=""){if(t.checkingRam)return se("getActionTime",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);if(n("getActionTime",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),M.a.bladeburner instanceof u.a&&(7===M.a.bitNodeN||pe))try{return M.a.bladeburner.getActionTimeNetscriptFn(e,a,t)}catch(e){throw Object(K.d)(t,"Bladeburner.getActionTime() failed with exception: "+e)}throw Object(K.d)(t,"getActionTime() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed at the Bladeburner division or because you do not have Source-File 7")},getActionEstimatedSuccessChance:function(e="",a=""){if(t.checkingRam)return se("getActionEstimatedSuccessChance",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);if(n("getActionEstimatedSuccessChance",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),M.a.bladeburner instanceof u.a&&(7===M.a.bitNodeN||pe))try{return M.a.bladeburner.getActionEstimatedSuccessChanceNetscriptFn(e,a,t)}catch(e){throw Object(K.d)(t,"Bladeburner.getActionEstimatedSuccessChance() failed with exception: "+e)}throw Object(K.d)(t,"getActionEstimatedSuccessChance() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed at the Bladeburner division or because you do not have Source-File 7")},getActionRepGain:function(e="",a="",i){if(t.checkingRam)return se("getActionRepGain",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);n("getActionRepGain",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),Object(U.a)(t,"getActionRepGain");try{var r=Object(U.b)("getActionAutolevel",e,a);const n=M.a.bladeburner.getActionIdFromTypeAndName(e,a);if(null==n)return t.log(r),-1;const s=M.a.bladeburner.getActionObject(n);return null==s?(t.log(r),-1):(o=null==i||isNaN(i)?Math.pow(s.rewardFac,s.level-1):Math.pow(s.rewardFac,i-1),s.rankGain*o*l.BitNodeMultipliers.BladeburnerRank);var o}catch(e){throw Object(K.d)(t,Object(U.c)("getActionAutolevel",e))}},getActionCountRemaining:function(e="",a=""){if(t.checkingRam)return se("getActionCountRemaining",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);if(n("getActionCountRemaining",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),M.a.bladeburner instanceof u.a&&(7===M.a.bitNodeN||pe))try{return M.a.bladeburner.getActionCountRemainingNetscriptFn(e,a,t)}catch(e){throw Object(K.d)(t,"Bladeburner.getActionCountRemaining() failed with exception: "+e)}throw Object(K.d)(t,"getActionCountRemaining() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed at the Bladeburner division or because you do not have Source-File 7")},getActionMaxLevel:function(e="",a=""){if(t.checkingRam)return se("getActionMaxLevel",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);n("getActionMaxLevel",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),Object(U.a)(t,"getActionMaxLevel");try{var i=Object(U.b)("getActionMaxLevel",e,a);const n=M.a.bladeburner.getActionIdFromTypeAndName(e,a);if(null==n)return t.log(i),-1;const r=M.a.bladeburner.getActionObject(n);return null==r?(t.log(i),-1):r.maxLevel}catch(e){throw Object(K.d)(t,Object(U.c)("getActionMaxLevel",e))}},getActionCurrentLevel:function(e="",a=""){if(t.checkingRam)return se("getActionCurrentLevel",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);n("getActionCurrentLevel",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),Object(U.a)(t,"getActionCurrentLevel");try{var i=Object(U.b)("getActionCurrentLevel",e,a);const n=M.a.bladeburner.getActionIdFromTypeAndName(e,a);if(null==n)return t.log(i),-1;const r=M.a.bladeburner.getActionObject(n);return null==r?(t.log(i),-1):r.level}catch(e){throw Object(K.d)(t,Object(U.c)("getActionCurrentLevel",e))}},getActionAutolevel:function(e="",a=""){if(t.checkingRam)return se("getActionAutolevel",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);n("getActionAutolevel",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),Object(U.a)(t,"getActionAutolevel");try{var i=Object(U.b)("getActionAutolevel",e,a);const n=M.a.bladeburner.getActionIdFromTypeAndName(e,a);if(null==n)return t.log(i),!1;const r=M.a.bladeburner.getActionObject(n);return null==r?(t.log(i),!1):r.autoLevel}catch(e){throw Object(K.d)(t,Object(U.c)("getActionAutolevel",e))}},setActionAutolevel:function(e="",a="",i=!0){if(t.checkingRam)return se("setActionAutolevel",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);n("setActionAutolevel",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),Object(U.a)(t,"setActionAutolevel");try{var r=Object(U.b)("setActionAutolevel",e,a);const n=M.a.bladeburner.getActionIdFromTypeAndName(e,a);if(null==n)return void t.log(r);const o=M.a.bladeburner.getActionObject(n);if(null==o)return void t.log(r);o.autoLevel=i}catch(e){throw Object(K.d)(t,Object(U.c)("setActionAutolevel",e))}},setActionLevel:function(e="",a="",i=1){if(t.checkingRam)return se("setActionLevel",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);n("setActionLevel",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),Object(U.a)(t,"setActionLevel");try{var r=Object(U.b)("setActionLevel",e,a);const n=M.a.bladeburner.getActionIdFromTypeAndName(e,a);if(null==n)return void t.log(r);const o=M.a.bladeburner.getActionObject(n);if(null==o)return void t.log(r);if(i>o.maxLevel)return void t.log(`ERROR: bladeburner.${setActionLevel}() failed because level exceeds max level for given action.`);if(i<1)return void t.log(`ERROR: bladeburner.${setActionLevel}() failed because level is below 1.`);o.level=i}catch(e){throw Object(K.d)(t,Object(U.c)("setActionLevel",e))}},getRank:function(){if(t.checkingRam)return se("getRank",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);if(n("getRank",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),M.a.bladeburner instanceof u.a&&(7===M.a.bitNodeN||pe))return M.a.bladeburner.rank;throw Object(K.d)(t,"getRank() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed at the Bladeburner division or because you do not have Source-File 7")},getSkillPoints:function(){if(t.checkingRam)return se("getSkillPoints",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);if(n("getSkillPoints",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),M.a.bladeburner instanceof u.a&&(7===M.a.bitNodeN||pe))return M.a.bladeburner.skillPoints;throw Object(K.d)(t,"getSkillPoints() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed at the Bladeburner division or because you do not have Source-File 7")},getSkillLevel:function(e=""){if(t.checkingRam)return se("getSkillLevel",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);if(n("getSkillLevel",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),M.a.bladeburner instanceof u.a&&(7===M.a.bitNodeN||pe))try{return M.a.bladeburner.getSkillLevelNetscriptFn(e,t)}catch(e){throw Object(K.d)(t,"Bladeburner.getSkillLevel() failed with exception: "+e)}throw Object(K.d)(t,"getSkillLevel() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed at the Bladeburner division or because you do not have Source-File 7")},getSkillUpgradeCost:function(e=""){if(t.checkingRam)return se("getSkillUpgradeCost",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);if(n("getSkillUpgradeCost",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),M.a.bladeburner instanceof u.a&&(7===M.a.bitNodeN||pe))try{return M.a.bladeburner.getSkillUpgradeCostNetscriptFn(e,t)}catch(e){throw Object(K.d)(t,"Bladeburner.getSkillUpgradeCost() failed with exception: "+e)}throw Object(K.d)(t,"getSkillUpgradeCost() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed at the Bladeburner division or because you do not have Source-File 7")},upgradeSkill:function(e){if(t.checkingRam)return se("upgradeSkill",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);if(n("upgradeSkill",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),M.a.bladeburner instanceof u.a&&(7===M.a.bitNodeN||pe))try{return M.a.bladeburner.upgradeSkillNetscriptFn(e,t)}catch(e){throw Object(K.d)(t,"Bladeburner.upgradeSkill() failed with exception: "+e)}throw Object(K.d)(t,"upgradeSkill() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed at the Bladeburner division or because you do not have Source-File 7")},getTeamSize:function(e="",a=""){if(t.checkingRam)return se("getTeamSize",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);if(n("getTeamSize",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),M.a.bladeburner instanceof u.a&&(7===M.a.bitNodeN||pe))try{return M.a.bladeburner.getTeamSizeNetscriptFn(e,a,t)}catch(e){throw Object(K.d)(t,"Bladeburner.getTeamSize() failed with exception: "+e)}throw Object(K.d)(t,"getTeamSize() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed at the Bladeburner division or because you do not have Source-File 7")},setTeamSize:function(e="",a="",i){if(t.checkingRam)return se("setTeamSize",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);if(n("setTeamSize",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),M.a.bladeburner instanceof u.a&&(7===M.a.bitNodeN||pe))try{return M.a.bladeburner.setTeamSizeNetscriptFn(e,a,i,t)}catch(e){throw Object(K.d)(t,"Bladeburner.setTeamSize() failed with exception: "+e)}throw Object(K.d)(t,"setTeamSize() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed at the Bladeburner division or because you do not have Source-File 7")},getCityEstimatedPopulation:function(e){if(t.checkingRam)return se("getCityEstimatedPopulation",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);if(n("getCityEstimatedPopulation",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),M.a.bladeburner instanceof u.a&&(7===M.a.bitNodeN||pe))try{return M.a.bladeburner.getCityEstimatedPopulationNetscriptFn(e,t)}catch(e){throw Object(K.d)(t,"Bladeburner.getCityEstimatedPopulation() failed with exception: "+e)}throw Object(K.d)(t,"getCityEstimatedPopulation() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed at the Bladeburner division or because you do not have Source-File 7")},getCityEstimatedCommunities:function(e){if(t.checkingRam)return se("getCityEstimatedCommunities",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);if(n("getCityEstimatedCommunities",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),M.a.bladeburner instanceof u.a&&(7===M.a.bitNodeN||pe))try{return M.a.bladeburner.getCityEstimatedCommunitiesNetscriptFn(e,t)}catch(e){throw Object(K.d)(t,"Bladeburner.getCityEstimatedCommunities() failed with exception: "+e)}throw Object(K.d)(t,"getCityEstimatedCommunities() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed at the Bladeburner division or because you do not have Source-File 7")},getCityChaos:function(e){if(t.checkingRam)return se("getCityChaos",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);if(n("getCityChaos",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),M.a.bladeburner instanceof u.a&&(7===M.a.bitNodeN||pe))try{return M.a.bladeburner.getCityChaosNetscriptFn(e,t)}catch(e){throw Object(K.d)(t,"Bladeburner.getCityChaos() failed with exception: "+e)}throw Object(K.d)(t,"getCityChaos() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed at the Bladeburner division or because you do not have Source-File 7")},getCity:function(){if(t.checkingRam)return se("getCity",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);if(n("getCity",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),M.a.bladeburner instanceof u.a&&(7===M.a.bitNodeN||pe))try{return M.a.bladeburner.city}catch(e){throw Object(K.d)(t,"Bladeburner.getCity() failed with exception: "+e)}throw Object(K.d)(t,"getCity() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed at the Bladeburner division or because you do not have Source-File 7")},switchCity:function(e){if(t.checkingRam)return se("switchCity",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);if(n("switchCity",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),M.a.bladeburner instanceof u.a&&(7===M.a.bitNodeN||pe))try{return M.a.bladeburner.switchCityNetscriptFn(e,t)}catch(e){throw Object(K.d)(t,"Bladeburner.switchCity() failed with exception: "+e)}throw Object(K.d)(t,"switchCity() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed at the Bladeburner division or because you do not have Source-File 7")},getStamina:function(){if(t.checkingRam)return se("getStamina",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);if(n("getStamina",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),M.a.bladeburner instanceof u.a&&(7===M.a.bitNodeN||pe))return[M.a.bladeburner.stamina,M.a.bladeburner.maxStamina];throw Object(K.d)(t,"getStamina() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed at the Bladeburner division or because you do not have Source-File 7")},joinBladeburnerFaction:function(){if(t.checkingRam)return se("joinBladeburnerFaction",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);if(n("joinBladeburnerFaction",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),M.a.bladeburner instanceof u.a&&(7===M.a.bitNodeN||pe))return M.a.bladeburner.joinBladeburnerFactionNetscriptFn(t);throw Object(K.d)(t,"joinBladeburnerFaction() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed at the Bladeburner division or because you do not have Source-File 7")},joinBladeburnerDivision:function(){if(t.checkingRam)return se("joinBladeburnerDivision",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);if(n("joinBladeburnerDivision",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),7===M.a.bitNodeN||pe)return M.a.bladeburner instanceof u.a||(M.a.strength>=100&&M.a.defense>=100&&M.a.dexterity>=100&&M.a.agility>=100?(M.a.bladeburner=new u.a({new:!0}),t.log("You have been accepted into the Bladeburner division"),!0):(t.log("You do not meet the requirements for joining the Bladeburner division"),!1));throw Object(K.d)(t,"joinBladeburnerDivision() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed at the Bladeburner division or because you do not have Source-File 7")},getBonusTime:function(){if(t.checkingRam)return 0;if(7===M.a.bitNodeN||pe)return Math.round(M.a.bladeburner.storedCycles/5);throw Object(K.d)(t,"getBonusTime() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed at the Bladeburner division or because you do not have Source-File 7")}},codingcontract:{attempt:function(e,a,i=t.serverIp){if(t.checkingRam)return se("attempt",g.CONSTANTS.ScriptCodingContractBaseRamCost);n("attempt",g.CONSTANTS.ScriptCodingContractBaseRamCost);const r=fe(a,i);if(null==r)return t.log(`ERROR: codingcontract.getData() failed because it could find the specified contract ${a} on server ${i}`),!1;if(Object(X.is2DArray)(e)){let t=[];for(let n=0;n=r.getMaxNumTries()?(t.log(`Coding Contract ${a} failed. Contract is now self-destructing`),o.removeContract(a)):t.log(`Coding Contract ${a} failed. ${r.getMaxNumTries()-r.tries} attempts remaining`),!1},getContractType:function(e,a=t.serverIp){if(t.checkingRam)return se("getContractType",g.CONSTANTS.ScriptCodingContractBaseRamCost/2);n("getContractType",g.CONSTANTS.ScriptCodingContractBaseRamCost/2);let i=fe(e,a);return null==i?(t.log(`ERROR: codingcontract.getData() failed because it could find the specified contract ${e} on server ${a}`),null):i.getType()},getData:function(e,a=t.serverIp){if(t.checkingRam)return se("getData",g.CONSTANTS.ScriptCodingContractBaseRamCost/2);n("getData",g.CONSTANTS.ScriptCodingContractBaseRamCost/2);let i=fe(e,a);if(null==i)return t.log(`ERROR: codingcontract.getData() failed because it could find the specified contract ${e} on server ${a}`),null;let r=i.getData();if(r.constructor===Array){const e=r.slice();for(let t=0;t=M.a.sleeves.length||e<0?(t.log(`ERROR: sleeve.setToShockRecovery(${e}) failed because it is an invalid sleeve number.`),!1):M.a.sleeves[e].shockRecovery(M.a)},setToSynchronize:function(e=0){if(t.checkingRam)return se("setToSynchronize",g.CONSTANTS.ScriptSleeveBaseRamCost);if(10!==M.a.bitNodeN&&!j.SourceFileFlags[10])throw Object(K.d)(t,"setToSynchronize() failed because you do not currently have access to the Sleeve API. This is either because you are not in BitNode-10 or because you do not have Source-File 10");return n("setToSynchronize",g.CONSTANTS.ScriptSleeveBaseRamCost),e>=M.a.sleeves.length||e<0?(t.log(`ERROR: sleeve.setToSynchronize(${e}) failed because it is an invalid sleeve number.`),!1):M.a.sleeves[e].synchronize(M.a)},setToCommitCrime:function(e=0,a=""){if(t.checkingRam)return se("setToCommitCrime",g.CONSTANTS.ScriptSleeveBaseRamCost);if(10!==M.a.bitNodeN&&!j.SourceFileFlags[10])throw Object(K.d)(t,"setToCommitCrime() failed because you do not currently have access to the Sleeve API. This is either because you are not in BitNode-10 or because you do not have Source-File 10");return n("setToCommitCrime",g.CONSTANTS.ScriptSleeveBaseRamCost),e>=M.a.sleeves.length||e<0?(t.log(`ERROR: sleeve.setToCommitCrime(${e}) failed because it is an invalid sleeve number.`),!1):M.a.sleeves[e].commitCrime(M.a,a)},setToUniversityCourse:function(e=0,a="",i=""){if(t.checkingRam)return se("setToUniversityCourse",g.CONSTANTS.ScriptSleeveBaseRamCost);if(10!==M.a.bitNodeN&&!j.SourceFileFlags[10])throw Object(K.d)(t,"setToUniversityCourse() failed because you do not currently have access to the Sleeve API. This is either because you are not in BitNode-10 or because you do not have Source-File 10");return n("setToUniversityCourse",g.CONSTANTS.ScriptSleeveBaseRamCost),e>=M.a.sleeves.length||e<0?(t.log(`ERROR: sleeve.setToUniversityCourse(${e}) failed because it is an invalid sleeve number.`),!1):M.a.sleeves[e].takeUniversityCourse(M.a,a,i)},travel:function(e=0,a=""){if(t.checkingRam)return se("travel",g.CONSTANTS.ScriptSleeveBaseRamCost);if(10!==M.a.bitNodeN&&!j.SourceFileFlags[10])throw Object(K.d)(t,"travel() failed because you do not currently have access to the Sleeve API. This is either because you are not in BitNode-10 or because you do not have Source-File 10");return n("travel",g.CONSTANTS.ScriptSleeveBaseRamCost),e>=M.a.sleeves.length||e<0?(t.log(`ERROR: sleeve.travel(${e}) failed because it is an invalid sleeve number.`),!1):M.a.sleeves[e].travel(M.a,a)},setToCompanyWork:function(e=0,a=""){if(t.checkingRam)return se("setToCompanyWork",g.CONSTANTS.ScriptSleeveBaseRamCost);if(10!==M.a.bitNodeN&&!j.SourceFileFlags[10])throw Object(K.d)(t,"setToCompanyWork() failed because you do not currently have access to the Sleeve API. This is either because you are not in BitNode-10 or because you do not have Source-File 10");if(n("setToCompanyWork",g.CONSTANTS.ScriptSleeveBaseRamCost),e>=M.a.sleeves.length||e<0)return t.log(`ERROR: sleeve.setToCompanyWork(${e}) failed because it is an invalid sleeve number.`),!1;for(let n=0;n=M.a.sleeves.length||e<0)return t.log(`ERROR: sleeve.setToFactionWork(${e}) failed because it is an invalid sleeve number.`),!1;for(let n=0;n=M.a.sleeves.length||e<0?(t.log(`ERROR: sleeve.setToGymWorkout(${e}) failed because it is an invalid sleeve number.`),!1):M.a.sleeves[e].workoutAtGym(M.a,a,i)},getSleeveStats:function(e=0){if(t.checkingRam)return se("workoutAtGym",g.CONSTANTS.ScriptSleeveBaseRamCost);if(10!==M.a.bitNodeN&&!j.SourceFileFlags[10])throw Object(K.d)(t,"getStats() failed because you do not currently have access to the Sleeve API. This is either because you are not in BitNode-10 or because you do not have Source-File 10");if(n("workoutAtGym",g.CONSTANTS.ScriptSleeveBaseRamCost),e>=M.a.sleeves.length||e<0)return t.log(`ERROR: sleeve.workoutAtGym(${e}) failed because it is an invalid sleeve number.`),!1;const a=M.a.sleeves[e];return{shock:100-a.shock,sync:a.sync,hacking_skill:a.hacking_skill,strength:a.strength,defense:a.defense,dexterity:a.dexterity,agility:a.agility,charisma:a.charisma}},getTask:function(e=0){if(t.checkingRam)return se("getTask",g.CONSTANTS.ScriptSleeveBaseRamCost);if(10!==M.a.bitNodeN&&!j.SourceFileFlags[10])throw Object(K.d)(t,"getTask() failed because you do not currently have access to the Sleeve API. This is either because you are not in BitNode-10 or because you do not have Source-File 10");if(n("getTask",g.CONSTANTS.ScriptSleeveBaseRamCost),e>=M.a.sleeves.length||e<0)return t.log(`ERROR: sleeve.getTask(${e}) failed because it is an invalid sleeve number.`),!1;const a=M.a.sleeves[e];return{task:$.SleeveTaskType[a.currentTask],crime:a.crimeType,location:a.currentTaskLocation,gymStatType:a.gymStatType,factionWorkType:k.FactionWorkType[a.factionWorkType]}},getInformation:function(e=0){if(t.checkingRam)return se("getInformation",g.CONSTANTS.ScriptSleeveBaseRamCost);if(10!==M.a.bitNodeN&&!j.SourceFileFlags[10])throw Object(K.d)(t,"getInformation() failed because you do not currently have access to the Sleeve API. This is either because you are not in BitNode-10 or because you do not have Source-File 10");if(n("getInformation",g.CONSTANTS.ScriptSleeveBaseRamCost),e>=M.a.sleeves.length||e<0)return t.log(`ERROR: sleeve.getInformation(${e}) failed because it is an invalid sleeve number.`),!1;const a=M.a.sleeves[e];return{city:a.city,hp:a.hp,jobs:Object.keys(M.a.jobs),jobTitle:Object.values(M.a.jobs),maxHp:a.max_hp,tor:D.SpecialServerIps.hasOwnProperty("Darkweb Server"),mult:{agility:a.agility_mult,agilityExp:a.agility_exp_mult,companyRep:a.company_rep_mult,crimeMoney:a.crime_money_mult,crimeSuccess:a.crime_success_mult,defense:a.defense_mult,defenseExp:a.defense_exp_mult,dexterity:a.dexterity_mult,dexterityExp:a.dexterity_exp_mult,factionRep:a.faction_rep_mult,hacking:a.hacking_mult,hackingExp:a.hacking_exp_mult,strength:a.strength_mult,strengthExp:a.strength_exp_mult,workMoney:a.work_money_mult},timeWorked:a.currentTaskTime,earningsForSleeves:{workHackExpGain:a.earningsForSleeves.hack,workStrExpGain:a.earningsForSleeves.str,workDefExpGain:a.earningsForSleeves.def,workDexExpGain:a.earningsForSleeves.dex,workAgiExpGain:a.earningsForSleeves.agi,workChaExpGain:a.earningsForSleeves.cha,workMoneyGain:a.earningsForSleeves.money},earningsForPlayer:{workHackExpGain:a.earningsForPlayer.hack,workStrExpGain:a.earningsForPlayer.str,workDefExpGain:a.earningsForPlayer.def,workDexExpGain:a.earningsForPlayer.dex,workAgiExpGain:a.earningsForPlayer.agi,workChaExpGain:a.earningsForPlayer.cha,workMoneyGain:a.earningsForPlayer.money},earningsForTask:{workHackExpGain:a.earningsForTask.hack,workStrExpGain:a.earningsForTask.str,workDefExpGain:a.earningsForTask.def,workDexExpGain:a.earningsForTask.dex,workAgiExpGain:a.earningsForTask.agi,workChaExpGain:a.earningsForTask.cha,workMoneyGain:a.earningsForTask.money},workRepGain:a.getRepGain()}}}}}}).call(this,n(79))},function(e,t,n){"use strict";n.d(t,"a",function(){return i}),n.d(t,"b",function(){return r}),n.d(t,"f",function(){return l}),n.d(t,"e",function(){return c}),n.d(t,"g",function(){return p}),n.d(t,"h",function(){return m}),n.d(t,"c",function(){return o}),n.d(t,"d",function(){return s});var a=n(10);let i={},r={};function o(e){i=""===e?{}:JSON.parse(e)}function s(e){r=""===e?{}:JSON.parse(e)}function l(){for(var e in i)i.hasOwnProperty(e)&&Object(a.post)("alias "+e+"="+i[e]);for(var e in r)r.hasOwnProperty(e)&&Object(a.post)("global alias "+e+"="+r[e])}function c(e,t=!1){var n=e.match(/^([_|\w|!|%|,|@]+)="(.+)"$/);return null!=n&&3==n.length&&(t?function(e,t){e in i&&delete i[e];r[e]=t}(n[1],n[2]):function(e,t){e in r&&delete r[e];i[e]=t}(n[1],n[2]),!0)}function u(e){return r.hasOwnProperty(e)?r[e]:null}function p(e){return i.hasOwnProperty(e)?(delete i[e],!0):!!r.hasOwnProperty(e)&&(delete r[e],!0)}function m(e){var t=e.split(" ");if(t.length>0){if("unalias"===t[0])return t.join(" ");if(null!=(a=function(e){return i.hasOwnProperty(e)?i[e]:null}(t[0])))t[0]=a;else null!=(a=u(t[0]))&&(t[0]=a);for(var n=0;n"+n.infoText+""})),a.push(Object(k.createElement)("p",{innerText:"---------------"}));var i=t.getFavorGain();2!=i.length&&(i=0),i=i[0],a.push(Object(k.createElement)("p",{innerText:"Reputation: "+Object(C.formatNumber)(t.playerReputation,4),tooltip:"You will earn "+Object(C.formatNumber)(i,0)+" faction favor upon resetting after installing an Augmentation"})),a.push(Object(k.createElement)("p",{innerText:"---------------"})),a.push(Object(k.createElement)("p",{innerText:"Faction Favor: "+Object(C.formatNumber)(t.favor,0),tooltip:"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 favor you gain depends on how much reputation you have with the faction"})),a.push(Object(k.createElement)("p",{innerText:"---------------"})),a.push(Object(k.createElement)("pre",{id:"faction-work-description-text",innerText:"Perform work/carry out assignments for your faction to help further its cause! By doing so you will earn reputation for your faction. You will also gain reputation passively over time, although at a very slow rate. Earning reputation will allow you to purchase Augmentations through this faction, which are powerful upgrades that enhance your abilities. Note that you cannot use your terminal or create scripts when you are performing a task!"})),a.push(Object(k.createElement)("br"));var r=Object(k.createElement)("div",{class:"faction-work-div"}),c=Object(k.createElement)("div",{class:"faction-work-div-wrapper"});r.appendChild(c),c.appendChild(Object(k.createElement)("a",{class:"a-link-button",innerText:"Hacking Mission",clickListener:()=>{l.Engine.loadMissionContent();var e=new p.a(t.playerReputation,t);return Object(p.d)(!0,e),e.init(),!1}})),c.appendChild(Object(k.createElement)("p",{innerText:"Attempt a hacking mission for your faction. A mission is a mini game that, if won, earns you significant reputation with this faction. (Recommended hacking level: 200+)"})),a.push(r);var h=Object(k.createElement)("div",{class:"faction-work-div"}),d=Object(k.createElement)("div",{class:"faction-work-div-wrapper"});h.appendChild(d),d.appendChild(Object(k.createElement)("a",{class:"std-button",innerText:"Hacking Contracts",clickListener:()=>(m.a.startFactionHackWork(t),!1)})),d.appendChild(Object(k.createElement)("p",{innerText:"Complete hacking contracts for your faction. Your effectiveness, which determines how much reputation you gain for this faction, is based on your hacking skill. You will gain hacking exp."})),a.push(h);var f=Object(k.createElement)("div",{class:"faction-work-div"}),v=Object(k.createElement)("div",{class:"faction-work-div-wrapper"});f.appendChild(v),v.appendChild(Object(k.createElement)("a",{class:"std-button",innerText:"Field Work",clickListener:()=>(m.a.startFactionFieldWork(t),!1)})),v.appendChild(Object(k.createElement)("p",{innerText:"Carry out field missions for your faction. Your effectiveness, which determines how much reputation you gain for this faction, is based on all of your stats. You will gain exp for all stats."})),a.push(f);var O=Object(k.createElement)("div",{class:"faction-work-div"}),S=Object(k.createElement)("div",{class:"faction-work-div-wrapper"});O.appendChild(S),S.appendChild(Object(k.createElement)("a",{class:"std-button",innerText:"Security Work",clickListener:()=>(m.a.startFactionSecurityWork(t),!1)})),S.appendChild(Object(k.createElement)("p",{innerText:"Serve in a security detail for your faction. Your effectiveness, which determines how much reputation you gain for this faction, is based on your combat stats. You will gain exp for all combat stats."})),a.push(O);var A=Object(k.createElement)("div",{class:"faction-work-div"}),w=Object(k.createElement)("div",{class:"faction-work-div-wrapper"});A.appendChild(w);var x=Object(k.createElement)("p",{innerText:"This donation will result in 0.000 reputation gain"}),R=Object(k.createElement)("input",{class:"text-input",placeholder:"Donation amount",inputListener:()=>{let e=0;if(""!==R.value&&(e=parseFloat(R.value)),isNaN(e))x.innerText="Invalid donate amount entered!";else{var t=e/s.CONSTANTS.DonateMoneyToRepDivisor*m.a.faction_rep_mult;x.innerText="This donation will result in "+Object(C.formatNumber)(t,3)+" reputation gain"}}});w.appendChild(Object(k.createElement)("a",{class:"std-button",innerText:"Donate Money",clickListener:()=>{var n=parseFloat(R.value);if(isNaN(n)||n<0)Object(b.dialogBoxCreate)("Invalid amount entered!");else if(m.a.money.lt(n))Object(b.dialogBoxCreate)("You cannot afford to donate this much money!");else{m.a.loseMoney(n);var a=n/s.CONSTANTS.DonateMoneyToRepDivisor*m.a.faction_rep_mult;t.playerReputation+=a,Object(b.dialogBoxCreate)("You just donated "+y.numeralWrapper.format(n,"$0.000a")+" to "+t.name+" to gain "+Object(C.formatNumber)(a,3)+" reputation"),M(e)}}})),w.appendChild(R),w.appendChild(x),a.push(A);const N=Object(k.createElement)("div",{class:"faction-work-div",display:"inline"}),I=Object(k.createElement)("div",{class:"faction-work-div-wrapper"});if(N.appendChild(I),I.appendChild(Object(k.createElement)("a",{class:"std-button",innerText:"Purchase Augmentations",margin:"5px",clickListener:()=>(l.Engine.hideAllContent(),l.Engine.Display.factionAugmentationsContent.style.display="block",P(e),!1)})),I.appendChild(Object(k.createElement)("pre",{innerHTML:"
    As your reputation with this faction rises, you will unlock Augmentations, which you can purchase to enhance your abilities.

    "})),a.push(N),2!=m.a.bitNodeN||"Slum Snakes"!=e&&"Tetrads"!=e&&"The Syndicate"!=e&&"The Dark Army"!=e&&"Speakers for the Dead"!=e&&"NiteSec"!=e&&"The Black Hand"!=e){if("The Covenant"===e&&m.a.bitNodeN>=10&&g.SourceFileFlags[10]){const e=Object(k.createElement)("div",{class:"faction-work-div",display:"inline"}),t=Object(k.createElement)("div",{class:"faction-work-div-wrapper"});e.appendChild(t),t.appendChild(Object(k.createElement)("a",{class:"std-button",innerText:"Purchase Duplicate Sleeves",clickListener:()=>{Object(_.createPurchaseSleevesFromCovenantPopup)(m.a)}})),t.appendChild(Object(k.createElement)("p",{innerText:"Purchase Duplicate Sleeves. These are permanent! You can purchase up to 5 total."})),a.push(e)}A.style.display=t.favor>=Math.floor(s.CONSTANTS.BaseFavorToDonate*o.BitNodeMultipliers.RepToDonateToFaction)?"inline":"none",r.style.display=n.offerHackingMission?"inline":"none",h.style.display=n.offerHackingWork?"inline":"none",f.style.display=n.offerFieldWork?"inline":"none",O.style.display=n.offerSecurityWork?"inline":"none";for(B=0;B{if(m.a.inGang())l.Engine.loadGangContent();else{let a=!1;"NiteSec"!==e&&"The Black Hand"!==e||(a=!0);var t=Object(T.yesNoBoxGetYesButton)(),n=Object(T.yesNoBoxGetNoButton)();t.innerHTML="Create Gang",n.innerHTML="Cancel",t.addEventListener("click",()=>{m.a.startGang(e,a),document.getElementById("world-menu-header").click(),document.getElementById("world-menu-header").click(),l.Engine.loadGangContent(),Object(T.yesNoBoxClose)()}),n.addEventListener("click",()=>{Object(T.yesNoBoxClose)()});let i="";i=a?"This is a HACKING gang. Members in this gang will have different tasks than COMBAT gangs. Compared to combat gangs, progression with hacking gangs is more straightforward as territory warfare is not as important.

    ":"This is a COMBAT gang. Members in this gang will have different tasks than HACKING gangs. Compared to hacking gangs, progression with combat gangs can be more difficult as territory management is more important. However, well-managed combat gangs can progress faster than hacking ones.

    ",Object(T.yesNoBoxCreate)(`Would you like to create a new Gang with ${e}?

    `+"Note that this will prevent you from creating a Gang with any other Faction until this BitNode is destroyed.

    "+i+"Other than hacking vs combat, there are NO differences between the Factions you can create a Gang with, and each of these Factions have all Augmentations available.")}}})),D.appendChild(Object(k.createElement)("p",{innerText:"Create and manage a gang for this Faction. Gangs will earn you money and faction reputation."})),a.splice(7,1,L),m.a.inGang()&&m.a.gang.facName!=e&&(L.style.display="none");for(var B=0;B(l.Engine.loadFactionContent(),M(e),!1)})),n.push(Object(k.createElement)("h1",{innerText:"Faction Augmentations"})),n.push(Object(k.createElement)("p",{id:"faction-augmentations-page-desc",innerHTML:"Lists all Augmentations that are available to purchase from "+e+"

    Augmentations are powerful upgrades that will enhance your abilities."})),n.push(Object(k.createElement)("br")),n.push(Object(k.createElement)("br"));var i=Object(k.createElement)("ul");const r=Object(k.createElement)("a",{innerText:"Sort by Cost",class:"a-link-button",clickListener:()=>{d.Settings.PurchaseAugmentationsOrder=h.PurchaseAugmentationsOrderSetting.Cost;var e=t.augmentations.slice();e.sort((e,t)=>{var n=a.Augmentations[e],i=a.Augmentations[t];if(null==n||null==i)throw new Error("Invalid Augmentation Names");return n.baseCost-i.baseCost}),Object(E.removeChildrenFromElement)(i),A(i,e,t)}}),o=Object(k.createElement)("a",{innerText:"Sort by Reputation",class:"a-link-button",clickListener:()=>{d.Settings.PurchaseAugmentationsOrder=h.PurchaseAugmentationsOrderSetting.Reputation;var e=t.augmentations.slice();e.sort((e,t)=>{var n=a.Augmentations[e],i=a.Augmentations[t];if(null==n||null==i)throw new Error("Invalid Augmentation Names");return n.baseRepRequirement-i.baseRepRequirement}),Object(E.removeChildrenFromElement)(i),A(i,e,t)}}),s=Object(k.createElement)("a",{innerText:"Sort by Default Order",class:"a-link-button",clickListener:()=>{d.Settings.PurchaseAugmentationsOrder=h.PurchaseAugmentationsOrderSetting.Default,Object(E.removeChildrenFromElement)(i),A(i,t.augmentations,t)}});switch(n.push(r),n.push(o),n.push(s),d.Settings.PurchaseAugmentationsOrder){case h.PurchaseAugmentationsOrderSetting.Cost:r.click();break;case h.PurchaseAugmentationsOrderSetting.Reputation:o.click();break;default:s.click()}n.push(i);for(var c=0;c(d.Settings.SuppressBuyAugmentationConfirmation?R(s,n):w(s,n),!1)});s.name==r.AugmentationNames.NeuroFluxGovernor&&(g.innerText+=" - Level "+N());var _=Object(k.createElement)("p",{display:"inline"}),f=s.baseRepRequirement*i.augmentationRepRequirementMult;x(s)?s.name!=r.AugmentationNames.NeuroFluxGovernor&&(s.owned||l)?(g.setAttribute("class","a-link-button-inactive"),_.innerHTML="ALREADY OWNED"):n.playerReputation>=f?(g.setAttribute("class","a-link-button"),_.innerHTML="UNLOCKED - "+y.numeralWrapper.format(s.baseCost*i.augmentationPriceMult,"$0.000a")):(g.setAttribute("class","a-link-button-inactive"),_.innerHTML="LOCKED (Requires "+Object(C.formatNumber)(f,1)+" faction reputation) - "+y.numeralWrapper.format(s.baseCost*i.augmentationPriceMult,"$0.000a"),_.style.color="red"):(g.setAttribute("class","a-link-button-inactive"),_.innerHTML="LOCKED (Requires "+s.prereqs.join(",")+" as prerequisite(s))",_.style.color="red"),h.appendChild(g),p.appendChild(h),p.appendChild(_),u.appendChild(p),e.appendChild(u)}()}function w(e,t){const n=t.getInfo();var a=Object(T.yesNoBoxGetYesButton)(),i=Object(T.yesNoBoxGetNoButton)();a.innerHTML="Purchase",i.innerHTML="Cancel",a.addEventListener("click",function(){R(e,t)}),i.addEventListener("click",function(){Object(T.yesNoBoxClose)()}),Object(T.yesNoBoxCreate)("

    "+e.name+"


    "+e.info+"


    Would you like to purchase the "+e.name+" Augmentation for $"+Object(C.formatNumber)(e.baseCost*n.augmentationPriceMult,2)+"?")}function x(e){var t=!0;if(e.prereqs&&e.prereqs.length>0)for(var n=0;n{if(e instanceof Element)i.removeElement(e);else try{const t=document.getElementById(e);t instanceof Element&&i.removeElement(t)}catch(e){console.error(`createPopupCloseButton() threw: ${e}`)}return document.removeEventListener("keydown",r),!1}}),document.addEventListener("keydown",r),n}},function(e,t,n){"use strict";n.d(t,"b",function(){return r}),n.d(t,"c",function(){return o}),n.d(t,"e",function(){return s}),n.d(t,"d",function(){return l}),n.d(t,"a",function(){return c}),n.d(t,"f",function(){return u});var a=n(20),i=n(0);n(74);function r(e){const t=(100-e.hackDifficulty)/100,n=1.75*i.a.hacking_skill+.2*i.a.intelligence,a=(n-e.requiredHackingSkill)/n*t*i.a.hacking_chance_mult;return a>1?1:a<0?0:a}function o(e){null==e.baseDifficulty&&(e.baseDifficulty=e.hackDifficulty);var t=3;return(t+=e.baseDifficulty*i.a.hacking_exp_mult*.3)*a.BitNodeMultipliers.HackExpGain}function s(e){const t=(100-e.hackDifficulty)/100*((i.a.hacking_skill-(e.requiredHackingSkill-1))/i.a.hacking_skill)*i.a.hacking_money_mult/240;return t<0?0:t>1?1:t*a.BitNodeMultipliers.ScriptHackMoney}function l(e,t,n){const a=e.requiredHackingSkill*e.hackDifficulty;null==t&&(t=i.a.hacking_skill),null==n&&(n=i.a.intelligence);var r=2.5*a+500;return 5*(r/=t+50+.1*n)/i.a.hacking_speed_mult}function c(e,t,n){return 3.2*l(e,t,n)}function u(e,t,n){return 4*l(e,t,n)}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const a=n(1);t.SourceFileFlags=Array(a.CONSTANTS.TotalNumBitNodes+1),t.updateSourceFileFlags=function(e){for(let e=0;e{let e=M();return null!=e&&e.beautifyScript(),!1}});O=Object(C.createElement)("p",{display:"inline-block",margin:"10px",id:"script-editor-status-text"});const n=Object(C.createElement)("label",{for:"script-editor-ram-check",margin:"4px",marginTop:"8px",innerText:"Dynamic RAM Usage Checker",color:"white",tooltip:"Enable/Disable the dynamic RAM Usage display. You may want to disable it for very long scripts because there may be performance issues"});(T=Object(C.createElement)("input",{type:"checkbox",name:"script-editor-ram-check",id:"script-editor-ram-check",margin:"4px",marginTop:"8px"})).checked=!0;const a=Object(C.createElement)("a",{class:"std-button",display:"inline-block",href:"https://bitburner.readthedocs.io/en/latest/index.html",innerText:"Netscript Documentation",target:"_blank"}),i=Object(C.createElement)("button",{class:"std-button",display:"inline-block",innerText:"Save & Close (Ctrl/Cmd + b)",clickListener:()=>(A(),!1)});e.appendChild(t),e.appendChild(i),e.appendChild(O),e.appendChild(T),e.appendChild(n),e.appendChild(a);const r={saveAndCloseFn:A,quitFn:s.Engine.loadTerminalContent};m.a.init(r),h.a.init(r);const o=document.getElementById("script-editor-option-editor");if(null==o)return console.error("Could not find DOM Element for editor selector (id=script-editor-option-editor)"),!1;for(let e=0;e{const e=o.value;switch(e){case f.EditorSetting.Ace:const t=h.a.getCode(),n=h.a.getFilename();m.a.create(),h.a.setInvisible(),m.a.openScript(n,t);break;case f.EditorSetting.CodeMirror:const a=m.a.getCode(),i=m.a.getFilename();h.a.create(),m.a.setInvisible(),h.a.openScript(i,a);break;default:return void console.error(`Unrecognized Editor Setting: ${e}`)}_.Settings.Editor=e}),o.onchange()}function M(){switch(_.Settings.Editor){case f.EditorSetting.Ace:return m.a;case f.EditorSetting.CodeMirror:return h.a;default:throw console.log(`Invalid Editor Setting: ${_.Settings.Editor}`),new Error(`Invalid Editor Setting: ${_.Settings.Editor}`)}}async function P(){var e=document.getElementById("script-editor-filename").value;if(null==T||!T.checked||!Object(r.isScriptFilename)(e))return void(O.innerText="N/A");let t;try{t=M().getCode()}catch(e){return void(O.innerText="RAM: ERROR")}var n=t.repeat(1),a=await Object(i.calculateRamUsage)(n);O.innerText=-1!==a?"RAM: "+v.numeralWrapper.format(a,"0.00")+" GB":"RAM: Syntax Error"}function A(){var e=document.getElementById("script-editor-filename").value;let t;try{t=M().getCode()}catch(e){return void Object(E.dialogBoxCreate)("Something went wrong when trying to save (getCurrentEditor().getCode()). Please report to game developer with details")}if(c.a.isRunning&&c.a.currStep===c.d.TerminalTypeScript){if("foodnstuff.script"!==e)return void Object(E.dialogBoxCreate)("Leave the script name as 'foodnstuff'!");if(-1==(t=t.replace(/\s/g,"")).indexOf("while(true){hack('foodnstuff');}"))return void Object(E.dialogBoxCreate)("Please copy and paste the code from the tutorial!");let i=p.a.getCurrentServer();for(var n=0;n=1&&(n=1),e.dataMap)if(e.dataMap.hasOwnProperty(a)){if(0==e.dataMap[a][2]||null==e.dataMap[a][2])continue;if(null==(m=d.AllServers[a]))continue;var i=Math.round(.5*e.dataMap[a][2]/e.onlineRunningTime*t);console.log(e.filename+" called grow() on "+m.hostname+" "+i+" times while offline"),e.log("Called grow() on "+m.hostname+" "+i+" times while offline");var r=Object(g.processSingleServerGrowth)(m,450*i,p.a);e.log(m.hostname+" grown by "+v.numeralWrapper.format(100*r-100,"0.000000%")+" from grow() calls made while offline")}var s=0;for(var a in e.dataMap)if(e.dataMap.hasOwnProperty(a)){if(0==e.dataMap[a][0]||null==e.dataMap[a][0])continue;if(null==(m=d.AllServers[a]))continue;var l=.5*e.dataMap[a][0]/e.onlineRunningTime*t;(l*=n)>m.moneyAvailable&&(l=m.moneyAvailable),s+=l,p.a.gainMoney(l),p.a.recordMoneySource(l,"hacking"),console.log(e.filename+" generated $"+l+" while offline by hacking "+m.hostname),e.log(e.filename+" generated $"+l+" while offline by hacking "+m.hostname),m.moneyAvailable-=l,m.moneyAvailable<0&&(m.moneyAvailable=0),isNaN(m.moneyAvailable)&&(m.moneyAvailable=0)}var c=e.onlineExpGained/e.onlineRunningTime*.5*t;for(var a in c*=n,p.a.gainHackingExp(c),e.offlineMoneyMade+=s,e.offlineRunningTime+=t,e.offlineExpGained+=c,e.dataMap)if(e.dataMap.hasOwnProperty(a)){if(0==e.dataMap[a][1]||null==e.dataMap[a][1])continue;if(null==(m=d.AllServers[a]))continue;var u=Math.round(.5*e.dataMap[a][1]/e.onlineRunningTime*t);console.log(e.filename+" hacked "+m.hostname+" "+u+" times while offline"),e.log("Hacked "+m.hostname+" "+u+" times while offline"),m.fortify(o.CONSTANTS.ServerFortifyAmount*u)}for(var a in e.dataMap)if(e.dataMap.hasOwnProperty(a)){if(0==e.dataMap[a][3]||null==e.dataMap[a][3])continue;var m;if(null==(m=d.AllServers[a]))continue;var h=Math.round(.5*e.dataMap[a][3]/e.onlineRunningTime*t);console.log(e.filename+" called weaken() on "+m.hostname+" "+h+" times while offline"),e.log("Called weaken() on "+m.hostname+" "+h+" times while offline"),m.weaken(o.CONSTANTS.ServerWeakenAmount*h)}return s}function R(e,t,n){for(var a=0;ae)return!1;if((n+=t[a+1])>=e)return!0}}function p(e,t){return e<65?36===e:e<91||(e<97?95===e:e<123||(e<=65535?e>=170&&o.test(String.fromCharCode(e)):!1!==t&&u(e,l)))}function m(e,t){return e<48?36===e:e<58||!(e<65)&&(e<91||(e<97?95===e:e<123||(e<=65535?e>=170&&s.test(String.fromCharCode(e)):!1!==t&&(u(e,l)||u(e,c)))))}var h=function(e,t){void 0===t&&(t={}),this.label=e,this.keyword=t.keyword,this.beforeExpr=!!t.beforeExpr,this.startsExpr=!!t.startsExpr,this.isLoop=!!t.isLoop,this.isAssign=!!t.isAssign,this.prefix=!!t.prefix,this.postfix=!!t.postfix,this.binop=t.binop||null,this.updateContext=null};function d(e,t){return new h(e,{beforeExpr:!0,binop:t})}var g={beforeExpr:!0},_={startsExpr:!0},f={};function y(e,t){return void 0===t&&(t={}),t.keyword=e,f[e]=new h(e,t)}var b={num:new h("num",_),regexp:new h("regexp",_),string:new h("string",_),name:new h("name",_),eof:new h("eof"),bracketL:new h("[",{beforeExpr:!0,startsExpr:!0}),bracketR:new h("]"),braceL:new h("{",{beforeExpr:!0,startsExpr:!0}),braceR:new h("}"),parenL:new h("(",{beforeExpr:!0,startsExpr:!0}),parenR:new h(")"),comma:new h(",",g),semi:new h(";",g),colon:new h(":",g),dot:new h("."),question:new h("?",g),arrow:new h("=>",g),template:new h("template"),ellipsis:new h("...",g),backQuote:new h("`",_),dollarBraceL:new h("${",{beforeExpr:!0,startsExpr:!0}),eq:new h("=",{beforeExpr:!0,isAssign:!0}),assign:new h("_=",{beforeExpr:!0,isAssign:!0}),incDec:new h("++/--",{prefix:!0,postfix:!0,startsExpr:!0}),prefix:new h("prefix",{beforeExpr:!0,prefix:!0,startsExpr:!0}),logicalOR:d("||",1),logicalAND:d("&&",2),bitwiseOR:d("|",3),bitwiseXOR:d("^",4),bitwiseAND:d("&",5),equality:d("==/!=",6),relational:d("",7),bitShift:d("<>",8),plusMin:new h("+/-",{beforeExpr:!0,binop:9,prefix:!0,startsExpr:!0}),modulo:d("%",10),star:d("*",10),slash:d("/",10),starstar:new h("**",{beforeExpr:!0}),_break:y("break"),_case:y("case",g),_catch:y("catch"),_continue:y("continue"),_debugger:y("debugger"),_default:y("default",g),_do:y("do",{isLoop:!0,beforeExpr:!0}),_else:y("else",g),_finally:y("finally"),_for:y("for",{isLoop:!0}),_function:y("function",_),_if:y("if"),_return:y("return",g),_switch:y("switch"),_throw:y("throw",g),_try:y("try"),_var:y("var"),_const:y("const"),_while:y("while",{isLoop:!0}),_with:y("with"),_new:y("new",{beforeExpr:!0,startsExpr:!0}),_this:y("this",_),_super:y("super",_),_class:y("class"),_extends:y("extends",g),_export:y("export"),_import:y("import"),_null:y("null",_),_true:y("true",_),_false:y("false",_),_in:y("in",{beforeExpr:!0,binop:7}),_instanceof:y("instanceof",{beforeExpr:!0,binop:7}),_typeof:y("typeof",{beforeExpr:!0,prefix:!0,startsExpr:!0}),_void:y("void",{beforeExpr:!0,prefix:!0,startsExpr:!0}),_delete:y("delete",{beforeExpr:!0,prefix:!0,startsExpr:!0})},v=/\r\n?|\n|\u2028|\u2029/,E=new RegExp(v.source,"g");function k(e){return 10===e||13===e||8232===e||8233===e}var C=/[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/,T=/(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g,O=Object.prototype,S=O.hasOwnProperty,M=O.toString;function P(e,t){return S.call(e,t)}var A=Array.isArray||function(e){return"[object Array]"===M.call(e)},w=function(e,t){this.line=e,this.column=t};w.prototype.offset=function(e){return new w(this.line,this.column+e)};var x=function(e,t,n){this.start=t,this.end=n,null!==e.sourceFile&&(this.source=e.sourceFile)};function R(e,t){for(var n=1,a=0;;){E.lastIndex=a;var i=E.exec(e);if(!(i&&i.index=2015&&(t.ecmaVersion-=2009),null==t.allowReserved&&(t.allowReserved=t.ecmaVersion<5),A(t.onToken)){var a=t.onToken;t.onToken=function(e){return a.push(e)}}return A(t.onComment)&&(t.onComment=function(e,t){return function(n,a,i,r,o,s){var l={type:n?"Block":"Line",value:a,start:i,end:r};e.locations&&(l.loc=new x(this,o,s)),e.ranges&&(l.range=[i,r]),t.push(l)}}(t,t.onComment)),t}var L={};function D(e){return new RegExp("^("+e.replace(/ /g,"|")+")$")}var B=function(e,n,i){this.options=e=I(e),this.sourceFile=e.sourceFile,this.keywords=D(a[e.ecmaVersion>=6?6:5]);var r="";if(!e.allowReserved){for(var o=e.ecmaVersion;!(r=t[o]);o--);"module"==e.sourceType&&(r+=" await")}this.reservedWords=D(r);var s=(r?r+" ":"")+t.strict;this.reservedWordsStrict=D(s),this.reservedWordsStrictBind=D(s+" "+t.strictBind),this.input=String(n),this.containsEsc=!1,this.loadPlugins(e.plugins),i?(this.pos=i,this.lineStart=this.input.lastIndexOf("\n",i-1)+1,this.curLine=this.input.slice(0,this.lineStart).split(v).length):(this.pos=this.lineStart=0,this.curLine=1),this.type=b.eof,this.value=null,this.start=this.end=this.pos,this.startLoc=this.endLoc=this.curPosition(),this.lastTokEndLoc=this.lastTokStartLoc=null,this.lastTokStart=this.lastTokEnd=this.pos,this.context=this.initialContext(),this.exprAllowed=!0,this.inModule="module"===e.sourceType,this.strict=this.inModule||this.strictDirective(this.pos),this.potentialArrowAt=-1,this.inFunction=this.inGenerator=this.inAsync=!1,this.yieldPos=this.awaitPos=0,this.labels=[],0===this.pos&&e.allowHashBang&&"#!"===this.input.slice(0,2)&&this.skipLineComment(2),this.scopeStack=[],this.enterFunctionScope()};B.prototype.isKeyword=function(e){return this.keywords.test(e)},B.prototype.isReservedWord=function(e){return this.reservedWords.test(e)},B.prototype.extend=function(e,t){this[e]=t(this[e])},B.prototype.loadPlugins=function(e){for(var t in e){var n=L[t];if(!n)throw new Error("Plugin '"+t+"' not found");n(this,e[t])}},B.prototype.parse=function(){var e=this.options.program||this.startNode();return this.nextToken(),this.parseTopLevel(e)};var W=B.prototype,j=/^(?:'((?:[^']|\.)*)'|"((?:[^"]|\.)*)"|;)/;W.strictDirective=function(e){for(;;){T.lastIndex=e,e+=T.exec(this.input)[0].length;var t=j.exec(this.input.slice(e));if(!t)return!1;if("use strict"==(t[1]||t[2]))return!0;e+=t[0].length}},W.eat=function(e){return this.type===e&&(this.next(),!0)},W.isContextual=function(e){return this.type===b.name&&this.value===e},W.eatContextual=function(e){return this.value===e&&this.eat(b.name)},W.expectContextual=function(e){this.eatContextual(e)||this.unexpected()},W.canInsertSemicolon=function(){return this.type===b.eof||this.type===b.braceR||v.test(this.input.slice(this.lastTokEnd,this.start))},W.insertSemicolon=function(){if(this.canInsertSemicolon())return this.options.onInsertedSemicolon&&this.options.onInsertedSemicolon(this.lastTokEnd,this.lastTokEndLoc),!0},W.semicolon=function(){this.eat(b.semi)||this.insertSemicolon()||this.unexpected()},W.afterTrailingComma=function(e,t){if(this.type==e)return this.options.onTrailingComma&&this.options.onTrailingComma(this.lastTokStart,this.lastTokStartLoc),t||this.next(),!0},W.expect=function(e){this.eat(e)||this.unexpected()},W.unexpected=function(e){this.raise(null!=e?e:this.start,"Unexpected token")};var F=function(){this.shorthandAssign=this.trailingComma=this.parenthesizedAssign=this.parenthesizedBind=-1};W.checkPatternErrors=function(e,t){if(e){e.trailingComma>-1&&this.raiseRecoverable(e.trailingComma,"Comma is not permitted after the rest element");var n=t?e.parenthesizedAssign:e.parenthesizedBind;n>-1&&this.raiseRecoverable(n,"Parenthesized pattern")}},W.checkExpressionErrors=function(e,t){var n=e?e.shorthandAssign:-1;if(!t)return n>=0;n>-1&&this.raise(n,"Shorthand property assignments are valid only in destructuring patterns")},W.checkYieldAwaitInDefaultParams=function(){this.yieldPos&&(!this.awaitPos||this.yieldPos=6&&(e.sourceType=this.options.sourceType),this.finishNode(e,"Program")};var H={kind:"loop"},G={kind:"switch"};U.isLet=function(){if(this.type!==b.name||this.options.ecmaVersion<6||"let"!=this.value)return!1;T.lastIndex=this.pos;var e=T.exec(this.input),t=this.pos+e[0].length,n=this.input.charCodeAt(t);if(91===n||123==n)return!0;if(p(n,!0)){for(var a=t+1;m(this.input.charCodeAt(a),!0);)++a;var i=this.input.slice(t,a);if(!this.isKeyword(i))return!0}return!1},U.isAsyncFunction=function(){if(this.type!==b.name||this.options.ecmaVersion<8||"async"!=this.value)return!1;T.lastIndex=this.pos;var e=T.exec(this.input),t=this.pos+e[0].length;return!(v.test(this.input.slice(this.pos,t))||"function"!==this.input.slice(t,t+8)||t+8!=this.input.length&&m(this.input.charAt(t+8)))},U.parseStatement=function(e,t,n){var a,i=this.type,r=this.startNode();switch(this.isLet()&&(i=b._var,a="let"),i){case b._break:case b._continue:return this.parseBreakContinueStatement(r,i.keyword);case b._debugger:return this.parseDebuggerStatement(r);case b._do:return this.parseDoStatement(r);case b._for:return this.parseForStatement(r);case b._function:return!e&&this.options.ecmaVersion>=6&&this.unexpected(),this.parseFunctionStatement(r,!1);case b._class:return e||this.unexpected(),this.parseClass(r,!0);case b._if:return this.parseIfStatement(r);case b._return:return this.parseReturnStatement(r);case b._switch:return this.parseSwitchStatement(r);case b._throw:return this.parseThrowStatement(r);case b._try:return this.parseTryStatement(r);case b._const:case b._var:return a=a||this.value,e||"var"==a||this.unexpected(),this.parseVarStatement(r,a);case b._while:return this.parseWhileStatement(r);case b._with:return this.parseWithStatement(r);case b.braceL:return this.parseBlock();case b.semi:return this.parseEmptyStatement(r);case b._export:case b._import:return this.options.allowImportExportEverywhere||(t||this.raise(this.start,"'import' and 'export' may only appear at the top level"),this.inModule||this.raise(this.start,"'import' and 'export' may appear only with 'sourceType: module'")),i===b._import?this.parseImport(r):this.parseExport(r,n);default:if(this.isAsyncFunction()&&e)return this.next(),this.parseFunctionStatement(r,!0);var o=this.value,s=this.parseExpression();return i===b.name&&"Identifier"===s.type&&this.eat(b.colon)?this.parseLabeledStatement(r,o,s):this.parseExpressionStatement(r,s)}},U.parseBreakContinueStatement=function(e,t){var n="break"==t;this.next(),this.eat(b.semi)||this.insertSemicolon()?e.label=null:this.type!==b.name?this.unexpected():(e.label=this.parseIdent(),this.semicolon());for(var a=0;a=6?this.eat(b.semi):this.semicolon(),this.finishNode(e,"DoWhileStatement")},U.parseForStatement=function(e){if(this.next(),this.labels.push(H),this.enterLexicalScope(),this.expect(b.parenL),this.type===b.semi)return this.parseFor(e,null);var t=this.isLet();if(this.type===b._var||this.type===b._const||t){var n=this.startNode(),a=t?"let":this.value;return this.next(),this.parseVar(n,!0,a),this.finishNode(n,"VariableDeclaration"),!(this.type===b._in||this.options.ecmaVersion>=6&&this.isContextual("of"))||1!==n.declarations.length||"var"!==a&&n.declarations[0].init?this.parseFor(e,n):this.parseForIn(e,n)}var i=new F,r=this.parseExpression(!0,i);return this.type===b._in||this.options.ecmaVersion>=6&&this.isContextual("of")?(this.toAssignable(r),this.checkLVal(r),this.checkPatternErrors(i,!0),this.parseForIn(e,r)):(this.checkExpressionErrors(i,!0),this.parseFor(e,r))},U.parseFunctionStatement=function(e,t){return this.next(),this.parseFunction(e,!0,!1,t)},U.isFunction=function(){return this.type===b._function||this.isAsyncFunction()},U.parseIfStatement=function(e){return this.next(),e.test=this.parseParenExpression(),e.consequent=this.parseStatement(!this.strict&&this.isFunction()),e.alternate=this.eat(b._else)?this.parseStatement(!this.strict&&this.isFunction()):null,this.finishNode(e,"IfStatement")},U.parseReturnStatement=function(e){return this.inFunction||this.options.allowReturnOutsideFunction||this.raise(this.start,"'return' outside of function"),this.next(),this.eat(b.semi)||this.insertSemicolon()?e.argument=null:(e.argument=this.parseExpression(),this.semicolon()),this.finishNode(e,"ReturnStatement")},U.parseSwitchStatement=function(e){var t;this.next(),e.discriminant=this.parseParenExpression(),e.cases=[],this.expect(b.braceL),this.labels.push(G),this.enterLexicalScope();for(var n=!1;this.type!=b.braceR;)if(this.type===b._case||this.type===b._default){var a=this.type===b._case;t&&this.finishNode(t,"SwitchCase"),e.cases.push(t=this.startNode()),t.consequent=[],this.next(),a?t.test=this.parseExpression():(n&&this.raiseRecoverable(this.lastTokStart,"Multiple default clauses"),n=!0,t.test=null),this.expect(b.colon)}else t||this.unexpected(),t.consequent.push(this.parseStatement(!0));return this.exitLexicalScope(),t&&this.finishNode(t,"SwitchCase"),this.next(),this.labels.pop(),this.finishNode(e,"SwitchStatement")},U.parseThrowStatement=function(e){return this.next(),v.test(this.input.slice(this.lastTokEnd,this.start))&&this.raise(this.lastTokEnd,"Illegal newline after throw"),e.argument=this.parseExpression(),this.semicolon(),this.finishNode(e,"ThrowStatement")};var K=[];U.parseTryStatement=function(e){if(this.next(),e.block=this.parseBlock(),e.handler=null,this.type===b._catch){var t=this.startNode();this.next(),this.expect(b.parenL),t.param=this.parseBindingAtom(),this.enterLexicalScope(),this.checkLVal(t.param,"let"),this.expect(b.parenR),t.body=this.parseBlock(!1),this.exitLexicalScope(),e.handler=this.finishNode(t,"CatchClause")}return e.finalizer=this.eat(b._finally)?this.parseBlock():null,e.handler||e.finalizer||this.raise(e.start,"Missing catch or finally clause"),this.finishNode(e,"TryStatement")},U.parseVarStatement=function(e,t){return this.next(),this.parseVar(e,!1,t),this.semicolon(),this.finishNode(e,"VariableDeclaration")},U.parseWhileStatement=function(e){return this.next(),e.test=this.parseParenExpression(),this.labels.push(H),e.body=this.parseStatement(!1),this.labels.pop(),this.finishNode(e,"WhileStatement")},U.parseWithStatement=function(e){return this.strict&&this.raise(this.start,"'with' in strict mode"),this.next(),e.object=this.parseParenExpression(),e.body=this.parseStatement(!1),this.finishNode(e,"WithStatement")},U.parseEmptyStatement=function(e){return this.next(),this.finishNode(e,"EmptyStatement")},U.parseLabeledStatement=function(e,t,n){for(var a=0;a=0;r--){var o=this.labels[r];if(o.statementStart!=e.start)break;o.statementStart=this.start,o.kind=i}return this.labels.push({name:t,kind:i,statementStart:this.start}),e.body=this.parseStatement(!0),("ClassDeclaration"==e.body.type||"VariableDeclaration"==e.body.type&&"var"!=e.body.kind||"FunctionDeclaration"==e.body.type&&(this.strict||e.body.generator))&&this.raiseRecoverable(e.body.start,"Invalid labeled declaration"),this.labels.pop(),e.label=n,this.finishNode(e,"LabeledStatement")},U.parseExpressionStatement=function(e,t){return e.expression=t,this.semicolon(),this.finishNode(e,"ExpressionStatement")},U.parseBlock=function(e){void 0===e&&(e=!0);var t=this.startNode();for(t.body=[],this.expect(b.braceL),e&&this.enterLexicalScope();!this.eat(b.braceR);){var n=this.parseStatement(!0);t.body.push(n)}return e&&this.exitLexicalScope(),this.finishNode(t,"BlockStatement")},U.parseFor=function(e,t){return e.init=t,this.expect(b.semi),e.test=this.type===b.semi?null:this.parseExpression(),this.expect(b.semi),e.update=this.type===b.parenR?null:this.parseExpression(),this.expect(b.parenR),this.exitLexicalScope(),e.body=this.parseStatement(!1),this.labels.pop(),this.finishNode(e,"ForStatement")},U.parseForIn=function(e,t){var n=this.type===b._in?"ForInStatement":"ForOfStatement";return this.next(),e.left=t,e.right=this.parseExpression(),this.expect(b.parenR),this.exitLexicalScope(),e.body=this.parseStatement(!1),this.labels.pop(),this.finishNode(e,n)},U.parseVar=function(e,t,n){for(e.declarations=[],e.kind=n;;){var a=this.startNode();if(this.parseVarId(a,n),this.eat(b.eq)?a.init=this.parseMaybeAssign(t):"const"!==n||this.type===b._in||this.options.ecmaVersion>=6&&this.isContextual("of")?"Identifier"==a.id.type||t&&(this.type===b._in||this.isContextual("of"))?a.init=null:this.raise(this.lastTokEnd,"Complex binding patterns require an initialization value"):this.unexpected(),e.declarations.push(this.finishNode(a,"VariableDeclarator")),!this.eat(b.comma))break}return e},U.parseVarId=function(e,t){e.id=this.parseBindingAtom(t),this.checkLVal(e.id,t,!1)},U.parseFunction=function(e,t,n,a){this.initFunction(e),this.options.ecmaVersion>=6&&!a&&(e.generator=this.eat(b.star)),this.options.ecmaVersion>=8&&(e.async=!!a),t&&(e.id="nullableID"===t&&this.type!=b.name?null:this.parseIdent(),e.id&&this.checkLVal(e.id,"var"));var i=this.inGenerator,r=this.inAsync,o=this.yieldPos,s=this.awaitPos,l=this.inFunction;return this.inGenerator=e.generator,this.inAsync=e.async,this.yieldPos=0,this.awaitPos=0,this.inFunction=!0,this.enterFunctionScope(),t||(e.id=this.type==b.name?this.parseIdent():null),this.parseFunctionParams(e),this.parseFunctionBody(e,n),this.inGenerator=i,this.inAsync=r,this.yieldPos=o,this.awaitPos=s,this.inFunction=l,this.finishNode(e,t?"FunctionDeclaration":"FunctionExpression")},U.parseFunctionParams=function(e){this.expect(b.parenL),e.params=this.parseBindingList(b.parenR,!1,this.options.ecmaVersion>=8,!0),this.checkYieldAwaitInDefaultParams()},U.parseClass=function(e,t){this.next(),this.parseClassId(e,t),this.parseClassSuper(e);var n=this.startNode(),a=!1;for(n.body=[],this.expect(b.braceL);!this.eat(b.braceR);)if(!this.eat(b.semi)){var i=this.startNode(),r=this.eat(b.star),o=!1,s=this.type===b.name&&"static"===this.value;this.parsePropertyName(i),i.static=s&&this.type!==b.parenL,i.static&&(r&&this.unexpected(),r=this.eat(b.star),this.parsePropertyName(i)),this.options.ecmaVersion>=8&&!r&&!i.computed&&"Identifier"===i.key.type&&"async"===i.key.name&&this.type!==b.parenL&&!this.canInsertSemicolon()&&(o=!0,this.parsePropertyName(i)),i.kind="method";var l=!1;if(!i.computed){var c=i.key;r||o||"Identifier"!==c.type||this.type===b.parenL||"get"!==c.name&&"set"!==c.name||(l=!0,i.kind=c.name,c=this.parsePropertyName(i)),!i.static&&("Identifier"===c.type&&"constructor"===c.name||"Literal"===c.type&&"constructor"===c.value)&&(a&&this.raise(c.start,"Duplicate constructor in the same class"),l&&this.raise(c.start,"Constructor can't have get/set modifier"),r&&this.raise(c.start,"Constructor can't be a generator"),o&&this.raise(c.start,"Constructor can't be an async method"),i.kind="constructor",a=!0)}if(this.parseClassMethod(n,i,r,o),l){var u="get"===i.kind?0:1;if(i.value.params.length!==u){var p=i.value.start;"get"===i.kind?this.raiseRecoverable(p,"getter should have no params"):this.raiseRecoverable(p,"setter should have exactly one param")}else"set"===i.kind&&"RestElement"===i.value.params[0].type&&this.raiseRecoverable(i.value.params[0].start,"Setter cannot use rest params")}}return e.body=this.finishNode(n,"ClassBody"),this.finishNode(e,t?"ClassDeclaration":"ClassExpression")},U.parseClassMethod=function(e,t,n,a){t.value=this.parseMethod(n,a),e.body.push(this.finishNode(t,"MethodDefinition"))},U.parseClassId=function(e,t){e.id=this.type===b.name?this.parseIdent():!0===t?this.unexpected():null},U.parseClassSuper=function(e){e.superClass=this.eat(b._extends)?this.parseExprSubscripts():null},U.parseExport=function(e,t){if(this.next(),this.eat(b.star))return this.expectContextual("from"),e.source=this.type===b.string?this.parseExprAtom():this.unexpected(),this.semicolon(),this.finishNode(e,"ExportAllDeclaration");if(this.eat(b._default)){var n;if(this.checkExport(t,"default",this.lastTokStart),this.type===b._function||(n=this.isAsyncFunction())){var a=this.startNode();this.next(),n&&this.next(),e.declaration=this.parseFunction(a,"nullableID",!1,n)}else if(this.type===b._class){var i=this.startNode();e.declaration=this.parseClass(i,"nullableID")}else e.declaration=this.parseMaybeAssign(),this.semicolon();return this.finishNode(e,"ExportDefaultDeclaration")}if(this.shouldParseExportStatement())e.declaration=this.parseStatement(!0),"VariableDeclaration"===e.declaration.type?this.checkVariableExport(t,e.declaration.declarations):this.checkExport(t,e.declaration.id.name,e.declaration.id.start),e.specifiers=[],e.source=null;else{if(e.declaration=null,e.specifiers=this.parseExportSpecifiers(t),this.eatContextual("from"))e.source=this.type===b.string?this.parseExprAtom():this.unexpected();else{for(var r=0;r=6&&e)switch(e.type){case"Identifier":this.inAsync&&"await"===e.name&&this.raise(e.start,"Can not use 'await' as identifier inside an async function");break;case"ObjectPattern":case"ArrayPattern":break;case"ObjectExpression":e.type="ObjectPattern";for(var n=0;n=6&&(e.computed||e.method||e.shorthand))){var n,a=e.key;switch(a.type){case"Identifier":n=a.name;break;case"Literal":n=String(a.value);break;default:return}var i=e.kind;if(this.options.ecmaVersion>=6)"__proto__"===n&&"init"===i&&(t.proto&&this.raiseRecoverable(a.start,"Redefinition of __proto__ property"),t.proto=!0);else{var r=t[n="$"+n];r?("init"===i?this.strict&&r.init||r.get||r.set:r.init||r[i])&&this.raiseRecoverable(a.start,"Redefinition of property"):r=t[n]={init:!1,get:!1,set:!1},r[i]=!0}}},$.parseExpression=function(e,t){var n=this.start,a=this.startLoc,i=this.parseMaybeAssign(e,t);if(this.type===b.comma){var r=this.startNodeAt(n,a);for(r.expressions=[i];this.eat(b.comma);)r.expressions.push(this.parseMaybeAssign(e,t));return this.finishNode(r,"SequenceExpression")}return i},$.parseMaybeAssign=function(e,t,n){if(this.inGenerator&&this.isContextual("yield"))return this.parseYield();var a=!1,i=-1,r=-1;t?(i=t.parenthesizedAssign,r=t.trailingComma,t.parenthesizedAssign=t.trailingComma=-1):(t=new F,a=!0);var o=this.start,s=this.startLoc;this.type!=b.parenL&&this.type!=b.name||(this.potentialArrowAt=this.start);var l=this.parseMaybeConditional(e,t);if(n&&(l=n.call(this,l,o,s)),this.type.isAssign){this.checkPatternErrors(t,!0),a||F.call(t);var c=this.startNodeAt(o,s);return c.operator=this.value,c.left=this.type===b.eq?this.toAssignable(l):l,t.shorthandAssign=-1,this.checkLVal(l),this.next(),c.right=this.parseMaybeAssign(e),this.finishNode(c,"AssignmentExpression")}return a&&this.checkExpressionErrors(t,!0),i>-1&&(t.parenthesizedAssign=i),r>-1&&(t.trailingComma=r),l},$.parseMaybeConditional=function(e,t){var n=this.start,a=this.startLoc,i=this.parseExprOps(e,t);if(this.checkExpressionErrors(t))return i;if(this.eat(b.question)){var r=this.startNodeAt(n,a);return r.test=i,r.consequent=this.parseMaybeAssign(),this.expect(b.colon),r.alternate=this.parseMaybeAssign(e),this.finishNode(r,"ConditionalExpression")}return i},$.parseExprOps=function(e,t){var n=this.start,a=this.startLoc,i=this.parseMaybeUnary(t,!1);return this.checkExpressionErrors(t)?i:i.start==n&&"ArrowFunctionExpression"===i.type?i:this.parseExprOp(i,n,a,-1,e)},$.parseExprOp=function(e,t,n,a,i){var r=this.type.binop;if(null!=r&&(!i||this.type!==b._in)&&r>a){var o=this.type===b.logicalOR||this.type===b.logicalAND,s=this.value;this.next();var l=this.start,c=this.startLoc,u=this.parseExprOp(this.parseMaybeUnary(null,!1),l,c,r,i),p=this.buildBinary(t,n,e,u,s,o);return this.parseExprOp(p,t,n,a,i)}return e},$.buildBinary=function(e,t,n,a,i,r){var o=this.startNodeAt(e,t);return o.left=n,o.operator=i,o.right=a,this.finishNode(o,r?"LogicalExpression":"BinaryExpression")},$.parseMaybeUnary=function(e,t){var n,a=this.start,i=this.startLoc;if(this.inAsync&&this.isContextual("await"))n=this.parseAwait(e),t=!0;else if(this.type.prefix){var r=this.startNode(),o=this.type===b.incDec;r.operator=this.value,r.prefix=!0,this.next(),r.argument=this.parseMaybeUnary(null,!0),this.checkExpressionErrors(e,!0),o?this.checkLVal(r.argument):this.strict&&"delete"===r.operator&&"Identifier"===r.argument.type?this.raiseRecoverable(r.start,"Deleting local variable in strict mode"):t=!0,n=this.finishNode(r,o?"UpdateExpression":"UnaryExpression")}else{if(n=this.parseExprSubscripts(e),this.checkExpressionErrors(e))return n;for(;this.type.postfix&&!this.canInsertSemicolon();){var s=this.startNodeAt(a,i);s.operator=this.value,s.prefix=!1,s.argument=n,this.checkLVal(n),this.next(),n=this.finishNode(s,"UpdateExpression")}}return!t&&this.eat(b.starstar)?this.buildBinary(a,i,n,this.parseMaybeUnary(null,!1),"**",!1):n},$.parseExprSubscripts=function(e){var t=this.start,n=this.startLoc,a=this.parseExprAtom(e),i="ArrowFunctionExpression"===a.type&&")"!==this.input.slice(this.lastTokStart,this.lastTokEnd);if(this.checkExpressionErrors(e)||i)return a;var r=this.parseSubscripts(a,t,n);return e&&"MemberExpression"===r.type&&(e.parenthesizedAssign>=r.start&&(e.parenthesizedAssign=-1),e.parenthesizedBind>=r.start&&(e.parenthesizedBind=-1)),r},$.parseSubscripts=function(e,t,n,a){for(var i,r=this.options.ecmaVersion>=8&&"Identifier"===e.type&&"async"===e.name&&this.lastTokEnd==e.end&&!this.canInsertSemicolon();;)if((i=this.eat(b.bracketL))||this.eat(b.dot)){var o=this.startNodeAt(t,n);o.object=e,o.property=i?this.parseExpression():this.parseIdent(!0),o.computed=!!i,i&&this.expect(b.bracketR),e=this.finishNode(o,"MemberExpression")}else if(!a&&this.eat(b.parenL)){var s=new F,l=this.yieldPos,c=this.awaitPos;this.yieldPos=0,this.awaitPos=0;var u=this.parseExprList(b.parenR,this.options.ecmaVersion>=8,!1,s);if(r&&!this.canInsertSemicolon()&&this.eat(b.arrow))return this.checkPatternErrors(s,!1),this.checkYieldAwaitInDefaultParams(),this.yieldPos=l,this.awaitPos=c,this.parseArrowExpression(this.startNodeAt(t,n),u,!0);this.checkExpressionErrors(s,!0),this.yieldPos=l||this.yieldPos,this.awaitPos=c||this.awaitPos;var p=this.startNodeAt(t,n);p.callee=e,p.arguments=u,e=this.finishNode(p,"CallExpression")}else{if(this.type!==b.backQuote)return e;var m=this.startNodeAt(t,n);m.tag=e,m.quasi=this.parseTemplate(),e=this.finishNode(m,"TaggedTemplateExpression")}},$.parseExprAtom=function(e){var t,n=this.potentialArrowAt==this.start;switch(this.type){case b._super:this.inFunction||this.raise(this.start,"'super' outside of function or class");case b._this:var a=this.type===b._this?"ThisExpression":"Super";return t=this.startNode(),this.next(),this.finishNode(t,a);case b.name:var i=this.start,r=this.startLoc,o=this.parseIdent(this.type!==b.name);if(this.options.ecmaVersion>=8&&"async"===o.name&&!this.canInsertSemicolon()&&this.eat(b._function))return this.parseFunction(this.startNodeAt(i,r),!1,!1,!0);if(n&&!this.canInsertSemicolon()){if(this.eat(b.arrow))return this.parseArrowExpression(this.startNodeAt(i,r),[o],!1);if(this.options.ecmaVersion>=8&&"async"===o.name&&this.type===b.name)return o=this.parseIdent(),!this.canInsertSemicolon()&&this.eat(b.arrow)||this.unexpected(),this.parseArrowExpression(this.startNodeAt(i,r),[o],!0)}return o;case b.regexp:var s=this.value;return(t=this.parseLiteral(s.value)).regex={pattern:s.pattern,flags:s.flags},t;case b.num:case b.string:return this.parseLiteral(this.value);case b._null:case b._true:case b._false:return(t=this.startNode()).value=this.type===b._null?null:this.type===b._true,t.raw=this.type.keyword,this.next(),this.finishNode(t,"Literal");case b.parenL:var l=this.start,c=this.parseParenAndDistinguishExpression(n);return e&&(e.parenthesizedAssign<0&&!this.isSimpleAssignTarget(c)&&(e.parenthesizedAssign=l),e.parenthesizedBind<0&&(e.parenthesizedBind=l)),c;case b.bracketL:return t=this.startNode(),this.next(),t.elements=this.parseExprList(b.bracketR,!0,!0,e),this.finishNode(t,"ArrayExpression");case b.braceL:return this.parseObj(!1,e);case b._function:return t=this.startNode(),this.next(),this.parseFunction(t,!1);case b._class:return this.parseClass(this.startNode(),!1);case b._new:return this.parseNew();case b.backQuote:return this.parseTemplate();default:this.unexpected()}},$.parseLiteral=function(e){var t=this.startNode();return t.value=e,t.raw=this.input.slice(this.start,this.end),this.next(),this.finishNode(t,"Literal")},$.parseParenExpression=function(){this.expect(b.parenL);var e=this.parseExpression();return this.expect(b.parenR),e},$.parseParenAndDistinguishExpression=function(e){var t,n=this.start,a=this.startLoc,i=this.options.ecmaVersion>=8;if(this.options.ecmaVersion>=6){this.next();var r,o,s=this.start,l=this.startLoc,c=[],u=!0,p=!1,m=new F,h=this.yieldPos,d=this.awaitPos;for(this.yieldPos=0,this.awaitPos=0;this.type!==b.parenR;){if(u?u=!1:this.expect(b.comma),i&&this.afterTrailingComma(b.parenR,!0)){p=!0;break}if(this.type===b.ellipsis){r=this.start,c.push(this.parseParenItem(this.parseRest())),this.type===b.comma&&this.raise(this.start,"Comma is not permitted after the rest element");break}this.type!==b.parenL||o||(o=this.start),c.push(this.parseMaybeAssign(!1,m,this.parseParenItem))}var g=this.start,_=this.startLoc;if(this.expect(b.parenR),e&&!this.canInsertSemicolon()&&this.eat(b.arrow))return this.checkPatternErrors(m,!1),this.checkYieldAwaitInDefaultParams(),o&&this.unexpected(o),this.yieldPos=h,this.awaitPos=d,this.parseParenArrowList(n,a,c);c.length&&!p||this.unexpected(this.lastTokStart),r&&this.unexpected(r),this.checkExpressionErrors(m,!0),this.yieldPos=h||this.yieldPos,this.awaitPos=d||this.awaitPos,c.length>1?((t=this.startNodeAt(s,l)).expressions=c,this.finishNodeAt(t,"SequenceExpression",g,_)):t=c[0]}else t=this.parseParenExpression();if(this.options.preserveParens){var f=this.startNodeAt(n,a);return f.expression=t,this.finishNode(f,"ParenthesizedExpression")}return t},$.parseParenItem=function(e){return e},$.parseParenArrowList=function(e,t,n){return this.parseArrowExpression(this.startNodeAt(e,t),n)};var Y=[];$.parseNew=function(){var e=this.startNode(),t=this.parseIdent(!0);if(this.options.ecmaVersion>=6&&this.eat(b.dot))return e.meta=t,e.property=this.parseIdent(!0),"target"!==e.property.name&&this.raiseRecoverable(e.property.start,"The only valid meta property for new is new.target"),this.inFunction||this.raiseRecoverable(e.start,"new.target can only be used in functions"),this.finishNode(e,"MetaProperty");var n=this.start,a=this.startLoc;return e.callee=this.parseSubscripts(this.parseExprAtom(),n,a,!0),this.eat(b.parenL)?e.arguments=this.parseExprList(b.parenR,this.options.ecmaVersion>=8,!1):e.arguments=Y,this.finishNode(e,"NewExpression")},$.parseTemplateElement=function(){var e=this.startNode();return e.value={raw:this.input.slice(this.start,this.end).replace(/\r\n?/g,"\n"),cooked:this.value},this.next(),e.tail=this.type===b.backQuote,this.finishNode(e,"TemplateElement")},$.parseTemplate=function(){var e=this.startNode();this.next(),e.expressions=[];var t=this.parseTemplateElement();for(e.quasis=[t];!t.tail;)this.expect(b.dollarBraceL),e.expressions.push(this.parseExpression()),this.expect(b.braceR),e.quasis.push(t=this.parseTemplateElement());return this.next(),this.finishNode(e,"TemplateLiteral")},$.parseObj=function(e,t){var n=this.startNode(),a=!0,i={};for(n.properties=[],this.next();!this.eat(b.braceR);){if(a)a=!1;else if(this.expect(b.comma),this.afterTrailingComma(b.braceR))break;var r,o,s,l,c=this.startNode();this.options.ecmaVersion>=6&&(c.method=!1,c.shorthand=!1,(e||t)&&(s=this.start,l=this.startLoc),e||(r=this.eat(b.star))),this.parsePropertyName(c),e||!(this.options.ecmaVersion>=8)||r||c.computed||"Identifier"!==c.key.type||"async"!==c.key.name||this.type===b.parenL||this.type===b.colon||this.canInsertSemicolon()?o=!1:(o=!0,this.parsePropertyName(c,t)),this.parsePropertyValue(c,e,r,o,s,l,t),this.checkPropClash(c,i),n.properties.push(this.finishNode(c,"Property"))}return this.finishNode(n,e?"ObjectPattern":"ObjectExpression")},$.parsePropertyValue=function(e,t,n,a,i,r,o){if((n||a)&&this.type===b.colon&&this.unexpected(),this.eat(b.colon))e.value=t?this.parseMaybeDefault(this.start,this.startLoc):this.parseMaybeAssign(!1,o),e.kind="init";else if(this.options.ecmaVersion>=6&&this.type===b.parenL)t&&this.unexpected(),e.kind="init",e.method=!0,e.value=this.parseMethod(n,a);else if(this.options.ecmaVersion>=5&&!e.computed&&"Identifier"===e.key.type&&("get"===e.key.name||"set"===e.key.name)&&this.type!=b.comma&&this.type!=b.braceR){(n||a||t)&&this.unexpected(),e.kind=e.key.name,this.parsePropertyName(e),e.value=this.parseMethod(!1);var s="get"===e.kind?0:1;if(e.value.params.length!==s){var l=e.value.start;"get"===e.kind?this.raiseRecoverable(l,"getter should have no params"):this.raiseRecoverable(l,"setter should have exactly one param")}else"set"===e.kind&&"RestElement"===e.value.params[0].type&&this.raiseRecoverable(e.value.params[0].start,"Setter cannot use rest params")}else this.options.ecmaVersion>=6&&!e.computed&&"Identifier"===e.key.type?((this.keywords.test(e.key.name)||(this.strict?this.reservedWordsStrict:this.reservedWords).test(e.key.name)||this.inGenerator&&"yield"==e.key.name||this.inAsync&&"await"==e.key.name)&&this.raiseRecoverable(e.key.start,"'"+e.key.name+"' can not be used as shorthand property"),e.kind="init",t?e.value=this.parseMaybeDefault(i,r,e.key):this.type===b.eq&&o?(o.shorthandAssign<0&&(o.shorthandAssign=this.start),e.value=this.parseMaybeDefault(i,r,e.key)):e.value=e.key,e.shorthand=!0):this.unexpected()},$.parsePropertyName=function(e){if(this.options.ecmaVersion>=6){if(this.eat(b.bracketL))return e.computed=!0,e.key=this.parseMaybeAssign(),this.expect(b.bracketR),e.key;e.computed=!1}return e.key=this.type===b.num||this.type===b.string?this.parseExprAtom():this.parseIdent(!0)},$.initFunction=function(e){e.id=null,this.options.ecmaVersion>=6&&(e.generator=!1,e.expression=!1),this.options.ecmaVersion>=8&&(e.async=!1)},$.parseMethod=function(e,t){var n=this.startNode(),a=this.inGenerator,i=this.inAsync,r=this.yieldPos,o=this.awaitPos,s=this.inFunction;return this.initFunction(n),this.options.ecmaVersion>=6&&(n.generator=e),this.options.ecmaVersion>=8&&(n.async=!!t),this.inGenerator=n.generator,this.inAsync=n.async,this.yieldPos=0,this.awaitPos=0,this.inFunction=!0,this.enterFunctionScope(),this.expect(b.parenL),n.params=this.parseBindingList(b.parenR,!1,this.options.ecmaVersion>=8),this.checkYieldAwaitInDefaultParams(),this.parseFunctionBody(n,!1),this.inGenerator=a,this.inAsync=i,this.yieldPos=r,this.awaitPos=o,this.inFunction=s,this.finishNode(n,"FunctionExpression")},$.parseArrowExpression=function(e,t,n){var a=this.inGenerator,i=this.inAsync,r=this.yieldPos,o=this.awaitPos,s=this.inFunction;return this.enterFunctionScope(),this.initFunction(e),this.options.ecmaVersion>=8&&(e.async=!!n),this.inGenerator=!1,this.inAsync=e.async,this.yieldPos=0,this.awaitPos=0,this.inFunction=!0,e.params=this.toAssignableList(t,!0),this.parseFunctionBody(e,!0),this.inGenerator=a,this.inAsync=i,this.yieldPos=r,this.awaitPos=o,this.inFunction=s,this.finishNode(e,"ArrowFunctionExpression")},$.parseFunctionBody=function(e,t){var n=t&&this.type!==b.braceL,a=this.strict,i=!1;if(n)e.body=this.parseMaybeAssign(),e.expression=!0,this.checkParams(e,!1);else{var r=this.options.ecmaVersion>=7&&!this.isSimpleParamList(e.params);a&&!r||(i=this.strictDirective(this.end))&&r&&this.raiseRecoverable(e.start,"Illegal 'use strict' directive in function with non-simple parameter list");var o=this.labels;this.labels=[],i&&(this.strict=!0),this.checkParams(e,!a&&!i&&!t&&this.isSimpleParamList(e.params)),e.body=this.parseBlock(!1),e.expression=!1,this.labels=o}this.exitFunctionScope(),this.strict&&e.id&&this.checkLVal(e.id,"none"),this.strict=a},$.isSimpleParamList=function(e){for(var t=0;t=6||-1==this.input.slice(this.start,this.end).indexOf("\\"))&&this.raiseRecoverable(this.start,"The keyword '"+this.value+"' is reserved"),this.inGenerator&&"yield"===this.value&&this.raiseRecoverable(this.start,"Can not use 'yield' as identifier inside a generator"),this.inAsync&&"await"===this.value&&this.raiseRecoverable(this.start,"Can not use 'await' as identifier inside an async function"),t.name=this.value):e&&this.type.keyword?t.name=this.type.keyword:this.unexpected(),this.next(),this.finishNode(t,"Identifier")},$.parseYield=function(){this.yieldPos||(this.yieldPos=this.start);var e=this.startNode();return this.next(),this.type==b.semi||this.canInsertSemicolon()||this.type!=b.star&&!this.type.startsExpr?(e.delegate=!1,e.argument=null):(e.delegate=this.eat(b.star),e.argument=this.parseMaybeAssign()),this.finishNode(e,"YieldExpression")},$.parseAwait=function(){this.awaitPos||(this.awaitPos=this.start);var e=this.startNode();return this.next(),e.argument=this.parseMaybeUnary(null,!0),this.finishNode(e,"AwaitExpression")};var z=B.prototype;z.raise=function(e,t){var n=R(this.input,e);t+=" ("+n.line+":"+n.column+")";var a=new SyntaxError(t);throw a.pos=e,a.loc=n,a.raisedAt=this.pos,a},z.raiseRecoverable=z.raise,z.curPosition=function(){if(this.options.locations)return new w(this.curLine,this.pos-this.lineStart)};var V=B.prototype,J=Object.assign||function(e){for(var t=[],n=arguments.length-1;n-- >0;)t[n]=arguments[n+1];for(var a=0;a=0;e--)if(this.context[e].generator)return!0;return!1},ne.updateContext=function(e){var t,n=this.type;n.keyword&&e==b.dot?this.exprAllowed=!1:(t=n.updateContext)?t.call(this,e):this.exprAllowed=n.beforeExpr},b.parenR.updateContext=b.braceR.updateContext=function(){if(1!=this.context.length){var e,t=this.context.pop();t===te.b_stat&&(e=this.curContext())&&"function"===e.token?(this.context.pop(),this.exprAllowed=!1):this.exprAllowed=t===te.b_tmpl||!t.isExpr}else this.exprAllowed=!0},b.braceL.updateContext=function(e){this.context.push(this.braceIsBlock(e)?te.b_stat:te.b_expr),this.exprAllowed=!0},b.dollarBraceL.updateContext=function(){this.context.push(te.b_tmpl),this.exprAllowed=!0},b.parenL.updateContext=function(e){var t=e===b._if||e===b._for||e===b._with||e===b._while;this.context.push(t?te.p_stat:te.p_expr),this.exprAllowed=!0},b.incDec.updateContext=function(){},b._function.updateContext=function(e){e.beforeExpr&&e!==b.semi&&e!==b._else&&(e!==b.colon&&e!==b.braceL||this.curContext()!==te.b_stat)&&this.context.push(te.f_expr),this.exprAllowed=!1},b.backQuote.updateContext=function(){this.curContext()===te.q_tmpl?this.context.pop():this.context.push(te.q_tmpl),this.exprAllowed=!1},b.star.updateContext=function(e){e==b._function&&(this.curContext()===te.f_expr?this.context[this.context.length-1]=te.f_expr_gen:this.context.push(te.f_gen)),this.exprAllowed=!0},b.name.updateContext=function(e){var t=!1;this.options.ecmaVersion>=6&&("of"==this.value&&!this.exprAllowed||"yield"==this.value&&this.inGeneratorContext())&&(t=!0),this.exprAllowed=t};var ae=function(e){this.type=e.type,this.value=e.value,this.start=e.start,this.end=e.end,e.options.locations&&(this.loc=new x(e,e.startLoc,e.endLoc)),e.options.ranges&&(this.range=[e.start,e.end])},ie=B.prototype,re="object"==typeof Packages&&"[object JavaPackage]"==Object.prototype.toString.call(Packages);function oe(e,t,n,a){try{return new RegExp(e,t)}catch(e){if(void 0!==n)throw e instanceof SyntaxError&&a.raise(n,"Error parsing regular expression: "+e.message),e}}ie.next=function(){this.options.onToken&&this.options.onToken(new ae(this)),this.lastTokEnd=this.end,this.lastTokStart=this.start,this.lastTokEndLoc=this.endLoc,this.lastTokStartLoc=this.startLoc,this.nextToken()},ie.getToken=function(){return this.next(),new ae(this)},"undefined"!=typeof Symbol&&(ie[Symbol.iterator]=function(){var e=this;return{next:function(){var t=e.getToken();return{done:t.type===b.eof,value:t}}}}),ie.curContext=function(){return this.context[this.context.length-1]},ie.nextToken=function(){var e=this.curContext();return e&&e.preserveSpace||this.skipSpace(),this.start=this.pos,this.options.locations&&(this.startLoc=this.curPosition()),this.pos>=this.input.length?this.finishToken(b.eof):e.override?e.override(this):void this.readToken(this.fullCharCodeAtPos())},ie.readToken=function(e){return p(e,this.options.ecmaVersion>=6)||92===e?this.readWord():this.getTokenFromCode(e)},ie.fullCharCodeAtPos=function(){var e=this.input.charCodeAt(this.pos);if(e<=55295||e>=57344)return e;var t=this.input.charCodeAt(this.pos+1);return(e<<10)+t-56613888},ie.skipBlockComment=function(){var e,t=this.options.onComment&&this.curPosition(),n=this.pos,a=this.input.indexOf("*/",this.pos+=2);if(-1===a&&this.raise(this.pos-2,"Unterminated comment"),this.pos=a+2,this.options.locations)for(E.lastIndex=n;(e=E.exec(this.input))&&e.index8&&e<14||e>=5760&&C.test(String.fromCharCode(e))))break e;++this.pos}}},ie.finishToken=function(e,t){this.end=this.pos,this.options.locations&&(this.endLoc=this.curPosition());var n=this.type;this.type=e,this.value=t,this.updateContext(n)},ie.readToken_dot=function(){var e=this.input.charCodeAt(this.pos+1);if(e>=48&&e<=57)return this.readNumber(!0);var t=this.input.charCodeAt(this.pos+2);return this.options.ecmaVersion>=6&&46===e&&46===t?(this.pos+=3,this.finishToken(b.ellipsis)):(++this.pos,this.finishToken(b.dot))},ie.readToken_slash=function(){var e=this.input.charCodeAt(this.pos+1);return this.exprAllowed?(++this.pos,this.readRegexp()):61===e?this.finishOp(b.assign,2):this.finishOp(b.slash,1)},ie.readToken_mult_modulo_exp=function(e){var t=this.input.charCodeAt(this.pos+1),n=1,a=42===e?b.star:b.modulo;return this.options.ecmaVersion>=7&&42===t&&(++n,a=b.starstar,t=this.input.charCodeAt(this.pos+2)),61===t?this.finishOp(b.assign,n+1):this.finishOp(a,n)},ie.readToken_pipe_amp=function(e){var t=this.input.charCodeAt(this.pos+1);return t===e?this.finishOp(124===e?b.logicalOR:b.logicalAND,2):61===t?this.finishOp(b.assign,2):this.finishOp(124===e?b.bitwiseOR:b.bitwiseAND,1)},ie.readToken_caret=function(){var e=this.input.charCodeAt(this.pos+1);return 61===e?this.finishOp(b.assign,2):this.finishOp(b.bitwiseXOR,1)},ie.readToken_plus_min=function(e){var t=this.input.charCodeAt(this.pos+1);return t===e?45==t&&62==this.input.charCodeAt(this.pos+2)&&v.test(this.input.slice(this.lastTokEnd,this.pos))?(this.skipLineComment(3),this.skipSpace(),this.nextToken()):this.finishOp(b.incDec,2):61===t?this.finishOp(b.assign,2):this.finishOp(b.plusMin,1)},ie.readToken_lt_gt=function(e){var t=this.input.charCodeAt(this.pos+1),n=1;return t===e?(n=62===e&&62===this.input.charCodeAt(this.pos+2)?3:2,61===this.input.charCodeAt(this.pos+n)?this.finishOp(b.assign,n+1):this.finishOp(b.bitShift,n)):33==t&&60==e&&45==this.input.charCodeAt(this.pos+2)&&45==this.input.charCodeAt(this.pos+3)?(this.inModule&&this.unexpected(),this.skipLineComment(4),this.skipSpace(),this.nextToken()):(61===t&&(n=2),this.finishOp(b.relational,n))},ie.readToken_eq_excl=function(e){var t=this.input.charCodeAt(this.pos+1);return 61===t?this.finishOp(b.equality,61===this.input.charCodeAt(this.pos+2)?3:2):61===e&&62===t&&this.options.ecmaVersion>=6?(this.pos+=2,this.finishToken(b.arrow)):this.finishOp(61===e?b.eq:b.prefix,1)},ie.getTokenFromCode=function(e){switch(e){case 46:return this.readToken_dot();case 40:return++this.pos,this.finishToken(b.parenL);case 41:return++this.pos,this.finishToken(b.parenR);case 59:return++this.pos,this.finishToken(b.semi);case 44:return++this.pos,this.finishToken(b.comma);case 91:return++this.pos,this.finishToken(b.bracketL);case 93:return++this.pos,this.finishToken(b.bracketR);case 123:return++this.pos,this.finishToken(b.braceL);case 125:return++this.pos,this.finishToken(b.braceR);case 58:return++this.pos,this.finishToken(b.colon);case 63:return++this.pos,this.finishToken(b.question);case 96:if(this.options.ecmaVersion<6)break;return++this.pos,this.finishToken(b.backQuote);case 48:var t=this.input.charCodeAt(this.pos+1);if(120===t||88===t)return this.readRadixNumber(16);if(this.options.ecmaVersion>=6){if(111===t||79===t)return this.readRadixNumber(8);if(98===t||66===t)return this.readRadixNumber(2)}case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:return this.readNumber(!1);case 34:case 39:return this.readString(e);case 47:return this.readToken_slash();case 37:case 42:return this.readToken_mult_modulo_exp(e);case 124:case 38:return this.readToken_pipe_amp(e);case 94:return this.readToken_caret();case 43:case 45:return this.readToken_plus_min(e);case 60:case 62:return this.readToken_lt_gt(e);case 61:case 33:return this.readToken_eq_excl(e);case 126:return this.finishOp(b.prefix,1)}this.raise(this.pos,"Unexpected character '"+le(e)+"'")},ie.finishOp=function(e,t){var n=this.input.slice(this.pos,this.pos+t);return this.pos+=t,this.finishToken(e,n)};var se=!!oe("￿","u");function le(e){return e<=65535?String.fromCharCode(e):(e-=65536,String.fromCharCode(55296+(e>>10),56320+(1023&e)))}ie.readRegexp=function(){for(var e,t,n=this,a=this.pos;;){n.pos>=n.input.length&&n.raise(a,"Unterminated regular expression");var i=n.input.charAt(n.pos);if(v.test(i)&&n.raise(a,"Unterminated regular expression"),e)e=!1;else{if("["===i)t=!0;else if("]"===i&&t)t=!1;else if("/"===i&&!t)break;e="\\"===i}++n.pos}var r=this.input.slice(a,this.pos);++this.pos;var o=this.readWord1(),s=r,l="";if(o){var c=/^[gim]*$/;this.options.ecmaVersion>=6&&(c=/^[gimuy]*$/),c.test(o)||this.raise(a,"Invalid regular expression flag"),o.indexOf("u")>=0&&(se?l="u":(s=(s=s.replace(/\\u\{([0-9a-fA-F]+)\}/g,function(e,t,i){return(t=Number("0x"+t))>1114111&&n.raise(a+i+3,"Code point out of bounds"),"x"})).replace(/\\u([a-fA-F0-9]{4})|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,"x"),l=l.replace("u","")))}var u=null;return re||(oe(s,l,a,this),u=oe(r,o)),this.finishToken(b.regexp,{pattern:r,flags:o,value:u})},ie.readInt=function(e,t){for(var n=this.pos,a=0,i=0,r=null==t?1/0:t;i=97?s-97+10:s>=65?s-65+10:s>=48&&s<=57?s-48:1/0)>=e)break;++this.pos,a=a*e+o}return this.pos===n||null!=t&&this.pos-n!==t?null:a},ie.readRadixNumber=function(e){this.pos+=2;var t=this.readInt(e);return null==t&&this.raise(this.start+2,"Expected number in radix "+e),p(this.fullCharCodeAtPos())&&this.raise(this.pos,"Identifier directly after number"),this.finishToken(b.num,t)},ie.readNumber=function(e){var t=this.pos,n=!1,a=48===this.input.charCodeAt(this.pos);e||null!==this.readInt(10)||this.raise(t,"Invalid number"),a&&this.pos==t+1&&(a=!1);var i=this.input.charCodeAt(this.pos);46!==i||a||(++this.pos,this.readInt(10),n=!0,i=this.input.charCodeAt(this.pos)),69!==i&&101!==i||a||(43!==(i=this.input.charCodeAt(++this.pos))&&45!==i||++this.pos,null===this.readInt(10)&&this.raise(t,"Invalid number"),n=!0),p(this.fullCharCodeAtPos())&&this.raise(this.pos,"Identifier directly after number");var r,o=this.input.slice(t,this.pos);return n?r=parseFloat(o):a&&1!==o.length?/[89]/.test(o)||this.strict?this.raise(t,"Invalid number"):r=parseInt(o,8):r=parseInt(o,10),this.finishToken(b.num,r)},ie.readCodePoint=function(){var e,t=this.input.charCodeAt(this.pos);if(123===t){this.options.ecmaVersion<6&&this.unexpected();var n=++this.pos;e=this.readHexChar(this.input.indexOf("}",this.pos)-this.pos),++this.pos,e>1114111&&this.raise(n,"Code point out of bounds")}else e=this.readHexChar(4);return e},ie.readString=function(e){for(var t="",n=++this.pos;;){this.pos>=this.input.length&&this.raise(this.start,"Unterminated string constant");var a=this.input.charCodeAt(this.pos);if(a===e)break;92===a?(t+=this.input.slice(n,this.pos),t+=this.readEscapedChar(!1),n=this.pos):(k(a)&&this.raise(this.start,"Unterminated string constant"),++this.pos)}return t+=this.input.slice(n,this.pos++),this.finishToken(b.string,t)},ie.readTmplToken=function(){for(var e="",t=this.pos;;){this.pos>=this.input.length&&this.raise(this.start,"Unterminated template");var n=this.input.charCodeAt(this.pos);if(96===n||36===n&&123===this.input.charCodeAt(this.pos+1))return this.pos===this.start&&this.type===b.template?36===n?(this.pos+=2,this.finishToken(b.dollarBraceL)):(++this.pos,this.finishToken(b.backQuote)):(e+=this.input.slice(t,this.pos),this.finishToken(b.template,e));if(92===n)e+=this.input.slice(t,this.pos),e+=this.readEscapedChar(!0),t=this.pos;else if(k(n)){switch(e+=this.input.slice(t,this.pos),++this.pos,n){case 13:10===this.input.charCodeAt(this.pos)&&++this.pos;case 10:e+="\n";break;default:e+=String.fromCharCode(n)}this.options.locations&&(++this.curLine,this.lineStart=this.pos),t=this.pos}else++this.pos}},ie.readEscapedChar=function(e){var t=this.input.charCodeAt(++this.pos);switch(++this.pos,t){case 110:return"\n";case 114:return"\r";case 120:return String.fromCharCode(this.readHexChar(2));case 117:return le(this.readCodePoint());case 116:return"\t";case 98:return"\b";case 118:return"\v";case 102:return"\f";case 13:10===this.input.charCodeAt(this.pos)&&++this.pos;case 10:return this.options.locations&&(this.lineStart=this.pos,++this.curLine),"";default:if(t>=48&&t<=55){var n=this.input.substr(this.pos-1,3).match(/^[0-7]+/)[0],a=parseInt(n,8);return a>255&&(n=n.slice(0,-1),a=parseInt(n,8)),"0"!==n&&(this.strict||e)&&this.raise(this.pos-2,"Octal literal in strict mode"),this.pos+=n.length-1,String.fromCharCode(a)}return String.fromCharCode(t)}},ie.readHexChar=function(e){var t=this.pos,n=this.readInt(16,e);return null===n&&this.raise(t,"Bad character escape sequence"),n},ie.readWord1=function(){this.containsEsc=!1;for(var e="",t=!0,n=this.pos,a=this.options.ecmaVersion>=6;this.posd()?1/0:t*i.CONSTANTS.BaseCostFor1GBOfRamServer*a.BitNodeMultipliers.PurchasedServerCost}function h(){return Math.round(i.CONSTANTS.PurchasedServerLimit*a.BitNodeMultipliers.PurchasedServerLimit)}function d(){const e=Math.round(i.CONSTANTS.PurchasedServerMaxRam*a.BitNodeMultipliers.PurchasedServerMaxRam);return 1<<31-Math.clz32(e)}function g(e){const t=m(e);if(r.a.money.lt(t))Object(l.dialogBoxCreate)("You don't have enough money to purchase this server!");else if(r.a.purchasedServers.length>=h())Object(l.dialogBoxCreate)("You have reached the maximum limit of "+h()+" servers. You cannot purchase any more. You can delete some of your purchased servers using the deleteServer() Netscript function in a script");else{var n=Object(u.yesNoTxtInpBoxGetInput)();if(""!=n){var a=new s.Server({ip:Object(c.createRandomIp)(),hostname:n,organizationName:"",isConnectedTo:!1,adminRights:!0,purchasedByPlayer:!0,maxRam:e});Object(o.AddToAllServers)(a),r.a.purchasedServers.push(a.ip);var i=r.a.getHomeComputer();i.serversOnNetwork.push(a.ip),a.serversOnNetwork.push(i.ip),r.a.loseMoney(t),Object(l.dialogBoxCreate)("Server successfully purchased with hostname "+n)}else Object(l.dialogBoxCreate)("You must enter a hostname for your new server!")}}function _(e){if(r.a.money.lt(e))return void Object(l.dialogBoxCreate)("You do not have enough money to purchase additional RAM for your home computer");const t=r.a.getHomeComputer();t.maxRam>=i.CONSTANTS.HomeComputerMaxRam?Object(l.dialogBoxCreate)("You cannot upgrade your home computer RAM because it is at its maximum possible value"):(t.maxRam*=2,r.a.loseMoney(e),Object(l.dialogBoxCreate)("Purchased additional RAM for home computer! It now has "+t.maxRam+"GB of RAM."))}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.setTimeoutRef=window.setTimeout.bind(window)},function(e,t,n){"use strict";n.d(t,"a",function(){return f}),n.d(t,"b",function(){return g}),n.d(t,"e",function(){return d}),n.d(t,"d",function(){return y}),n.d(t,"c",function(){return v});var a=n(54),i=(n(16),n(13)),r=n(5),o=n(30),s=n(72),l=n(0),c=n(77),u=n(21),p=n(19),m=n(9);function h(e,t=!1){e.recvd=!0,!t&&p.Settings.SuppressMessages||d(e),function(e,t){var n=Object(u.GetServerByHostname)(t);if(null==n)return void console.log("WARNING: Did not locate "+t);for(var a=0;a

    This message was saved as "+e.filename+" onto your home computer.";Object(m.dialogBoxCreate)(t)}function g(){var e=f[b.Jumper0],t=f[b.Jumper1],n=f[b.Jumper2],a=f[b.Jumper3],u=f[b.Jumper4],p=f[b.CyberSecTest],d=f[b.NiteSecTest],g=f[b.BitRunnersTest],_=f[b.RedPill],y=!1;i.Augmentations[r.AugmentationNames.TheRedPill].owned&&(y=!0),_&&y&&0===l.a.sourceFiles.length&&!c.b&&!s.c?m.dialogBoxOpened||h(_,!0):_&&y?c.b||s.c||m.dialogBoxOpened||h(_):e&&!e.recvd&&l.a.hacking_skill>=25?(h(e),l.a.getHomeComputer().programs.push(o.Programs.Flight.name)):t&&!t.recvd&&l.a.hacking_skill>=40?h(t):p&&!p.recvd&&l.a.hacking_skill>=50?h(p):n&&!n.recvd&&l.a.hacking_skill>=175?h(n):d&&!d.recvd&&l.a.hacking_skill>=200?h(d):a&&!a.recvd&&l.a.hacking_skill>=350?h(a):u&&!u.recvd&&l.a.hacking_skill>=490?h(u):g&&!g.recvd&&l.a.hacking_skill>=500&&h(g)}function _(e){f[e.filename]=e}let f={};function y(e){f=JSON.parse(e,Reviver)}let b={Jumper0:"j0.msg",Jumper1:"j1.msg",Jumper2:"j2.msg",Jumper3:"j3.msg",Jumper4:"j4.msg",CyberSecTest:"csec-test.msg",NiteSecTest:"nitesec-test.msg",BitRunnersTest:"19dfj3l1nd.msg",RedPill:"icarus.msg"};function v(){f={},_(new a.Message(b.Jumper0,"I know you can sense it. I know you're searching for it. It's why you spend night after night at your computer.

    It's real, I've seen it. And I can help you find it. But not right now. You're not ready yet.

    Use this program to track your progress

    The fl1ght.exe program was added to your home computer

    -jump3R")),_(new a.Message(b.Jumper1,"Soon you will be contacted by a hacking group known as CyberSec. They can help you with your search.

    You should join them, garner their favor, and exploit them for their Augmentations. But do not trust them. They are not what they seem. No one is.

    -jump3R")),_(new a.Message(b.Jumper2,"Do not try to save the world. There is no world to save. If you want to find the truth, worry only about yourself. Ethics and morals will get you killed.

    Watch out for a hacking group known as NiteSec.

    -jump3R")),_(new a.Message(b.Jumper3,"You must learn to walk before you can run. And you must run before you can fly. Look for the black hand.

    I.I.I.I

    -jump3R")),_(new a.Message(b.Jumper4,"To find what you are searching for, you must understand the bits. The bits are all around us. The runners will help you.

    -jump3R")),_(new a.Message(b.CyberSecTest,"We've been watching you. Your skills are very impressive. But you're wasting your talents. If you join us, you can put your skills to good use and change the world for the better. If you join us, we can unlock your full potential.

    But first, you must pass our test. Find and hack our server using the Terminal.

    -CyberSec")),_(new a.Message(b.NiteSecTest,"People say that the corrupted governments and corporations rule the world. Yes, maybe they do. But do you know who everyone really fears? People like us. Because they can't hide from us. Because they can't fight shadows and ideas with bullets.

    Join us, and people will fear you, too.

    Find and hack our hidden server using the Terminal. Then, we will contact you again.

    -NiteSec")),_(new a.Message(b.BitRunnersTest,"We know what you are doing. We know what drives you. We know what you are looking for.

    We can help you find the answers.

    run4theh111z")),_(new a.Message(b.RedPill,"@)(#V%*N)@(#*)*C)@#%*)*V)@#(*%V@)(#VN%*)@#(*%
    )@B(*#%)@)M#B*%V)____FIND___#$@)#%(B*)@#(*%B)
    @_#(%_@#M(BDSPOMB__THE-CAVE_#)$(*@#$)@#BNBEGB
    DFLSMFVMV)#@($*)@#*$MV)@#(*$V)M#(*$)M@(#*VM$)"))}},function(e,t,n){"use strict";(function(e){n.d(t,"a",function(){return T}),n.d(t,"d",function(){return O}),n.d(t,"c",function(){return S}),n.d(t,"b",function(){return M});var a=n(177),i=n(176),r=n(11),o=n(69),s=n(14),l=n(53),c=n(3),u=n(9),p=n(17),m=n(31),h=n(99),d=n(4),g=n(37),_=n(12),f=n(7),y=n(43),b=n(15),v=n(33),E=n(75),k=n(26);e(document).keydown(function(e){if(_.routing.isOn(_.Page.Gang)&&e.altKey){if(null!=N.gangMemberFilter&&N.gangMemberFilter===document.activeElement)return;e.keyCode===m.KEY[1]?"block"===N.gangTerritorySubpage.style.display&&N.managementButton.click():e.keyCode===m.KEY[2]&&"block"===N.gangManagementSubpage.style.display&&N.territoryButton.click()}}),e(document).mousedown(function(t){N.gangMemberUpgradeBoxOpened&&null==e(t.target).closest("#gang-member-upgrade-popup-box-content").get(0)&&(Object(E.removeElement)(N.gangMemberUpgradeBox),N.gangMemberUpgradeBox=null,N.gangMemberUpgradeBoxContent=null,N.gangMemberUpgradeBoxOpened=!1,N.gangMemberUpgradeBoxElements=null)});let C=["Slum Snakes","Tetrads","The Syndicate","The Dark Army","Speakers for the Dead","NiteSec","The Black Hand"],T={"Slum Snakes":{power:1,territory:1/7},Tetrads:{power:1,territory:1/7},"The Syndicate":{power:1,territory:1/7},"The Dark Army":{power:1,territory:1/7},"Speakers for the Dead":{power:1,territory:1/7},NiteSec:{power:1,territory:1/7},"The Black Hand":{power:1,territory:1/7}};function O(){T={"Slum Snakes":{power:1,territory:1/7},Tetrads:{power:1,territory:1/7},"The Syndicate":{power:1,territory:1/7},"The Dark Army":{power:1,territory:1/7},"Speakers for the Dead":{power:1,territory:1/7},NiteSec:{power:1,territory:1/7},"The Black Hand":{power:1,territory:1/7}}}function S(e){T=JSON.parse(e,p.Reviver)}function M(e,t=!1){this.facName=e,this.members=[],this.wanted=1,this.respect=1,this.isHackingGang=t,this.respectGainRate=0,this.wantedGainRate=0,this.moneyGainRate=0,this.storedCycles=0,this.storedTerritoryAndPowerCycles=0,this.territoryClashChance=0,this.territoryWarfareEngaged=!1,this.notifyMemberDeath=!0}function P(e){this.name=e,this.task="Unassigned",this.earnedRespect=0,this.hack=1,this.str=1,this.def=1,this.dex=1,this.agi=1,this.cha=1,this.hack_exp=0,this.str_exp=0,this.def_exp=0,this.dex_exp=0,this.agi_exp=0,this.cha_exp=0,this.hack_mult=1,this.str_mult=1,this.def_mult=1,this.dex_mult=1,this.agi_mult=1,this.cha_mult=1,this.hack_asc_mult=1,this.str_asc_mult=1,this.def_asc_mult=1,this.dex_asc_mult=1,this.agi_asc_mult=1,this.cha_asc_mult=1,this.upgrades=[],this.augmentations=[]}function A(e="",t="",n=!1,a=!1,i={baseRespect:0,baseWanted:0,baseMoney:0,hackWeight:0,strWeight:0,defWeight:0,dexWeight:0,agiWeight:0,chaWeight:0,difficulty:0}){this.name=e,this.desc=t,this.isHacking=n,this.isCombat=a,this.baseRespect=i.baseRespect?i.baseRespect:0,this.baseWanted=i.baseWanted?i.baseWanted:0,this.baseMoney=i.baseMoney?i.baseMoney:0,this.hackWeight=i.hackWeight?i.hackWeight:0,this.strWeight=i.strWeight?i.strWeight:0,this.defWeight=i.defWeight?i.defWeight:0,this.dexWeight=i.dexWeight?i.dexWeight:0,this.agiWeight=i.agiWeight?i.agiWeight:0,this.chaWeight=i.chaWeight?i.chaWeight:0,100!=Math.round(this.hackWeight+this.strWeight+this.defWeight+this.dexWeight+this.agiWeight+this.chaWeight)&&console.error(`GangMemberTask ${this.name} weights do not add up to 100`),this.difficulty=i.difficulty?i.difficulty:1,this.territory=i.territory?i.territory:{money:1,respect:1,wanted:1}}M.prototype.getPower=function(){return T[this.facName].power},M.prototype.getTerritory=function(){return T[this.facName].territory},M.prototype.process=function(e=1,t){const n=1e3/r.Engine._idleSpeed;if(isNaN(e)&&console.error(`NaN passed into Gang.process(): ${e}`),this.storedCycles+=e,this.storedCycles<2*n)return;const a=Math.min(this.storedCycles,5*n);try{this.processGains(a,t),this.processExperienceGains(a),this.processTerritoryAndPowerGains(a),this.storedCycles-=a}catch(e){Object(y.exceptionAlert)(`Exception caught when processing Gang: ${e}`)}},M.prototype.processGains=function(e=1,t){for(var n=0,a=0,i=0,r=0;rt&&(n=1),this.wanted=n,this.wanted<1&&(this.wanted=1)}else console.warn("ERROR: wantedLevelGains is NaN");"number"==typeof n?(t.gainMoney(n*e),t.recordMoneySource(n*e,"gang")):console.warn("ERROR: respectGains is NaN")},M.prototype.processTerritoryAndPowerGains=function(e=1){if(this.storedTerritoryAndPowerCycles+=e,!(this.storedTerritoryAndPowerCycles<100)){this.storedTerritoryAndPowerCycles-=100;var t=this.facName;for(const e in T)if(T.hasOwnProperty(e))if(e==t)T[e].power+=this.calculatePower();else{const t=Math.random();if(t<.5){const t=.005*T[e].power;T[e].power+=Math.min(.85,t)}else{const n=.75*t*T[e].territory;T[e].power+=n}}this.territoryWarfareEngaged?this.territoryClashChance=1:this.territoryClashChance>0&&(this.territoryClashChance=Math.max(0,this.territoryClashChance-.01));for(var n=0;ne!==n),a=Object(b.getRandomInt)(0,e.length-1),i=C[n],r=e[a];if(!(i!==t&&r!==t||Math.random()=30)&&this.respect>=this.getRespectNeededToRecruitMember()},M.prototype.getRespectNeededToRecruitMember=function(){if(this.members.length<3)return 0;const e=this.members.length-2;return Math.round(.9*Math.pow(e,3)+Math.pow(e,2))},M.prototype.recruitMember=function(e){if(""===(e=String(e))||!this.canRecruitMember())return!1;if(this.members.filter(t=>t.name===e).length>=1)return!1;let t=new P(e);return this.members.push(t),_.routing.isOn(_.Page.Gang)&&(this.createGangMemberDisplayElement(t),this.updateGangContent()),!0},M.prototype.getWantedPenalty=function(){return this.respect/(this.respect+this.wanted)},M.prototype.processExperienceGains=function(e=1){for(var t=0;t=0;--e){const n=this.members[e];if("Territory Warfare"!==n.task)continue;const a=t/Math.pow(n.def,.6);Math.random()")):t.log(`Ascended Gang member ${e.name}`),_.routing.isOn(_.Page.Gang)&&this.displayGangMemberList(),n}catch(e){if(null!=t)throw e;Object(y.exceptionAlert)(e)}},M.prototype.getDiscount=function(){const e=this.getPower(),t=this.respect,n=Math.pow(t,.01)+t/5e6+Math.pow(e,.01)+e/1e6-1;return Math.max(1,n)},M.prototype.getAllTaskNames=function(){let e=[];const t=Object.keys(w);return e=this.isHackingGang?t.filter(e=>{let t=w[e];return null!=t&&("Unassigned"!==e&&t.isHacking)}):t.filter(e=>{let t=w[e];return null!=t&&("Unassigned"!==e&&t.isCombat)})},M.prototype.getAllUpgradeNames=function(){return Object.keys(R)},M.prototype.getUpgradeCost=function(e){return null==R[e]?1/0:R[e].getCost(this)},M.prototype.getUpgradeType=function(e){const t=R[e];if(null==t)return"";switch(t.type){case"w":return"Weapon";case"a":return"Armor";case"v":return"Vehicle";case"r":return"Rootkit";case"g":return"Augmentation";default:return""}},M.prototype.toJSON=function(){return Object(p.Generic_toJSON)("Gang",this)},M.fromJSON=function(e){return Object(p.Generic_fromJSON)(M,e.data)},p.Reviver.constructors.Gang=M,P.prototype.calculateSkill=function(e,t=1){return Math.max(Math.floor(t*(32*Math.log(e+534.5)-200)),1)},P.prototype.updateSkillLevels=function(){this.hack=this.calculateSkill(this.hack_exp,this.hack_mult*this.hack_asc_mult),this.str=this.calculateSkill(this.str_exp,this.str_mult*this.str_asc_mult),this.def=this.calculateSkill(this.def_exp,this.def_mult*this.def_asc_mult),this.dex=this.calculateSkill(this.dex_exp,this.dex_mult*this.dex_asc_mult),this.agi=this.calculateSkill(this.agi_exp,this.agi_mult*this.agi_asc_mult),this.cha=this.calculateSkill(this.cha_exp,this.cha_mult*this.cha_asc_mult)},P.prototype.calculatePower=function(){return(this.hack+this.str+this.def+this.dex+this.agi+this.cha)/95},P.prototype.assignToTask=function(e){return w.hasOwnProperty(e)?(this.task=e,!0):(this.task="Unassigned",!1)},P.prototype.unassignFromTask=function(){this.task="Unassigned"},P.prototype.getTask=function(){return this.task instanceof A&&(this.task=this.task.name),w.hasOwnProperty(this.task)?w[this.task]:w.Unassigned},P.prototype.calculateRespectGain=function(e){const t=this.getTask();if(null==t||!(t instanceof A)||0===t.baseRespect)return 0;var n=t.hackWeight/100*this.hack+t.strWeight/100*this.str+t.defWeight/100*this.def+t.dexWeight/100*this.dex+t.agiWeight/100*this.agi+t.chaWeight/100*this.cha;if((n-=4*t.difficulty)<=0)return 0;const a=Math.pow(100*T[e.facName].territory,t.territory.respect)/100;if(isNaN(a)||a<=0)return 0;var i=e.getWantedPenalty();return 11*t.baseRespect*n*a*i},P.prototype.calculateWantedLevelGain=function(e){const t=this.getTask();if(null==t||!(t instanceof A)||0===t.baseWanted)return 0;var n=t.hackWeight/100*this.hack+t.strWeight/100*this.str+t.defWeight/100*this.def+t.dexWeight/100*this.dex+t.agiWeight/100*this.agi+t.chaWeight/100*this.cha;if((n-=3.5*t.difficulty)<=0)return 0;const a=Math.pow(100*T[e.facName].territory,t.territory.wanted)/100;return isNaN(a)||a<=0?0:t.baseWanted<0?.5*t.baseWanted*n*a:7*t.baseWanted/Math.pow(3*n*a,.8)},P.prototype.calculateMoneyGain=function(e){const t=this.getTask();if(null==t||!(t instanceof A)||0===t.baseMoney)return 0;var n=t.hackWeight/100*this.hack+t.strWeight/100*this.str+t.defWeight/100*this.def+t.dexWeight/100*this.dex+t.agiWeight/100*this.agi+t.chaWeight/100*this.cha;if((n-=3.2*t.difficulty)<=0)return 0;const a=Math.pow(100*T[e.facName].territory,t.territory.money)/100;if(isNaN(a)||a<=0)return 0;var i=e.getWantedPenalty();return 5*t.baseMoney*n*a*i},P.prototype.gainExperience=function(e=1){const t=this.getTask();if(null==t||!(t instanceof A)||t===w.Unassigned)return;const n=Math.pow(t.difficulty,.9)*e;this.hack_exp+=t.hackWeight/1500*n,this.str_exp+=t.strWeight/1500*n,this.def_exp+=t.defWeight/1500*n,this.dex_exp+=t.dexWeight/1500*n,this.agi_exp+=t.agiWeight/1500*n,this.cha_exp+=t.chaWeight/1500*n},P.prototype.recordEarnedRespect=function(e=1,t){this.earnedRespect+=this.calculateRespectGain(t)*e},P.prototype.ascend=function(){const e=this.getAscensionResults(),t=e.hack,n=e.str,a=e.def,i=e.dex,r=e.agi,o=e.cha;this.hack_asc_mult+=t,this.str_asc_mult+=n,this.def_asc_mult+=a,this.dex_asc_mult+=i,this.agi_asc_mult+=r,this.cha_asc_mult+=o,this.upgrades.length=0,this.hack_mult=1,this.str_mult=1,this.def_mult=1,this.dex_mult=1,this.agi_mult=1,this.cha_mult=1;for(let e=0;e{!function(e,t,n,a,i){w[e]=new A(e,t,n,a,i)}(e.name,e.desc,e.isHacking,e.isCombat,e.params)}),x.prototype.getCost=function(e){const t=e.getDiscount();return this.cost/t},x.prototype.createDescription=function(){const e=["Increases:"];null!=this.mults.str&&e.push(`* Strength by ${Math.round(100*(this.mults.str-1))}%`),null!=this.mults.def&&e.push(`* Defense by ${Math.round(100*(this.mults.def-1))}%`),null!=this.mults.dex&&e.push(`* Dexterity by ${Math.round(100*(this.mults.dex-1))}%`),null!=this.mults.agi&&e.push(`* Agility by ${Math.round(100*(this.mults.agi-1))}%`),null!=this.mults.cha&&e.push(`* Charisma by ${Math.round(100*(this.mults.cha-1))}%`),null!=this.mults.hack&&e.push(`* Hacking by ${Math.round(100*(this.mults.hack-1))}%`),this.desc=e.join("
    ")},x.prototype.apply=function(e){null!=this.mults.str&&(e.str_mult*=this.mults.str),null!=this.mults.def&&(e.def_mult*=this.mults.def),null!=this.mults.dex&&(e.dex_mult*=this.mults.dex),null!=this.mults.agi&&(e.agi_mult*=this.mults.agi),null!=this.mults.cha&&(e.cha_mult*=this.mults.cha),null!=this.mults.hack&&(e.hack_mult*=this.mults.hack)},x.prototype.toJSON=function(){return Object(p.Generic_toJSON)("GangMemberUpgrade",this)},x.fromJSON=function(e){return Object(p.Generic_fromJSON)(x,e.data)},p.Reviver.constructors.GangMemberUpgrade=x;const R={};i.gangMemberUpgradesMetadata.forEach(e=>{!function(e,t,n,a){R[e]=new x(e,t,n,a)}(e.name,e.cost,e.upgType,e.mults)}),M.prototype.createGangMemberUpgradeBox=function(e,t=""){const n="gang-member-upgrade-popup-box";if(N.gangMemberUpgradeBoxOpened){if(null==N.gangMemberUpgradeBoxElements||null==N.gangMemberUpgradeBox||null==N.gangMemberUpgradeBoxContent)return void console.error("Refreshing Gang member upgrade box throws error because required elements are null");for(var a=2;a-1||this.members[a].task.indexOf(i)>-1){var r=this.members[a].createGangMemberUpgradePanel(this,e);N.gangMemberUpgradeBoxContent.appendChild(r),N.gangMemberUpgradeBoxElements.push(r)}}else{N.gangMemberUpgradeBoxFilter=Object(d.createElement)("input",{type:"text",placeholder:"Filter gang members",value:t,onkeyup:()=>{var t=N.gangMemberUpgradeBoxFilter.value.toString();this.createGangMemberUpgradeBox(e,t)}}),N.gangMemberUpgradeBoxDiscount=Object(d.createElement)("p",{innerText:"Discount: -"+c.numeralWrapper.format(1-1/this.getDiscount(),"0.00%"),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."}),N.gangMemberUpgradeBoxElements=[N.gangMemberUpgradeBoxFilter,N.gangMemberUpgradeBoxDiscount];for(i=N.gangMemberUpgradeBoxFilter.value.toString(),a=0;a-1||this.members[a].task.indexOf(i)>-1)&&N.gangMemberUpgradeBoxElements.push(this.members[a].createGangMemberUpgradePanel(this,e));N.gangMemberUpgradeBox=Object(g.createPopup)(n,N.gangMemberUpgradeBoxElements),N.gangMemberUpgradeBoxContent=document.getElementById(n+"-content"),N.gangMemberUpgradeBoxOpened=!0}},P.prototype.createGangMemberUpgradePanel=function(e,t){var n=Object(d.createElement)("div",{border:"1px solid white"}),a=Object(d.createElement)("h1",{innerText:this.name+" ("+this.task+")"});n.appendChild(a);var i=Object(d.createElement)("pre",{fontSize:"14px",display:"inline-block",width:"20%",innerText:"Hack: "+this.hack+" (x"+Object(f.formatNumber)(this.hack_mult*this.hack_asc_mult,2)+")\nStr: "+this.str+" (x"+Object(f.formatNumber)(this.str_mult*this.str_asc_mult,2)+")\nDef: "+this.def+" (x"+Object(f.formatNumber)(this.def_mult*this.def_asc_mult,2)+")\nDex: "+this.dex+" (x"+Object(f.formatNumber)(this.dex_mult*this.dex_asc_mult,2)+")\nAgi: "+this.agi+" (x"+Object(f.formatNumber)(this.agi_mult*this.agi_asc_mult,2)+")\nCha: "+this.cha+" (x"+Object(f.formatNumber)(this.cha_mult*this.cha_asc_mult,2)+")\n"});const r=[];function o(e){const t=R[e];null!=t?r.push(Object(d.createElement)("div",{class:"gang-owned-upgrade",innerText:e,tooltip:t.desc})):console.error(`Could not find GangMemberUpgrade object for name ${e}`)}for(const e of this.upgrades)o(e);for(const e of this.augmentations)o(e);var s=Object(d.createElement)("div",{class:"gang-owned-upgrades-div",innerText:"Purchased Upgrades:"});for(const e of r)s.appendChild(e);n.appendChild(i),n.appendChild(s),n.appendChild(Object(d.createElement)("br",{}));const l=[],u=[],p=[],m=[],h=[];for(let n in R)if(R.hasOwnProperty(n)){let a=R[n];if(t.money.lt(a.getCost(e)))continue;if(this.upgrades.includes(n)||this.augmentations.includes(n))continue;switch(a.type){case"w":l.push(a);break;case"a":u.push(a);break;case"v":p.push(a);break;case"r":m.push(a);break;case"g":h.push(a);break;default:console.error(`ERROR: Invalid Gang Member Upgrade Type: ${a.type}`)}}const g=Object(d.createElement)("div",{width:"20%",display:"inline-block"}),_=Object(d.createElement)("div",{width:"20%",display:"inline-block"}),y=Object(d.createElement)("div",{width:"20%",display:"inline-block"}),b=Object(d.createElement)("div",{width:"20%",display:"inline-block"}),v=Object(d.createElement)("div",{width:"20%",display:"inline-block"});g.appendChild(Object(d.createElement)("h2",{innerText:"Weapons"})),_.appendChild(Object(d.createElement)("h2",{innerText:"Armor"})),y.appendChild(Object(d.createElement)("h2",{innerText:"Vehicles"})),b.appendChild(Object(d.createElement)("h2",{innerText:"Rootkits"})),v.appendChild(Object(d.createElement)("h2",{innerText:"Augmentations"}));const E=[l,u,p,m,h],k=[g,_,y,b,v];for(let n=0;n(i.buyUpgrade(n,t,e),!1)};r>=3?s.tooltipleft=n.desc:s.tooltip=n.desc,a.appendChild(Object(d.createElement)("a",s))}(a[r],i,this,n,e)}}return n.appendChild(g),n.appendChild(_),n.appendChild(y),n.appendChild(b),n.appendChild(v),n};const N={gangContentCreated:!1,gangContainer:null,managementButton:null,territoryButton:null,gangManagementSubpage:null,gangTerritorySubpage:null,gangDesc:null,gangInfo:null,gangRecruitMemberButton:null,gangRecruitRequirementText:null,gangExpandAllButton:null,gangCollapseAllButton:null,gangMemberFilter:null,gangManageEquipmentButton:null,gangMemberList:null,gangMemberPanels:{},gangMemberUpgradeBoxOpened:!1,gangMemberUpgradeBox:null,gangMemberUpgradeBoxContent:null,gangMemberUpgradeBoxFilter:null,gangMemberUpgradeBoxDiscount:null,gangMemberUpgradeBoxElements:null,gangTerritoryDescText:null,gangTerritoryWarfareCheckbox:null,gangTerritoryWarfareCheckboxLabel:null,gangTerritoryWarfareClashChance:null,gangTerritoryDeathNotifyCheckbox:null,gangTerritoryDeathNotifyCheckboxLabel:null,gangTerritoryInfoText:null};M.prototype.displayGangContent=function(e){if(!N.gangContentCreated||null==N.gangContainer){N.gangContentCreated=!0,N.gangContainer=Object(d.createElement)("div",{id:"gang-container",class:"generic-menupage-container"});var t=this.facName;this.members,this.wanted,this.respect;N.gangContainer.appendChild(Object(d.createElement)("a",{class:"a-link-button",display:"inline-block",innerText:"Back",clickListener:()=>(r.Engine.loadFactionContent(),Object(l.a)(t),!1)})),N.managementButton=Object(d.createElement)("a",{id:"gang-management-subpage-button",class:"a-link-button-inactive",display:"inline-block",innerHTML:"Gang Management (Alt+1)",clickListener:()=>(N.gangManagementSubpage.style.display="block",N.gangTerritorySubpage.style.display="none",N.managementButton.classList.toggle("a-link-button-inactive"),N.managementButton.classList.toggle("a-link-button"),N.territoryButton.classList.toggle("a-link-button-inactive"),N.territoryButton.classList.toggle("a-link-button"),this.updateGangContent(),!1)}),N.territoryButton=Object(d.createElement)("a",{id:"gang-territory-subpage-button",class:"a-link-button",display:"inline-block",innerHTML:"Gang Territory (Alt+2)",clickListener:()=>(N.gangManagementSubpage.style.display="none",N.gangTerritorySubpage.style.display="block",N.managementButton.classList.toggle("a-link-button-inactive"),N.managementButton.classList.toggle("a-link-button"),N.territoryButton.classList.toggle("a-link-button-inactive"),N.territoryButton.classList.toggle("a-link-button"),this.updateGangContent(),!1)}),N.gangContainer.appendChild(N.managementButton),N.gangContainer.appendChild(N.territoryButton),N.gangManagementSubpage=Object(d.createElement)("div",{display:"block",id:"gang-management-subpage"});var n="";n=this.isHackingGang?"Ethical Hacking":"Vigilante Justice",N.gangDesc=Object(d.createElement)("p",{width:"70%",innerHTML:"This page is used to manage your gang members and get an overview of your gang's stats.

    If a gang member is not earning much money or respect, the task that you have assigned to that member might be too difficult. Consider training that member's stats or choosing an easier task. The tasks closer to the top of the dropdown list are generally easier. Alternatively, the gang member's low production might be due to the fact that your wanted level is too high. Consider assigning a few members to the '"+n+"' task to lower your wanted level.

    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"}),N.gangManagementSubpage.appendChild(N.gangDesc),N.gangInfo=Object(d.createElement)("p",{id:"gang-info",width:"70%"}),N.gangManagementSubpage.appendChild(N.gangInfo),N.gangRecruitMemberButton=Object(d.createElement)("a",{id:"gang-management-recruit-member-btn",class:"a-link-button-inactive",innerHTML:"Recruit Gang Member",display:"inline-block",margin:"10px",clickListener:()=>{const e="recruit-gang-member-popup";let t;const n=Object(d.createElement)("p",{innerText:"Please enter a name for your new Gang member:"}),a=Object(d.createElement)("br"),i=Object(d.createElement)("input",{onkeyup:e=>{e.keyCode===m.KEY.ENTER&&t.click()},placeholder:"Name must be unique",type:"text"});t=Object(d.createElement)("a",{class:"std-button",clickListener:()=>{let t=i.value;return""===t?(Object(u.dialogBoxCreate)("You must enter a name for your Gang member!"),!1):this.canRecruitMember()?this.recruitMember(t)?(Object(k.removeElementById)(e),!1):(Object(u.dialogBoxCreate)("You already have a gang member with this name!"),!1):(Object(u.dialogBoxCreate)("You cannot recruit another Gang member!"),!1)},innerText:"Recruit Gang Member"});const r=Object(d.createElement)("a",{class:"std-button",clickListener:()=>(Object(k.removeElementById)(e),!1),innerText:"Cancel"});Object(g.createPopup)(e,[n,a,i,t,r])}}),N.gangManagementSubpage.appendChild(N.gangRecruitMemberButton),N.gangRecruitRequirementText=Object(d.createElement)("p",{color:"red",id:"gang-recruit-requirement-text",margin:"10px"}),N.gangManagementSubpage.appendChild(N.gangRecruitRequirementText),N.gangManagementSubpage.appendChild(Object(d.createElement)("br",{})),N.gangExpandAllButton=Object(d.createElement)("a",{class:"a-link-button",display:"inline-block",innerHTML:"Expand All",clickListener:()=>{for(var e=N.gangManagementSubpage.getElementsByClassName("accordion-header"),t=0;t{for(var e=N.gangManagementSubpage.getElementsByClassName("accordion-header"),t=0;t{this.displayGangMemberList()}}),N.gangManageEquipmentButton=Object(d.createElement)("a",{class:"a-link-button",display:"inline-block",innerHTML:"Manage Equipment",clickListener:()=>{this.createGangMemberUpgradeBox(e)}}),N.gangManagementSubpage.appendChild(N.gangExpandAllButton),N.gangManagementSubpage.appendChild(N.gangCollapseAllButton),N.gangManagementSubpage.appendChild(N.gangMemberFilter),N.gangManagementSubpage.appendChild(N.gangManageEquipmentButton),N.gangMemberList=Object(d.createElement)("ul",{id:"gang-member-list"}),this.displayGangMemberList(),N.gangManagementSubpage.appendChild(N.gangMemberList),N.gangTerritorySubpage=Object(d.createElement)("div",{id:"gang-territory-subpage",display:"none"}),N.gangTerritoryDescText=Object(d.createElement)("p",{width:"70%",innerHTML:"This page shows how much territory your Gang controls. This statistic is listed as a percentage, which represents how much of the total territory you control.

    Every ~20 seconds, your gang has a chance to 'clash' with other gangs. Your chance to win a clash depends on your gang's power, which is listed in the display below. Your gang's power slowly accumulates over time. The accumulation rate is determined by the stats of all Gang members you have assigned to the 'Territory Warfare' task. Gang members that are not assigned to this task do not contribute to your gang's power. Your gang also loses a small amount of power whenever you lose a clash

    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.

    "}),N.gangTerritorySubpage.appendChild(N.gangTerritoryDescText),N.gangTerritoryWarfareCheckbox=Object(d.createElement)("input",{display:"inline-block",id:"gang-management-territory-warfare-checkbox",changeListener:()=>{this.territoryWarfareEngaged=N.gangTerritoryWarfareCheckbox.checked},margin:"2px",type:"checkbox"}),N.gangTerritoryWarfareCheckbox.checked=this.territoryWarfareEngaged,N.gangTerritoryWarfareCheckboxLabel=Object(d.createElement)("label",{color:"white",display:"inline-block",for:"gang-management-territory-warfare-checkbox",innerText:"Engage in Territory Warfare",tooltip:"Engaging in Territory Warfare sets your clash chance to 100%. Disengaging will cause your clash chance to gradually decrease until it reaches 0%"}),N.gangTerritorySubpage.appendChild(N.gangTerritoryWarfareCheckbox),N.gangTerritorySubpage.appendChild(N.gangTerritoryWarfareCheckboxLabel),N.gangTerritorySubpage.appendChild(Object(d.createElement)("br")),N.gangTerritoryWarfareClashChance=Object(d.createElement)("p",{display:"inline-block"}),N.gangTerritorySubpage.appendChild(N.gangTerritoryWarfareClashChance),N.gangTerritorySubpage.appendChild(Object(d.createElement)("div",{class:"help-tip",display:"inline-block",innerText:"?",clickListener:()=>{Object(u.dialogBoxCreate)("This percentage represents the chance you have of 'clashing' with with another gang. If you do not wish to gain/lose territory, then keep this percentage at 0% by not engaging in territory warfare.")}})),N.gangTerritoryDeathNotifyCheckbox=Object(d.createElement)("input",{display:"inline-block",id:"gang-management-notify-member-death-checkbox",changeListener:()=>{this.notifyMemberDeath=N.gangTerritoryDeathNotifyCheckbox.checked},margin:"2px",type:"checkbox"}),N.gangTerritoryDeathNotifyCheckbox.checked=this.notifyMemberDeath,N.gangTerritoryDeathNotifyCheckboxLabel=Object(d.createElement)("label",{color:"white",display:"inline-block",for:"gang-management-notify-member-death-checkbox",innerText:"Notify about Gang Member Deaths",tooltip:"If this is enabled, then you will receive a pop-up notifying you whenever one of your Gang Members dies in a territory clash."}),N.gangTerritorySubpage.appendChild(Object(d.createElement)("br")),N.gangTerritorySubpage.appendChild(N.gangTerritoryDeathNotifyCheckbox),N.gangTerritorySubpage.appendChild(N.gangTerritoryDeathNotifyCheckboxLabel),N.gangTerritorySubpage.appendChild(Object(d.createElement)("br"));var a=Object(d.createElement)("fieldset",{display:"block",margin:"6px",width:"50%"});N.gangTerritoryInfoText=Object(d.createElement)("p"),a.appendChild(N.gangTerritoryInfoText),N.gangTerritorySubpage.appendChild(a),N.gangContainer.appendChild(N.gangTerritorySubpage),N.gangContainer.appendChild(N.gangManagementSubpage),document.getElementById("entire-game-container").appendChild(N.gangContainer)}N.gangContainer.style.display="block",this.updateGangContent()},M.prototype.displayGangMemberList=function(){Object(v.removeChildrenFromElement)(N.gangMemberList),N.gangMemberPanels={};const e=this.members,t=N.gangMemberFilter.value.toString();for(var n=0;n-1||e[n].task.indexOf(t)>-1)&&this.createGangMemberDisplayElement(e[n])},M.prototype.updateGangContent=function(){if(N.gangContentCreated)if(N.gangMemberUpgradeBoxOpened&&(N.gangMemberUpgradeBoxDiscount.childNodes[0].nodeValue="Discount: -"+c.numeralWrapper.format(1-1/this.getDiscount(),"0.00%")),"block"===N.gangTerritorySubpage.style.display){N.gangTerritoryWarfareClashChance.innerText=`Territory Clash Chance: ${c.numeralWrapper.format(this.territoryClashChance,"0.000%")}`,N.gangTerritoryWarfareCheckbox.checked=this.territoryWarfareEngaged,N.gangTerritoryInfoText.innerHTML="";const e=T[this.facName].power;for(const t in T)if(T.hasOwnProperty(t)){const n=T[t];let a,i=100*n.territory;if(a=i<=0?Object(f.formatNumber)(0,2):i>=100?Object(f.formatNumber)(100,2):Object(f.formatNumber)(i,2),t===this.facName){let e=`${t}
    Power: ${Object(f.formatNumber)(n.power,6)}
    `;e+=`Territory: ${a}%

    `,N.gangTerritoryInfoText.innerHTML+=e}else{const i=e/(n.power+e);let r=`${t}
    Power: ${Object(f.formatNumber)(n.power,6)}
    `;r+=`Territory: ${a}%
    `,r+=`Chance to win clash with this gang: ${c.numeralWrapper.format(i,"0.000%")}

    `,N.gangTerritoryInfoText.innerHTML+=r}}}else{if(N.gangInfo instanceof Element){var e,t=s.Factions[this.facName];e=t instanceof o.Faction?t.playerReputation:"ERROR",Object(v.removeChildrenFromElement)(N.gangInfo),N.gangInfo.appendChild(Object(d.createElement)("p",{display:"inline-block",innerText:"Respect: "+Object(f.formatNumber)(this.respect,6)+" ("+Object(f.formatNumber)(5*this.respectGainRate,6)+" / sec)",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."})),N.gangInfo.appendChild(Object(d.createElement)("br")),N.gangInfo.appendChild(Object(d.createElement)("p",{display:"inline-block",innerText:"Wanted Level: "+Object(f.formatNumber)(this.wanted,6)+" ("+Object(f.formatNumber)(5*this.wantedGainRate,6)+" / 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."})),N.gangInfo.appendChild(Object(d.createElement)("br"));var n=this.getWantedPenalty();n=100*(1-n),N.gangInfo.appendChild(Object(d.createElement)("p",{display:"inline-block",innerText:`Wanted Level Penalty: -${Object(f.formatNumber)(n,2)}%`,tooltip:"Penalty for respect and money gain rates due to Wanted Level"})),N.gangInfo.appendChild(Object(d.createElement)("br")),N.gangInfo.appendChild(Object(d.createElement)("p",{display:"inline-block",innerText:`Money gain rate: ${c.numeralWrapper.format(5*this.moneyGainRate,"$0.000a")} / sec`})),N.gangInfo.appendChild(Object(d.createElement)("br"));var a=100*T[this.facName].territory;let i;i=a<=0?Object(f.formatNumber)(0,2):a>=100?Object(f.formatNumber)(100,2):Object(f.formatNumber)(a,2),N.gangInfo.appendChild(Object(d.createElement)("p",{display:"inline-block",innerText:`Territory: ${Object(f.formatNumber)(i,3)}%`,tooltip:"The percentage of total territory your Gang controls"})),N.gangInfo.appendChild(Object(d.createElement)("br")),N.gangInfo.appendChild(Object(d.createElement)("p",{display:"inline-block",innerText:"Faction reputation: "+Object(f.formatNumber)(e,3)})),N.gangInfo.appendChild(Object(d.createElement)("br"));const l=1e3/r.Engine._idleSpeed;N.gangInfo.appendChild(Object(d.createElement)("p",{innerText:`Bonus time(s): ${this.storedCycles/l}`,display:"inline-block",tooltip:"You gain bonus time while offline or when the game is inactive (e.g. when the tab is throttled by the browser). Bonus time makes the Gang mechanic progress faster, up to 5x the normal speed"})),N.gangInfo.appendChild(Object(d.createElement)("br"))}else console.error("gang-info DOM element DNE");const i=this.members.length,l=this.getRespectNeededToRecruitMember(),u=N.gangRecruitMemberButton;i>=30?(u.className="a-link-button-inactive",N.gangRecruitRequirementText.style.display="inline-block",N.gangRecruitRequirementText.innerHTML="You have reached the maximum amount of gang members"):this.canRecruitMember()?(u.className="a-link-button",N.gangRecruitRequirementText.style.display="none"):(u.className="a-link-button-inactive",N.gangRecruitRequirementText.style.display="inline-block",N.gangRecruitRequirementText.innerHTML=`${Object(f.formatNumber)(l,2)} respect needed to recruit next member`);for(let e=0;e")});N.gangMemberPanels[t].statsDiv=r;const o=Object(d.createElement)("pre",{display:"inline",id:t+"gang-member-stats-text"}),s=Object(d.createElement)("br"),l=Object(d.createElement)("button",{class:"accordion-button",innerText:"Ascend",clickListener:()=>{const t=`gang-management-ascend-member ${e.name}`,n=e.getAscensionResults(),a=Object(d.createElement)("pre",{innerText:["Are you sure you want to ascend this member? (S)he will lose all of","his non-Augmentation upgrades and his/her stats will reset back to 1.","",`Furthermore, your gang will lose ${c.numeralWrapper.format(e.earnedRespect,"0.000000")} respect`,"","In return, (s)he will gain the following permanent boost to stat multipliers:\n",`Hacking: +${c.numeralWrapper.format(n.hack,"0.00%")}`,`Strength: +${c.numeralWrapper.format(n.str,"0.00%")}`,`Defense: +${c.numeralWrapper.format(n.def,"0.00%")}`,`Dexterity: +${c.numeralWrapper.format(n.dex,"0.00%")}`,`Agility: +${c.numeralWrapper.format(n.agi,"0.00%")}`,`Charisma: +${c.numeralWrapper.format(n.cha,"0.00%")}`].join("\n")}),i=Object(d.createElement)("button",{class:"std-button",clickListener:()=>(this.ascendMember(e),this.updateGangMemberDisplayElement(e),Object(k.removeElementById)(t),!1),innerText:"Ascend"}),r=Object(d.createElement)("button",{class:"std-button",clickListener:()=>(Object(k.removeElementById)(t),!1),innerText:"Cancel"});Object(g.createPopup)(t,[a,i,r])}}),p=Object(d.createElement)("div",{class:"help-tip",clickListener:()=>{Object(u.dialogBoxCreate)(["Ascending a Gang Member resets the member's progress and stats in exchange","for a permanent boost to their stat multipliers.","

    The additional stat multiplier that the Gang Member gains upon ascension","is based on the amount of multipliers the member has from non-Augmentation Equipment.","

    Upon ascension, the member will lose all of its non-Augmentation Equipment and your","gang will lose respect equal to the total respect earned by the member."].join(" "))},innerText:"?",marginTop:"5px"});r.appendChild(o),r.appendChild(s),r.appendChild(l),r.appendChild(p);const m=Object(d.createElement)("div",{class:"gang-member-info-div",id:t+"gang-member-task"}),_=Object(d.createElement)("select",{class:"dropdown",id:t+"gang-member-task-selector"});let f=this.getAllTaskNames();f.unshift("---");for(var y=0;y{var t=_.options[_.selectedIndex].text;e.assignToTask(t),this.setGangMemberTaskDescription(e,t),this.updateGangContent()}),w.hasOwnProperty(e.task)){var v=e.task,E=0;for(let e=0;e"))}var i=document.getElementById(t+"gang-member-gain-info");i&&(i.innerHTML=[`Money: $ ${Object(f.formatNumber)(5*e.calculateMoneyGain(this),2)} / sec`,`Respect: ${Object(f.formatNumber)(5*e.calculateRespectGain(this),6)} / sec`,`Wanted Level: ${Object(f.formatNumber)(5*e.calculateWantedLevelGain(this),6)} / sec`,`Total Respect Earned: ${Object(f.formatNumber)(e.earnedRespect,6)}`].join("
    "));const r=document.getElementById(t+"gang-member-task-selector");if(r){let t=this.getAllTaskNames();if(t.unshift("---"),w.hasOwnProperty(e.task)){const n=e.task;let a=0;for(let e=0;e7===e.n))))throw Object(r.d)(e,n)}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getElementById=function(e){const t=document.getElementById(e);if(null===t)throw new Error(`Unable to find element with id '${e}'`);return t}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const a=n(1),i=n(150),r=n(17);class o{constructor(e=""){this.alreadyInvited=!1,this.augmentations=[],this.favor=0,this.isBanned=!1,this.isMember=!1,this.name="",this.playerReputation=0,this.rolloverRep=0,this.name=e}static fromJSON(e){return r.Generic_fromJSON(o,e.data)}getInfo(){const e=i.FactionInfos[this.name];if(null==e)throw new Error(`Missing faction from FactionInfos: ${this.name} this probably means the faction got corrupted somehow`);return e}gainFavor(){null==this.favor&&(this.favor=0),null==this.rolloverRep&&(this.rolloverRep=0);const e=this.getFavorGain();2===e.length?(this.favor+=e[0],this.rolloverRep=e[1]):console.error("Invalid result from getFavorGain() function")}getFavorGain(){null==this.favor&&(this.favor=0),null==this.rolloverRep&&(this.rolloverRep=0);var e=0,t=this.playerReputation+this.rolloverRep;let n=a.CONSTANTS.FactionReputationToFavorBase*Math.pow(a.CONSTANTS.FactionReputationToFavorMult,this.favor);for(;t>0&&t>=n;)++e,t-=n,n*=a.CONSTANTS.FactionReputationToFavorMult;return[e,t]}addAllAugmentations(e){this.augmentations.length=0;for(const t in e)e.hasOwnProperty(t)&&this.augmentations.push(t)}toJSON(){return r.Generic_toJSON("Faction",this)}}t.Faction=o,r.Reviver.constructors.Faction=o},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.arrayToString=function(e){const t=[];for(let n=0;n["+(_Fconf_FconfSettings__WEBPACK_IMPORTED_MODULE_8__.FconfSettings.ENABLE_TIMESTAMPS?Object(_utils_helpers_getTimestamp__WEBPACK_IMPORTED_MODULE_35__.getTimestamp)()+" ":"")+_Player__WEBPACK_IMPORTED_MODULE_16__.a.getCurrentServer().hostname+" ~]> "+n),n.length>0&&(Terminal.resetTerminalInput(),Terminal.executeCommands(n))}if(e.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_31__.KEY.C&&e.ctrlKey&&(_engine__WEBPACK_IMPORTED_MODULE_6__.Engine._actionInProgress?(Object(_ui_postToTerminal__WEBPACK_IMPORTED_MODULE_38__.post)("Cancelling..."),_engine__WEBPACK_IMPORTED_MODULE_6__.Engine._actionInProgress=!1,Terminal.finishAction(!0)):_Fconf_FconfSettings__WEBPACK_IMPORTED_MODULE_8__.FconfSettings.ENABLE_BASH_HOTKEYS&&Terminal.resetTerminalInput()),e.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_31__.KEY.L&&e.ctrlKey&&(e.preventDefault(),Terminal.executeCommand("clear")),e.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_31__.KEY.UPARROW||_Fconf_FconfSettings__WEBPACK_IMPORTED_MODULE_8__.FconfSettings.ENABLE_BASH_HOTKEYS&&e.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_31__.KEY.P&&e.ctrlKey){if(_Fconf_FconfSettings__WEBPACK_IMPORTED_MODULE_8__.FconfSettings.ENABLE_BASH_HOTKEYS&&e.preventDefault(),null==t)return;var a=Terminal.commandHistoryIndex;if(0==(r=Terminal.commandHistory.length))return;(a<0||a>r)&&(Terminal.commandHistoryIndex=r),0!=a&&--Terminal.commandHistoryIndex;var i=Terminal.commandHistory[Terminal.commandHistoryIndex];t.value=i,Object(_utils_SetTimeoutRef__WEBPACK_IMPORTED_MODULE_27__.setTimeoutRef)(function(){t.selectionStart=t.selectionEnd=1e4},0)}if(e.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_31__.KEY.DOWNARROW||_Fconf_FconfSettings__WEBPACK_IMPORTED_MODULE_8__.FconfSettings.ENABLE_BASH_HOTKEYS&&e.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_31__.KEY.M&&e.ctrlKey){if(_Fconf_FconfSettings__WEBPACK_IMPORTED_MODULE_8__.FconfSettings.ENABLE_BASH_HOTKEYS&&e.preventDefault(),null==t)return;var r;a=Terminal.commandHistoryIndex;if(0==(r=Terminal.commandHistory.length))return;if((a<0||a>r)&&(Terminal.commandHistoryIndex=r),a==r||a==r-1)Terminal.commandHistoryIndex=r,t.value="";else{++Terminal.commandHistoryIndex;i=Terminal.commandHistory[Terminal.commandHistoryIndex];t.value=i}}if(e.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_31__.KEY.TAB){if(e.preventDefault(),null==t)return;var o=t.value;if(""==o)return;const a=o.lastIndexOf(";");-1!==a&&(o=o.slice(a+1));var s=(o=(o=o.trim()).replace(/\s\s+/g," ")).split(" "),l=s.length-2;l<-1&&(l=0);var c=determineAllPossibilitiesForTabCompletion(o,l);if(0==c.length)return;var u="";n="";if(0==s.length)return;1==s.length?n=s[0]:2==s.length?(n=s[0],u=s[1]):3==s.length?(n=s[0]+" "+s[1],u=s[2]):(u=s.pop(),n=s.join(" ")),tabCompletion(n,u,c),t.focus()}_Fconf_FconfSettings__WEBPACK_IMPORTED_MODULE_8__.FconfSettings.ENABLE_BASH_HOTKEYS&&(e.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_31__.KEY.A&&e.ctrlKey&&(e.preventDefault(),Terminal.moveTextCursor("home")),e.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_31__.KEY.E&&e.ctrlKey&&(e.preventDefault(),Terminal.moveTextCursor("end")),e.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_31__.KEY.B&&e.ctrlKey&&(e.preventDefault(),Terminal.moveTextCursor("prevchar")),e.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_31__.KEY.B&&e.altKey&&(e.preventDefault(),Terminal.moveTextCursor("prevword")),e.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_31__.KEY.F&&e.ctrlKey&&(e.preventDefault(),Terminal.moveTextCursor("nextchar")),e.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_31__.KEY.F&&e.altKey&&(e.preventDefault(),Terminal.moveTextCursor("nextword")),e.keyCode!==_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_31__.KEY.H&&e.keyCode!==_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_31__.KEY.D||!e.ctrlKey||(Terminal.modifyInput("backspace"),e.preventDefault()))}});let terminalCtrlPressed=!1,shiftKeyPressed=!1;function tabCompletion(e,t,n,a=0){if(n.constructor!==Array)return;if(!Object(_utils_StringHelperFunctions__WEBPACK_IMPORTED_MODULE_28__.containsAllStrings)(n))return;if(""==t)for(var i=n.length-1;i>=0;--i)n[i].toLowerCase().startsWith(e.toLowerCase())||n.splice(i,1);else for(i=n.length-1;i>=0;--i)n[i].toLowerCase().startsWith(t.toLowerCase())||n.splice(i,1);const r=document.getElementById("terminal-input-text-box");if(null==r)return void console.warn("Couldn't find terminal input DOM element (id=terminal-input-text-box) when trying to autocomplete");const o=r.value.lastIndexOf(";");var s="";if(0!=n.length)if(1==n.length)s=""==t?n[0]+" ":e+" "+n[0],r.value=-1===o?s:r.value.slice(0,o+1)+" "+s,r.focus();else{var l=Object(_utils_StringHelperFunctions__WEBPACK_IMPORTED_MODULE_28__.longestCommonStart)(n),c="";for(i=0;i "+e),Object(_ui_postToTerminal__WEBPACK_IMPORTED_MODULE_38__.post)(c)):(r.value=-1===o?l:r.value.slice(0,o+1)+" "+l,r.focus()):l==t?(Object(_ui_postToTerminal__WEBPACK_IMPORTED_MODULE_38__.post)("> "+e+" "+t),Object(_ui_postToTerminal__WEBPACK_IMPORTED_MODULE_38__.post)(c)):(r.value=-1==o?e+" "+l:r.value.slice(0,o+1)+" "+e+" "+l,r.focus())}}function determineAllPossibilitiesForTabCompletion(e,t=0){var n=[];n=n.concat(Object.keys(_Alias__WEBPACK_IMPORTED_MODULE_0__.b));var a=_Player__WEBPACK_IMPORTED_MODULE_16__.a.getCurrentServer();if((e=e.toLowerCase()).startsWith("./")&&-1==t){for(var i=0;i["+_Player__WEBPACK_IMPORTED_MODULE_16__.a.getCurrentServer().hostname+' ~]$
    ",v.noCloneChecked=!!e.cloneNode(!0).lastChild.defaultValue}();var we=s.documentElement,xe=/^key/,Ce=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,ke=/^([^.]*)(?:\.(.+)|)/;function Ae(){return!0}function Ee(){return!1}function _e(){try{return s.activeElement}catch(e){}}function Se(e,t,n,r,i,o){var s,a;if("object"==typeof t){for(a in"string"!=typeof n&&(r=r||n,n=void 0),t)Se(e,a,n,r,t[a],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Ee;else if(!i)return e;return 1===o&&(s=i,(i=function(e){return k().off(e),s.apply(this,arguments)}).guid=s.guid||(s.guid=k.guid++)),e.each(function(){k.event.add(this,t,i,r,n)})}k.event={global:{},add:function(e,t,n,r,i){var o,s,a,l,u,c,h,d,f,p,g,m=J.get(e);if(m)for(n.handler&&(n=(o=n).handler,i=o.selector),i&&k.find.matchesSelector(we,i),n.guid||(n.guid=k.guid++),(l=m.events)||(l=m.events={}),(s=m.handle)||(s=m.handle=function(t){return void 0!==k&&k.event.triggered!==t.type?k.event.dispatch.apply(e,arguments):void 0}),u=(t=(t||"").match(I)||[""]).length;u--;)f=g=(a=ke.exec(t[u])||[])[1],p=(a[2]||"").split(".").sort(),f&&(h=k.event.special[f]||{},f=(i?h.delegateType:h.bindType)||f,h=k.event.special[f]||{},c=k.extend({type:f,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&k.expr.match.needsContext.test(i),namespace:p.join(".")},o),(d=l[f])||((d=l[f]=[]).delegateCount=0,h.setup&&!1!==h.setup.call(e,r,p,s)||e.addEventListener&&e.addEventListener(f,s)),h.add&&(h.add.call(e,c),c.handler.guid||(c.handler.guid=n.guid)),i?d.splice(d.delegateCount++,0,c):d.push(c),k.event.global[f]=!0)},remove:function(e,t,n,r,i){var o,s,a,l,u,c,h,d,f,p,g,m=J.hasData(e)&&J.get(e);if(m&&(l=m.events)){for(u=(t=(t||"").match(I)||[""]).length;u--;)if(f=g=(a=ke.exec(t[u])||[])[1],p=(a[2]||"").split(".").sort(),f){for(h=k.event.special[f]||{},d=l[f=(r?h.delegateType:h.bindType)||f]||[],a=a[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),s=o=d.length;o--;)c=d[o],!i&&g!==c.origType||n&&n.guid!==c.guid||a&&!a.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(d.splice(o,1),c.selector&&d.delegateCount--,h.remove&&h.remove.call(e,c));s&&!d.length&&(h.teardown&&!1!==h.teardown.call(e,p,m.handle)||k.removeEvent(e,f,m.handle),delete l[f])}else for(f in l)k.event.remove(e,f+t[u],n,r,!0);k.isEmptyObject(l)&&J.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,s,a=k.event.fix(e),l=new Array(arguments.length),u=(J.get(this,"events")||{})[a.type]||[],c=k.event.special[a.type]||{};for(l[0]=a,t=1;t=1))for(;u!==this;u=u.parentNode||this)if(1===u.nodeType&&("click"!==e.type||!0!==u.disabled)){for(o=[],s={},n=0;n-1:k.find(i,this,null,[u]).length),s[i]&&o.push(r);o.length&&a.push({elem:u,handlers:o})}return u=this,l\x20\t\r\n\f]*)[^>]*)\/>/gi,De=/\s*$/g;function Le(e,t){return T(e,"table")&&T(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Me(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Pe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Oe(e,t){var n,r,i,o,s,a,l,u;if(1===t.nodeType){if(J.hasData(e)&&(o=J.access(e),s=J.set(t,o),u=o.events))for(i in delete s.handle,s.events={},u)for(n=0,r=u[i].length;n1&&"string"==typeof p&&!v.checkClone&&Te.test(p))return e.each(function(i){var o=e.eq(i);g&&(t[0]=p.call(this,i,o.html())),je(o,t,n,r)});if(d&&(o=(i=be(t,e[0].ownerDocument,!1,e,r)).firstChild,1===i.childNodes.length&&(i=o),o||r)){for(a=(s=k.map(me(i,"script"),Me)).length;h")},clone:function(e,t,n){var r,i,o,s,a=e.cloneNode(!0),l=k.contains(e.ownerDocument,e);if(!(v.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(s=me(a),r=0,i=(o=me(e)).length;r0&&ve(s,!l&&me(e,"script")),a},cleanData:function(e){for(var t,n,r,i=k.event.special,o=0;void 0!==(n=e[o]);o++)if(X(n)){if(t=n[J.expando]){if(t.events)for(r in t.events)i[r]?k.event.remove(n,r):k.removeEvent(n,r,t.handle);n[J.expando]=void 0}n[Q.expando]&&(n[Q.expando]=void 0)}}}),k.fn.extend({detach:function(e){return Ie(this,e,!0)},remove:function(e){return Ie(this,e)},text:function(e){return V(this,function(e){return void 0===e?k.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return je(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||Le(this,e).appendChild(e)})},prepend:function(){return je(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Le(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return je(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return je(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(k.cleanData(me(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return k.clone(this,e,t)})},html:function(e){return V(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!De.test(e)&&!ge[(fe.exec(e)||["",""])[1].toLowerCase()]){e=k.htmlPrefilter(e);try{for(;n=0&&(l+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-l-a-.5))),l}function Qe(e,t,n){var r=$e(e),i=ze(e,t,r),o="border-box"===k.css(e,"boxSizing",!1,r),s=o;if(Ne.test(i)){if(!n)return i;i="auto"}return s=s&&(v.boxSizingReliable()||i===e.style[t]),("auto"===i||!parseFloat(i)&&"inline"===k.css(e,"display",!1,r))&&(i=e["offset"+t[0].toUpperCase()+t.slice(1)],s=!0),(i=parseFloat(i)||0)+Je(e,t,n||(o?"border":"content"),s,r,i)+"px"}function et(e,t,n,r,i){return new et.prototype.init(e,t,n,r,i)}k.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=ze(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,s,a=Y(t),l=Ve.test(t),u=e.style;if(l||(t=Xe(a)),s=k.cssHooks[t]||k.cssHooks[a],void 0===n)return s&&"get"in s&&void 0!==(i=s.get(e,!1,r))?i:u[t];"string"===(o=typeof n)&&(i=ie.exec(n))&&i[1]&&(n=le(e,t,i),o="number"),null!=n&&n==n&&("number"===o&&(n+=i&&i[3]||(k.cssNumber[a]?"":"px")),v.clearCloneStyle||""!==n||0!==t.indexOf("background")||(u[t]="inherit"),s&&"set"in s&&void 0===(n=s.set(e,n,r))||(l?u.setProperty(t,n):u[t]=n))}},css:function(e,t,n,r){var i,o,s,a=Y(t);return Ve.test(t)||(t=Xe(a)),(s=k.cssHooks[t]||k.cssHooks[a])&&"get"in s&&(i=s.get(e,!0,n)),void 0===i&&(i=ze(e,t,r)),"normal"===i&&t in Ke&&(i=Ke[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),k.each(["height","width"],function(e,t){k.cssHooks[t]={get:function(e,n,r){if(n)return!Ue.test(k.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?Qe(e,t,r):ae(e,Ge,function(){return Qe(e,t,r)})},set:function(e,n,r){var i,o=$e(e),s="border-box"===k.css(e,"boxSizing",!1,o),a=r&&Je(e,t,r,s,o);return s&&v.scrollboxSize()===o.position&&(a-=Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-parseFloat(o[t])-Je(e,t,"border",!1,o)-.5)),a&&(i=ie.exec(n))&&"px"!==(i[3]||"px")&&(e.style[t]=n,n=k.css(e,t)),Ze(0,n,a)}}}),k.cssHooks.marginLeft=He(v.reliableMarginLeft,function(e,t){if(t)return(parseFloat(ze(e,"marginLeft"))||e.getBoundingClientRect().left-ae(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),k.each({margin:"",padding:"",border:"Width"},function(e,t){k.cssHooks[e+t]={expand:function(n){for(var r=0,i={},o="string"==typeof n?n.split(" "):[n];r<4;r++)i[e+oe[r]+t]=o[r]||o[r-2]||o[0];return i}},"margin"!==e&&(k.cssHooks[e+t].set=Ze)}),k.fn.extend({css:function(e,t){return V(this,function(e,t,n){var r,i,o={},s=0;if(Array.isArray(t)){for(r=$e(e),i=t.length;s1)}}),k.Tween=et,et.prototype={constructor:et,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||k.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(k.cssNumber[n]?"":"px")},cur:function(){var e=et.propHooks[this.prop];return e&&e.get?e.get(this):et.propHooks._default.get(this)},run:function(e){var t,n=et.propHooks[this.prop];return this.options.duration?this.pos=t=k.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):et.propHooks._default.set(this),this}},et.prototype.init.prototype=et.prototype,et.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=k.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){k.fx.step[e.prop]?k.fx.step[e.prop](e):1!==e.elem.nodeType||null==e.elem.style[k.cssProps[e.prop]]&&!k.cssHooks[e.prop]?e.elem[e.prop]=e.now:k.style(e.elem,e.prop,e.now+e.unit)}}},et.propHooks.scrollTop=et.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},k.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},k.fx=et.prototype.init,k.fx.step={};var tt,nt,rt=/^(?:toggle|show|hide)$/,it=/queueHooks$/;function ot(){nt&&(!1===s.hidden&&n.requestAnimationFrame?n.requestAnimationFrame(ot):n.setTimeout(ot,k.fx.interval),k.fx.tick())}function st(){return n.setTimeout(function(){tt=void 0}),tt=Date.now()}function at(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=oe[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function lt(e,t,n){for(var r,i=(ut.tweeners[t]||[]).concat(ut.tweeners["*"]),o=0,s=i.length;o1)},removeAttr:function(e){return this.each(function(){k.removeAttr(this,e)})}}),k.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return void 0===e.getAttribute?k.prop(e,t,n):(1===o&&k.isXMLDoc(e)||(i=k.attrHooks[t.toLowerCase()]||(k.expr.match.bool.test(t)?ct:void 0)),void 0!==n?null===n?void k.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=k.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!v.radioValue&&"radio"===t&&T(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(I);if(i&&1===e.nodeType)for(;n=i[r++];)e.removeAttribute(n)}}),ct={set:function(e,t,n){return!1===t?k.removeAttr(e,n):e.setAttribute(n,n),n}},k.each(k.expr.match.bool.source.match(/\w+/g),function(e,t){var n=ht[t]||k.find.attr;ht[t]=function(e,t,r){var i,o,s=t.toLowerCase();return r||(o=ht[s],ht[s]=i,i=null!=n(e,t,r)?s:null,ht[s]=o),i}});var dt=/^(?:input|select|textarea|button)$/i,ft=/^(?:a|area)$/i;function pt(e){return(e.match(I)||[]).join(" ")}function gt(e){return e.getAttribute&&e.getAttribute("class")||""}function mt(e){return Array.isArray(e)?e:"string"==typeof e&&e.match(I)||[]}k.fn.extend({prop:function(e,t){return V(this,k.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[k.propFix[e]||e]})}}),k.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&k.isXMLDoc(e)||(t=k.propFix[t]||t,i=k.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=k.find.attr(e,"tabindex");return t?parseInt(t,10):dt.test(e.nodeName)||ft.test(e.nodeName)&&e.href?0:-1}}},propFix:{for:"htmlFor",class:"className"}}),v.optSelected||(k.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),k.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){k.propFix[this.toLowerCase()]=this}),k.fn.extend({addClass:function(e){var t,n,r,i,o,s,a,l=0;if(y(e))return this.each(function(t){k(this).addClass(e.call(this,t,gt(this)))});if((t=mt(e)).length)for(;n=this[l++];)if(i=gt(n),r=1===n.nodeType&&" "+pt(i)+" "){for(s=0;o=t[s++];)r.indexOf(" "+o+" ")<0&&(r+=o+" ");i!==(a=pt(r))&&n.setAttribute("class",a)}return this},removeClass:function(e){var t,n,r,i,o,s,a,l=0;if(y(e))return this.each(function(t){k(this).removeClass(e.call(this,t,gt(this)))});if(!arguments.length)return this.attr("class","");if((t=mt(e)).length)for(;n=this[l++];)if(i=gt(n),r=1===n.nodeType&&" "+pt(i)+" "){for(s=0;o=t[s++];)for(;r.indexOf(" "+o+" ")>-1;)r=r.replace(" "+o+" "," ");i!==(a=pt(r))&&n.setAttribute("class",a)}return this},toggleClass:function(e,t){var n=typeof e,r="string"===n||Array.isArray(e);return"boolean"==typeof t&&r?t?this.addClass(e):this.removeClass(e):y(e)?this.each(function(n){k(this).toggleClass(e.call(this,n,gt(this),t),t)}):this.each(function(){var t,i,o,s;if(r)for(i=0,o=k(this),s=mt(e);t=s[i++];)o.hasClass(t)?o.removeClass(t):o.addClass(t);else void 0!==e&&"boolean"!==n||((t=gt(this))&&J.set(this,"__className__",t),this.setAttribute&&this.setAttribute("class",t||!1===e?"":J.get(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;for(t=" "+e+" ";n=this[r++];)if(1===n.nodeType&&(" "+pt(gt(n))+" ").indexOf(t)>-1)return!0;return!1}});var vt=/\r/g;k.fn.extend({val:function(e){var t,n,r,i=this[0];return arguments.length?(r=y(e),this.each(function(n){var i;1===this.nodeType&&(null==(i=r?e.call(this,n,k(this).val()):e)?i="":"number"==typeof i?i+="":Array.isArray(i)&&(i=k.map(i,function(e){return null==e?"":e+""})),(t=k.valHooks[this.type]||k.valHooks[this.nodeName.toLowerCase()])&&"set"in t&&void 0!==t.set(this,i,"value")||(this.value=i))})):i?(t=k.valHooks[i.type]||k.valHooks[i.nodeName.toLowerCase()])&&"get"in t&&void 0!==(n=t.get(i,"value"))?n:"string"==typeof(n=i.value)?n.replace(vt,""):null==n?"":n:void 0}}),k.extend({valHooks:{option:{get:function(e){var t=k.find.attr(e,"value");return null!=t?t:pt(k.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,s="select-one"===e.type,a=s?null:[],l=s?o+1:i.length;for(r=o<0?l:s?o:0;r-1)&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),k.each(["radio","checkbox"],function(){k.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=k.inArray(k(e).val(),t)>-1}},v.checkOn||(k.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),v.focusin="onfocusin"in n;var yt=/^(?:focusinfocus|focusoutblur)$/,bt=function(e){e.stopPropagation()};k.extend(k.event,{trigger:function(e,t,r,i){var o,a,l,u,c,h,d,f,g=[r||s],m=p.call(e,"type")?e.type:e,v=p.call(e,"namespace")?e.namespace.split("."):[];if(a=f=l=r=r||s,3!==r.nodeType&&8!==r.nodeType&&!yt.test(m+k.event.triggered)&&(m.indexOf(".")>-1&&(m=(v=m.split(".")).shift(),v.sort()),c=m.indexOf(":")<0&&"on"+m,(e=e[k.expando]?e:new k.Event(m,"object"==typeof e&&e)).isTrigger=i?2:3,e.namespace=v.join("."),e.rnamespace=e.namespace?new RegExp("(^|\\.)"+v.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=r),t=null==t?[e]:k.makeArray(t,[e]),d=k.event.special[m]||{},i||!d.trigger||!1!==d.trigger.apply(r,t))){if(!i&&!d.noBubble&&!b(r)){for(u=d.delegateType||m,yt.test(u+m)||(a=a.parentNode);a;a=a.parentNode)g.push(a),l=a;l===(r.ownerDocument||s)&&g.push(l.defaultView||l.parentWindow||n)}for(o=0;(a=g[o++])&&!e.isPropagationStopped();)f=a,e.type=o>1?u:d.bindType||m,(h=(J.get(a,"events")||{})[e.type]&&J.get(a,"handle"))&&h.apply(a,t),(h=c&&a[c])&&h.apply&&X(a)&&(e.result=h.apply(a,t),!1===e.result&&e.preventDefault());return e.type=m,i||e.isDefaultPrevented()||d._default&&!1!==d._default.apply(g.pop(),t)||!X(r)||c&&y(r[m])&&!b(r)&&((l=r[c])&&(r[c]=null),k.event.triggered=m,e.isPropagationStopped()&&f.addEventListener(m,bt),r[m](),e.isPropagationStopped()&&f.removeEventListener(m,bt),k.event.triggered=void 0,l&&(r[c]=l)),e.result}},simulate:function(e,t,n){var r=k.extend(new k.Event,n,{type:e,isSimulated:!0});k.event.trigger(r,null,t)}}),k.fn.extend({trigger:function(e,t){return this.each(function(){k.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return k.event.trigger(e,t,n,!0)}}),v.focusin||k.each({focus:"focusin",blur:"focusout"},function(e,t){var n=function(e){k.event.simulate(t,e.target,k.event.fix(e))};k.event.special[t]={setup:function(){var r=this.ownerDocument||this,i=J.access(r,t);i||r.addEventListener(e,n,!0),J.access(r,t,(i||0)+1)},teardown:function(){var r=this.ownerDocument||this,i=J.access(r,t)-1;i?J.access(r,t,i):(r.removeEventListener(e,n,!0),J.remove(r,t))}}});var wt=n.location,xt=Date.now(),Ct=/\?/;k.parseXML=function(e){var t;if(!e||"string"!=typeof e)return null;try{t=(new n.DOMParser).parseFromString(e,"text/xml")}catch(e){t=void 0}return t&&!t.getElementsByTagName("parsererror").length||k.error("Invalid XML: "+e),t};var kt=/\[\]$/,At=/\r?\n/g,Et=/^(?:submit|button|image|reset|file)$/i,_t=/^(?:input|select|textarea|keygen)/i;function St(e,t,n,r){var i;if(Array.isArray(t))k.each(t,function(t,i){n||kt.test(e)?r(e,i):St(e+"["+("object"==typeof i&&null!=i?t:"")+"]",i,n,r)});else if(n||"object"!==C(t))r(e,t);else for(i in t)St(e+"["+i+"]",t[i],n,r)}k.param=function(e,t){var n,r=[],i=function(e,t){var n=y(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(Array.isArray(e)||e.jquery&&!k.isPlainObject(e))k.each(e,function(){i(this.name,this.value)});else for(n in e)St(n,e[n],t,i);return r.join("&")},k.fn.extend({serialize:function(){return k.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=k.prop(this,"elements");return e?k.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!k(this).is(":disabled")&&_t.test(this.nodeName)&&!Et.test(e)&&(this.checked||!de.test(e))}).map(function(e,t){var n=k(this).val();return null==n?null:Array.isArray(n)?k.map(n,function(e){return{name:t.name,value:e.replace(At,"\r\n")}}):{name:t.name,value:n.replace(At,"\r\n")}}).get()}});var Ft=/%20/g,Dt=/#.*$/,Tt=/([?&])_=[^&]*/,Bt=/^(.*?):[ \t]*([^\r\n]*)$/gm,Lt=/^(?:GET|HEAD)$/,Mt=/^\/\//,Pt={},Ot={},Rt="*/".concat("*"),jt=s.createElement("a");function It(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(I)||[];if(y(n))for(;r=o[i++];)"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function Nt(e,t,n,r){var i={},o=e===Ot;function s(a){var l;return i[a]=!0,k.each(e[a]||[],function(e,a){var u=a(t,n,r);return"string"!=typeof u||o||i[u]?o?!(l=u):void 0:(t.dataTypes.unshift(u),s(u),!1)}),l}return s(t.dataTypes[0])||!i["*"]&&s("*")}function $t(e,t){var n,r,i=k.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&k.extend(!0,e,r),e}jt.href=wt.href,k.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:wt.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(wt.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Rt,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":k.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?$t($t(e,k.ajaxSettings),t):$t(k.ajaxSettings,e)},ajaxPrefilter:It(Pt),ajaxTransport:It(Ot),ajax:function(e,t){"object"==typeof e&&(t=e,e=void 0),t=t||{};var r,i,o,a,l,u,c,h,d,f,p=k.ajaxSetup({},t),g=p.context||p,m=p.context&&(g.nodeType||g.jquery)?k(g):k.event,v=k.Deferred(),y=k.Callbacks("once memory"),b=p.statusCode||{},w={},x={},C="canceled",A={readyState:0,getResponseHeader:function(e){var t;if(c){if(!a)for(a={};t=Bt.exec(o);)a[t[1].toLowerCase()]=t[2];t=a[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return c?o:null},setRequestHeader:function(e,t){return null==c&&(e=x[e.toLowerCase()]=x[e.toLowerCase()]||e,w[e]=t),this},overrideMimeType:function(e){return null==c&&(p.mimeType=e),this},statusCode:function(e){var t;if(e)if(c)A.always(e[A.status]);else for(t in e)b[t]=[b[t],e[t]];return this},abort:function(e){var t=e||C;return r&&r.abort(t),E(0,t),this}};if(v.promise(A),p.url=((e||p.url||wt.href)+"").replace(Mt,wt.protocol+"//"),p.type=t.method||t.type||p.method||p.type,p.dataTypes=(p.dataType||"*").toLowerCase().match(I)||[""],null==p.crossDomain){u=s.createElement("a");try{u.href=p.url,u.href=u.href,p.crossDomain=jt.protocol+"//"+jt.host!=u.protocol+"//"+u.host}catch(e){p.crossDomain=!0}}if(p.data&&p.processData&&"string"!=typeof p.data&&(p.data=k.param(p.data,p.traditional)),Nt(Pt,p,t,A),c)return A;for(d in(h=k.event&&p.global)&&0==k.active++&&k.event.trigger("ajaxStart"),p.type=p.type.toUpperCase(),p.hasContent=!Lt.test(p.type),i=p.url.replace(Dt,""),p.hasContent?p.data&&p.processData&&0===(p.contentType||"").indexOf("application/x-www-form-urlencoded")&&(p.data=p.data.replace(Ft,"+")):(f=p.url.slice(i.length),p.data&&(p.processData||"string"==typeof p.data)&&(i+=(Ct.test(i)?"&":"?")+p.data,delete p.data),!1===p.cache&&(i=i.replace(Tt,"$1"),f=(Ct.test(i)?"&":"?")+"_="+xt+++f),p.url=i+f),p.ifModified&&(k.lastModified[i]&&A.setRequestHeader("If-Modified-Since",k.lastModified[i]),k.etag[i]&&A.setRequestHeader("If-None-Match",k.etag[i])),(p.data&&p.hasContent&&!1!==p.contentType||t.contentType)&&A.setRequestHeader("Content-Type",p.contentType),A.setRequestHeader("Accept",p.dataTypes[0]&&p.accepts[p.dataTypes[0]]?p.accepts[p.dataTypes[0]]+("*"!==p.dataTypes[0]?", "+Rt+"; q=0.01":""):p.accepts["*"]),p.headers)A.setRequestHeader(d,p.headers[d]);if(p.beforeSend&&(!1===p.beforeSend.call(g,A,p)||c))return A.abort();if(C="abort",y.add(p.complete),A.done(p.success),A.fail(p.error),r=Nt(Ot,p,t,A)){if(A.readyState=1,h&&m.trigger("ajaxSend",[A,p]),c)return A;p.async&&p.timeout>0&&(l=n.setTimeout(function(){A.abort("timeout")},p.timeout));try{c=!1,r.send(w,E)}catch(e){if(c)throw e;E(-1,e)}}else E(-1,"No Transport");function E(e,t,s,a){var u,d,f,w,x,C=t;c||(c=!0,l&&n.clearTimeout(l),r=void 0,o=a||"",A.readyState=e>0?4:0,u=e>=200&&e<300||304===e,s&&(w=function(e,t,n){for(var r,i,o,s,a=e.contents,l=e.dataTypes;"*"===l[0];)l.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in a)if(a[i]&&a[i].test(r)){l.unshift(i);break}if(l[0]in n)o=l[0];else{for(i in n){if(!l[0]||e.converters[i+" "+l[0]]){o=i;break}s||(s=i)}o=o||s}if(o)return o!==l[0]&&l.unshift(o),n[o]}(p,A,s)),w=function(e,t,n,r){var i,o,s,a,l,u={},c=e.dataTypes.slice();if(c[1])for(s in e.converters)u[s.toLowerCase()]=e.converters[s];for(o=c.shift();o;)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!l&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),l=o,o=c.shift())if("*"===o)o=l;else if("*"!==l&&l!==o){if(!(s=u[l+" "+o]||u["* "+o]))for(i in u)if((a=i.split(" "))[1]===o&&(s=u[l+" "+a[0]]||u["* "+a[0]])){!0===s?s=u[i]:!0!==u[i]&&(o=a[0],c.unshift(a[1]));break}if(!0!==s)if(s&&e.throws)t=s(t);else try{t=s(t)}catch(e){return{state:"parsererror",error:s?e:"No conversion from "+l+" to "+o}}}return{state:"success",data:t}}(p,w,A,u),u?(p.ifModified&&((x=A.getResponseHeader("Last-Modified"))&&(k.lastModified[i]=x),(x=A.getResponseHeader("etag"))&&(k.etag[i]=x)),204===e||"HEAD"===p.type?C="nocontent":304===e?C="notmodified":(C=w.state,d=w.data,u=!(f=w.error))):(f=C,!e&&C||(C="error",e<0&&(e=0))),A.status=e,A.statusText=(t||C)+"",u?v.resolveWith(g,[d,C,A]):v.rejectWith(g,[A,C,f]),A.statusCode(b),b=void 0,h&&m.trigger(u?"ajaxSuccess":"ajaxError",[A,p,u?d:f]),y.fireWith(g,[A,C]),h&&(m.trigger("ajaxComplete",[A,p]),--k.active||k.event.trigger("ajaxStop")))}return A},getJSON:function(e,t,n){return k.get(e,t,n,"json")},getScript:function(e,t){return k.get(e,void 0,t,"script")}}),k.each(["get","post"],function(e,t){k[t]=function(e,n,r,i){return y(n)&&(i=i||r,r=n,n=void 0),k.ajax(k.extend({url:e,type:t,dataType:i,data:n,success:r},k.isPlainObject(e)&&e))}}),k._evalUrl=function(e){return k.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,throws:!0})},k.fn.extend({wrapAll:function(e){var t;return this[0]&&(y(e)&&(e=e.call(this[0])),t=k(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){for(var e=this;e.firstElementChild;)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(e){return y(e)?this.each(function(t){k(this).wrapInner(e.call(this,t))}):this.each(function(){var t=k(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=y(e);return this.each(function(n){k(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(e){return this.parent(e).not("body").each(function(){k(this).replaceWith(this.childNodes)}),this}}),k.expr.pseudos.hidden=function(e){return!k.expr.pseudos.visible(e)},k.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},k.ajaxSettings.xhr=function(){try{return new n.XMLHttpRequest}catch(e){}};var Wt={0:200,1223:204},zt=k.ajaxSettings.xhr();v.cors=!!zt&&"withCredentials"in zt,v.ajax=zt=!!zt,k.ajaxTransport(function(e){var t,r;if(v.cors||zt&&!e.crossDomain)return{send:function(i,o){var s,a=e.xhr();if(a.open(e.type,e.url,e.async,e.username,e.password),e.xhrFields)for(s in e.xhrFields)a[s]=e.xhrFields[s];for(s in e.mimeType&&a.overrideMimeType&&a.overrideMimeType(e.mimeType),e.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest"),i)a.setRequestHeader(s,i[s]);t=function(e){return function(){t&&(t=r=a.onload=a.onerror=a.onabort=a.ontimeout=a.onreadystatechange=null,"abort"===e?a.abort():"error"===e?"number"!=typeof a.status?o(0,"error"):o(a.status,a.statusText):o(Wt[a.status]||a.status,a.statusText,"text"!==(a.responseType||"text")||"string"!=typeof a.responseText?{binary:a.response}:{text:a.responseText},a.getAllResponseHeaders()))}},a.onload=t(),r=a.onerror=a.ontimeout=t("error"),void 0!==a.onabort?a.onabort=r:a.onreadystatechange=function(){4===a.readyState&&n.setTimeout(function(){t&&r()})},t=t("abort");try{a.send(e.hasContent&&e.data||null)}catch(e){if(t)throw e}},abort:function(){t&&t()}}}),k.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),k.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return k.globalEval(e),e}}}),k.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),k.ajaxTransport("script",function(e){var t,n;if(e.crossDomain)return{send:function(r,i){t=k("