From 29075acffe97b2af4e90bbd38c0a8e530380c8f7 Mon Sep 17 00:00:00 2001 From: danielyxie Date: Tue, 26 Feb 2019 00:45:34 -0800 Subject: [PATCH 1/7] Fixed changelog formatting --- doc/source/changelog.rst | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/doc/source/changelog.rst b/doc/source/changelog.rst index 2804ea535..47ee7059c 100644 --- a/doc/source/changelog.rst +++ b/doc/source/changelog.rst @@ -6,22 +6,22 @@ Changelog v0.44.0 - 2/26/2019 ------------------- * Bladeburner Changes: - ** Reduced the amount of rank needed to earn a skill point - ** Reduced the effects of the "Reaper" and "Evasive System" skills - ** Increased the effect of the "Hyperdrive" and "Hands of Midas" skills - ** Slightly increased the rate which the skill point cost rises for almost all skills - ** The "Overlock" Skill now has a maximum level of 90 instead of 95 - ** Money earned from Contracts increased by 400% - ** Changed the way population affects success rate. Extreme populations now have less dramatic effects - ** Added two new General Actions: Diplomacy and Hyperbolic Regeneration Chamber - ** Lowered the rep and money cost of the "Blade's Simulacrum" augmentation - ** Significantly decreased the initial amount of Contracts/Operations (the "Contracts/Operations remaining" value) - ** Decreased the rate at which the amount of Contracts/Operations increases over time - ** Decreased the number of successes you need to increase the max level of a Contract/Operation - ** Increased the average number of Synthoid communities each city has - ** Reduced the amount by which a successful raid will decrease the population of a city - ** The "riots" event will now increase the chaos of a city by a greater amount - ** Significantly increased the effect that Agility and Dexterity have on action time + * Reduced the amount of rank needed to earn a skill point + * Reduced the effects of the "Reaper" and "Evasive System" skills + * Increased the effect of the "Hyperdrive" and "Hands of Midas" skills + * Slightly increased the rate which the skill point cost rises for almost all skills + * The "Overlock" Skill now has a maximum level of 90 instead of 95 + * Money earned from Contracts increased by 400% + * Changed the way population affects success rate. Extreme populations now have less dramatic effects + * Added two new General Actions: Diplomacy and Hyperbolic Regeneration Chamber + * Lowered the rep and money cost of the "Blade's Simulacrum" augmentation + * Significantly decreased the initial amount of Contracts/Operations (the "Contracts/Operations remaining" value) + * Decreased the rate at which the amount of Contracts/Operations increases over time + * Decreased the number of successes you need to increase the max level of a Contract/Operation + * Increased the average number of Synthoid communities each city has + * Reduced the amount by which a successful raid will decrease the population of a city + * The "riots" event will now increase the chaos of a city by a greater amount + * Significantly increased the effect that Agility and Dexterity have on action time * Added new BitNode multipliers: * HomeComputerRamCost - Affects how much it costs to upgrade home computer's RAM * DaedalusAugsRequirement - Affects how many Augmentations you need in order to get invited to Daedalus From b26568bf7d91d786aa59ac2477be5858973ebe03 Mon Sep 17 00:00:00 2001 From: Mason Dechaineux Date: Mon, 25 Feb 2019 07:20:56 +1000 Subject: [PATCH 2/7] Fixed bug with rm terminal and ns commands that made non-exe files with .exe in their name undeletable. --- src/NetscriptFunctions.js | 2 +- src/Terminal.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/NetscriptFunctions.js b/src/NetscriptFunctions.js index 439eebfa5..9b7e6a56a 100644 --- a/src/NetscriptFunctions.js +++ b/src/NetscriptFunctions.js @@ -2261,7 +2261,7 @@ function NetscriptFunctions(workerScript) { throw makeRuntimeRejectMsg(workerScript, `Invalid server specified for rm(): ${ip}`); } - if (fn.includes(".exe")) { + if (fn.endsWith(".exe")) { for (var i = 0; i < s.programs.length; ++i) { if (s.programs[i] === fn) { s.programs.splice(i, 1); diff --git a/src/Terminal.js b/src/Terminal.js index 926318047..bb06b6c25 100644 --- a/src/Terminal.js +++ b/src/Terminal.js @@ -1342,7 +1342,7 @@ let Terminal = { //Check programs let delTarget = commandArray[1]; - if (delTarget.includes(".exe")) { + if (delTarget.endsWith(".exe")) { for (let i = 0; i < s.programs.length; ++i) { if (s.programs[i] === delTarget) { s.programs.splice(i, 1); From a27781009585d85569c434f4f5e94af0ccd7d6a3 Mon Sep 17 00:00:00 2001 From: danielyxie Date: Tue, 26 Feb 2019 00:51:48 -0800 Subject: [PATCH 3/7] v0.44.1 Duplicate Sleeve updates --- src/DevMenu.js | 26 ++++++ src/PersonObjects/Person.ts | 1 - src/PersonObjects/Sleeve/Sleeve.ts | 44 ++++++++- .../Sleeve/SleeveAugmentationsUI.ts | 91 +++++++++++++++++++ .../Sleeve/SleeveCovenantPurchases.ts | 2 +- src/PersonObjects/Sleeve/SleeveUI.ts | 25 +++-- src/Player.js | 4 +- 7 files changed, 180 insertions(+), 13 deletions(-) create mode 100644 src/PersonObjects/Sleeve/SleeveAugmentationsUI.ts diff --git a/src/DevMenu.js b/src/DevMenu.js index ceadc51cf..03b72f108 100644 --- a/src/DevMenu.js +++ b/src/DevMenu.js @@ -51,6 +51,15 @@ export function createDevMenu() { innerText: "Add $1000t", }); + const addMoney2 = createElement("button", { + class: "std-button", + clickListener: () => { + Player.gainMoney(1e12); + }, + display: "block", + innerText: "Add $1t", + }) + const addRam = createElement("button", { class: "std-button", clickListener: () => { @@ -588,6 +597,20 @@ export function createDevMenu() { innerText: "View Stock Price Caps", }); + // Sleeves + const sleevesHeader = createElement("h2", { innerText: "Sleeves" }); + + const sleevesRemoveAllShockRecovery = createElement("button", { + class: "std-button", + display: "block", + innerText: "Set Shock Recovery of All Sleeves to 0", + clickListener: () => { + for (let i = 0; i < Player.sleeves.length; ++i) { + Player.sleeves[i].shock = 100; + } + } + }); + // Add everything to container, then append to main menu const devMenuContainer = createElement("div", { class: "generic-menupage-container", @@ -597,6 +620,7 @@ export function createDevMenu() { devMenuContainer.appendChild(devMenuText); devMenuContainer.appendChild(genericHeader); devMenuContainer.appendChild(addMoney); + devMenuContainer.appendChild(addMoney2); devMenuContainer.appendChild(addRam); devMenuContainer.appendChild(triggerBitflume); devMenuContainer.appendChild(destroyCurrentBitnode); @@ -674,6 +698,8 @@ export function createDevMenu() { devMenuContainer.appendChild(stockPriceChangeBtn); devMenuContainer.appendChild(createElement("br")); devMenuContainer.appendChild(stockViewPriceCapBtn); + devMenuContainer.appendChild(sleevesHeader); + devMenuContainer.appendChild(sleevesRemoveAllShockRecovery); const entireGameContainer = document.getElementById("entire-game-container"); if (entireGameContainer == null) { diff --git a/src/PersonObjects/Person.ts b/src/PersonObjects/Person.ts index 6a80dce2f..9bc208a0a 100644 --- a/src/PersonObjects/Person.ts +++ b/src/PersonObjects/Person.ts @@ -5,7 +5,6 @@ import { IPlayerOwnedAugmentation } from "../Augmentation/PlayerOwnedAugmentatio import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; import { Cities } from "../Locations/Cities"; import { CONSTANTS } from "../Constants"; -import { IMap } from "../types"; // Interface that defines a generic object used to track experience/money // earnings for tasks diff --git a/src/PersonObjects/Sleeve/Sleeve.ts b/src/PersonObjects/Sleeve/Sleeve.ts index a634a8d2f..a02842560 100644 --- a/src/PersonObjects/Sleeve/Sleeve.ts +++ b/src/PersonObjects/Sleeve/Sleeve.ts @@ -13,6 +13,8 @@ import { Person, ITaskTracker, createTaskTracker } from "../Person"; +import { Augmentation } from "../../Augmentation/Augmentation"; + import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers"; import { Crime } from "../../Crime/Crime"; @@ -136,8 +138,11 @@ export class Sleeve extends Person { */ sync: number = 1; - constructor() { + constructor(p: IPlayer | null = null) { super(); + if (p != null) { + this.shockRecovery(p); + } } /** @@ -381,6 +386,17 @@ export class Sleeve extends Person { } } + installAugmentation(aug: Augmentation): void { + 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.applyAugmentation(aug); + this.updateStatLevels(); + } + log(entry: string): void { const MaxLogSize: number = 50; this.logs.push(entry); @@ -452,10 +468,10 @@ export class Sleeve extends Person { company!.playerReputation += (this.getRepGain(p) * cyclesUsed); break; case SleeveTaskType.Recovery: - this.shock = Math.min(100, this.shock + (0.0001 * cyclesUsed)); + this.shock = Math.min(100, this.shock + (0.0002 * cyclesUsed)); break; case SleeveTaskType.Sync: - this.sync = Math.min(100, this.sync + (0.0001 * cyclesUsed)); + this.sync = Math.min(100, this.sync + (0.0002 * cyclesUsed)); break; default: break; @@ -492,6 +508,28 @@ export class Sleeve extends Person { this.gymStatType = ""; } + shockRecovery(p: IPlayer): boolean { + if (this.currentTask !== SleeveTaskType.Idle) { + this.finishTask(p); + } else { + this.resetTaskStatus(); + } + + this.currentTask = SleeveTaskType.Recovery; + return true; + } + + synchronize(p: IPlayer): boolean { + if (this.currentTask !== SleeveTaskType.Idle) { + this.finishTask(p); + } else { + this.resetTaskStatus(); + } + + this.currentTask = SleeveTaskType.Sync; + return true; + } + /** * Take a course at a university */ diff --git a/src/PersonObjects/Sleeve/SleeveAugmentationsUI.ts b/src/PersonObjects/Sleeve/SleeveAugmentationsUI.ts new file mode 100644 index 000000000..280b8b37b --- /dev/null +++ b/src/PersonObjects/Sleeve/SleeveAugmentationsUI.ts @@ -0,0 +1,91 @@ +/** + * Module for handling the UI for purchasing Sleeve Augmentations + * This UI is a popup, not a full page + */ +import { Sleeve } from "./Sleeve"; + +import { IPlayer } from "../IPlayer"; + +import { Augmentation } from "../../Augmentation/Augmentation"; +import { Augmentations } from "../../Augmentation/Augmentations"; + +import { Faction } from "../../Faction/Faction"; +import { Factions } from "../../Faction/Factions"; + +import { numeralWrapper } from "../../ui/numeralFormat"; + +import { dialogBoxCreate } from "../../../utils/DialogBox"; + +import { clearEventListeners } from "../../../utils/uiHelpers/clearEventListeners"; +import { createElement } from "../../../utils/uiHelpers/createElement"; +import { createPopup } from "../../../utils/uiHelpers/createPopup"; +import { createPopupCloseButton } from "../../../utils/uiHelpers/createPopupCloseButton"; +import { getSelectValue } from "../../../utils/uiHelpers/getSelectData"; +import { removeChildrenFromElement } from "../../../utils/uiHelpers/removeChildrenFromElement"; +import { removeElement } from "../../../utils/uiHelpers/removeElement"; +import { removeElementById } from "../../../utils/uiHelpers/removeElementById"; + +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) { + const fac: Faction | null = Factions[facName]; + if (fac == null) { continue; } + + for (const augName of fac.augmentations) { + const aug: Augmentation | null = Augmentations[augName]; + + if (fac.playerReputation > aug.baseRepRequirement && !availableAugs.includes(aug)) { + availableAugs.push(aug); + } + } + } + + + // General info about buying Augmentations + const info = createElement("p", { + innerHTML: + [ + `You can purchase Augmentations for your Duplicate Sleeves. These Augmentations`, + `have the same effect as they would for you. You can only purchase Augmentations`, + `that you have unlocked through Factions.

`, + `When purchasing an Augmentation for a Duplicate Sleeve, they are immediately`, + `installed. This means that the Duplicate Sleeve will immediately lose all of`, + `its stat experience.` + ].join(" "), + }); + + const popupId = "purchase-sleeve-augs-popup"; + const popupElems: HTMLElement[] = [info]; + + for (const aug of availableAugs) { + const div = createElement("div", { + class: "cmpy-mgmt-upgrade-div", // We'll reuse this CSS class + }); + + div.appendChild(createElement("p", { + innerHTML: + [ + `

${aug.name}


`, + `Cost: ${numeralWrapper.formatMoney(aug.baseCost)}

`, + `${aug.info}` + ].join(" "), + clickListener: () => { + if (p.canAfford(aug.baseCost)) { + p.loseMoney(aug.baseCost); + sleeve.installAugmentation(aug); + dialogBoxCreate(`Installed ${aug.name} on Duplicate Sleeve!`, false) + } else { + dialogBoxCreate(`You cannot afford ${aug.name}`, false); + } + } + })); + + popupElems.push(div); + } + + createPopup(popupId, popupElems); +} diff --git a/src/PersonObjects/Sleeve/SleeveCovenantPurchases.ts b/src/PersonObjects/Sleeve/SleeveCovenantPurchases.ts index b05eb80bf..496641415 100644 --- a/src/PersonObjects/Sleeve/SleeveCovenantPurchases.ts +++ b/src/PersonObjects/Sleeve/SleeveCovenantPurchases.ts @@ -29,7 +29,7 @@ export function createPurchaseSleevesFromCovenantPopup(p: IPlayer) { if (p.canAfford(cost)) { p.loseMoney(cost); p.sleevesFromCovenant += 1; - p.sleeves.push(new Sleeve()); + p.sleeves.push(new Sleeve(p)); yesNoBoxClose(); } else { dialogBoxCreate("You cannot afford to purchase a Duplicate Sleeve", false); diff --git a/src/PersonObjects/Sleeve/SleeveUI.ts b/src/PersonObjects/Sleeve/SleeveUI.ts index 486e510ea..a9a0197fd 100644 --- a/src/PersonObjects/Sleeve/SleeveUI.ts +++ b/src/PersonObjects/Sleeve/SleeveUI.ts @@ -10,6 +10,8 @@ import { IPlayer } from "../IPlayer"; import { CONSTANTS } from "../../Constants"; import { Locations } from "../../Locations"; +import { Augmentations } from "../../Augmentation/Augmentations"; + import { Faction } from "../../Faction/Faction"; import { Factions } from "../../Faction/Factions"; import { FactionWorkType } from "../../Faction/FactionWorkTypeEnum"; @@ -44,6 +46,7 @@ interface ISleeveUIElems { stats: HTMLElement | null; moreStatsButton: HTMLElement | null; travelButton: HTMLElement | null; + purchaseAugsButton: HTMLElement | null; taskPanel: HTMLElement | null; taskSelector: HTMLSelectElement | null; taskDetailsSelector: HTMLSelectElement | null; @@ -171,6 +174,7 @@ function createSleeveUi(sleeve: Sleeve, allSleeves: Sleeve[]): ISleeveUIElems { stats: null, moreStatsButton: null, travelButton: null, + purchaseAugsButton: null, taskPanel: null, taskSelector: null, taskDetailsSelector: null, @@ -267,10 +271,22 @@ function createSleeveUi(sleeve: Sleeve, allSleeves: Sleeve[]): ISleeveUIElems { createPopup(popupId, popupArguments); } - }) + }); + elems.purchaseAugsButton = createElement("button", { + class: "std-button", + display: "block", + innerText: "Purchase Augmentations", + clickListener: () => { + + } + }); elems.statsPanel.appendChild(elems.stats); elems.statsPanel.appendChild(elems.moreStatsButton); elems.statsPanel.appendChild(elems.travelButton); + if (sleeve.shock >= 100) { + // You can only buy augs when shock recovery is 0 + elems.statsPanel.appendChild(elems.purchaseAugsButton); + } elems.taskPanel = createElement("div", { class: "sleeve-panel", width: "40%" }); elems.taskSelector = createElement("select") as HTMLSelectElement; @@ -655,14 +671,11 @@ function setSleeveTask(sleeve: Sleeve, elems: ISleeveUIElems): boolean { res = sleeve.workoutAtGym(playerRef!, detailValue2, detailValue); break; case "Shock Recovery": - sleeve.finishTask(playerRef!); sleeve.currentTask = SleeveTaskType.Recovery; - res = true; + res = sleeve.shockRecovery(playerRef!); break; case "Synchronize": - sleeve.finishTask(playerRef!); - sleeve.currentTask = SleeveTaskType.Sync; - res = true; + res = sleeve.synchronize(playerRef!); break; default: console.error(`Invalid/Unrecognized taskValue in setSleeveTask(): ${taskValue}`); diff --git a/src/Player.js b/src/Player.js index 9a47e79f1..5c48555ee 100644 --- a/src/Player.js +++ b/src/Player.js @@ -281,7 +281,7 @@ PlayerObject.prototype.prestigeAugmentation = function() { for (let i = 0; i < this.sleeves.length; ++i) { if (this.sleeves[i] instanceof Sleeve) { - this.sleeves[i].resetTaskStatus(); + this.sleeves[i].shockRecovery(this); } } @@ -372,7 +372,7 @@ 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.sleeves[i] = new Sleeve(this); } this.isWorking = false; From 1d07ca4ffbea359104bae3b51ef9800417097ce0 Mon Sep 17 00:00:00 2001 From: danielyxie Date: Tue, 26 Feb 2019 18:26:29 -0800 Subject: [PATCH 4/7] Fixed a few minor bugs with submitting solutions for Coding Contracts. Started on Getting STarted Guide for wiki --- doc/source/conf.py | 4 +- doc/source/guidesandtips.rst | 8 ++-- ...tingstartedguideforbeginnerprogrammers.rst | 47 +++++++++++++++++++ src/Constants.ts | 45 ++++-------------- src/NetscriptFunctions.js | 24 ++++++++-- .../Sleeve/SleeveAugmentationsUI.ts | 13 +++-- src/PersonObjects/Sleeve/SleeveUI.ts | 3 +- src/data/codingcontracttypes.ts | 3 +- src/ui/displayCharacterInfo.ts | 2 +- src/utils/helpers/is2DArray.ts | 8 ++++ utils/README.md | 4 ++ 11 files changed, 104 insertions(+), 57 deletions(-) create mode 100644 doc/source/guidesandtips/gettingstartedguideforbeginnerprogrammers.rst create mode 100644 src/utils/helpers/is2DArray.ts create mode 100644 utils/README.md diff --git a/doc/source/conf.py b/doc/source/conf.py index 22d8d56b0..46634b60b 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -64,9 +64,9 @@ documentation_title = '{0} Documentation'.format(project) # built documents. # # The short X.Y version. -version = '0.43' +version = '0.44' # The full version, including alpha/beta/rc tags. -release = '0.43.0' +release = '0.44.1' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/doc/source/guidesandtips.rst b/doc/source/guidesandtips.rst index d01e67cdd..c2f17f202 100644 --- a/doc/source/guidesandtips.rst +++ b/doc/source/guidesandtips.rst @@ -1,9 +1,11 @@ Guides & Tips ============= +Getting Started Guide for Intermediate Programmers +What BitNode should I do? +Beginners FAQ + .. toctree:: :maxdepth: 3 - Getting Started Guide for Beginner Programmers - Getting Started Guide for Intermediate Programmers - What BitNode should I do? + Getting Started Guide for Beginner Programmers diff --git a/doc/source/guidesandtips/gettingstartedguideforbeginnerprogrammers.rst b/doc/source/guidesandtips/gettingstartedguideforbeginnerprogrammers.rst new file mode 100644 index 000000000..7d17e78b5 --- /dev/null +++ b/doc/source/guidesandtips/gettingstartedguideforbeginnerprogrammers.rst @@ -0,0 +1,47 @@ +Getting Started Guide for Beginner Programmers +============================================== + +.. note:: Note that the scripts and strategies given in this guide aren't necessarily + optimal. They're just meant to introduce you to the game and help you get + started. + +This is an introductory guide to getting started with Bitburner. It is not meant to be a +comprehensive guide for the entire game, only the early stages. If you are confused +or overwhelmed by the game, especially the programming and scripting aspects, this +guide is perfect for you! + +Note that this guide is tailored towards those with minimal programming experience. + +Introduction +------------ +Bitburner is a cyberpunk-themed incremental RPG. The player progresses by raising +their :ref:`gameplay_stats`, earning money, and :ref:`climbing the corporate ladder `. +Eventually, after reaching certain criteria, the player will begin receiving invitations +from :ref:`gameplay_factions`. Joining these factions and working for them will unlock +:ref:`gameplay_augmentations`. Purchasing and installing Augmentations provide persistent +upgrades and are necessary for progressing in the game. + +The game has a minimal story/quest-line that can be followed to reach the end of the game. +Since this guide is only about getting started with Bitburner, it will not cover the +entire "quest-line". + +First Steps +----------- +I'm going to assume you followed the introductory tutorial when you first began the game. +In this introductory tutorial you created a script called `foodnstuff.script` and ran it +on the `foodnstuff` server. Right now, we'll kill this script. There are two ways +to do this: + +1. You can go to the Terminal and enter:: + + $ kill foodnstuff.script + +2. You can go to the "Active Scripts" page (:ref:`Keyboard shortcut ` Alt + s) and + press the "Kill Script" button for `foodnstuff.script`. + +If you skipped the introductory tutorial, then ignore the part above. Instead, go to the +"Hacknet Nodes" page (:ref:`Keyboard shortcut ` Alt + h) and purchase a +Hacknet Node to start generating some passive income. + +Creating our First Scripts +-------------------------- diff --git a/src/Constants.ts b/src/Constants.ts index 8ef109394..eb36b0b1b 100644 --- a/src/Constants.ts +++ b/src/Constants.ts @@ -510,44 +510,15 @@ export let CONSTANTS: IMap = { LatestUpdate: ` - v0.44.0 - * Bladeburner Changes: - ** Reduced the amount of rank needed to earn a skill point - ** Reduced the effects of the "Reaper" and "Evasive System" skills - ** Increased the effect of the "Hyperdrive" and "Hands of Midas" skills - ** Slightly increased the rate which the skill point cost rises for almost all skills - ** The "Overlock" Skill now has a maximum level of 90 instead of 95 - ** Money earned from Contracts increased by 400% - ** Changed the way population affects success rate. Extreme populations now have less dramatic effects - ** Added two new General Actions: Diplomacy and Hyperbolic Regeneration Chamber - ** Lowered the rep and money cost of the "Blade's Simulacrum" augmentation - ** Significantly decreased the initial amount of Contracts/Operations (the "Contracts/Operations remaining" value) - ** Decreased the rate at which the amount of Contracts/Operations increases over time - ** Decreased the number of successes you need to increase the max level of a Contract/Operation - ** Increased the average number of Synthoid communities each city has - ** Reduced the amount by which a successful raid will decrease the population of a city - ** The "riots" event will now increase the chaos of a city by a greater amount - ** Significantly increased the effect that Agility and Dexterity have on action time + v0.44.1 + * Duplicate Sleeve changes: + ** You can now purchase Augmentations for your Duplicate Sleeves + ** Sleeves are now assigned to Shock Recovery task by default + ** Shock Recovery and Synchronize tasks are now twice as effective - * Added new BitNode multipliers: - ** HomeComputerRamCost - Affects how much it costs to upgrade home computer's RAM - ** DaedalusAugsRequirement - Affects how many Augmentations you need in order to get invited to Daedalus - ** FourSigmaMarketDataCost - Affects how much it costs to unlock the stock market's 4S Market Data - ** FourSigmaMarketDataApiCost - Affects how much it costs to unlock the stock market's 4S Market Data API - - * A few minor changes to BitNode multipliers across the board (mostly for the new multipliers) - * 'The Covenant' now requires 20 total Augmentations to get invited, rather than 30 - * You can now purchase permanent Duplicate Sleeves from 'The Covenant'. This requires Source-File 10, and you must be in BN-10 or after - * You can now track where all of your money comes from in the 'Stats' page - * Increased the money gained from Coding Contracts by 50% - * getCharacterInformation() function now returns the player's HP and max HP - * Bug Fix: You can no longer disconnect the enemy's connections in Hacking Missions - * Bug Fix: Duplicate Sleeve faction reputation gain is now properly affected by faction favor - * Bug Fix: After installing Augmentations, the Terminal display will now correctly show the current server as "home" - * Bug Fix: Fixed an exploit where you could change the duration of timed functions (e.g. hack, weaken) in NetscriptJS - * Bug Fix: You should now properly be able to use the ServerProfile.exe program - * Bug Fix: Prevented exploit that allowed you to accept faction invites programmatically through NetscriptJS - * Bug Fix: Faction invitations for megacorporations should now work properly + * Bug Fix: 'rm' Terminal and Netscript commands now work on non-program files that have '.exe' in the name (by Github user MasonD) + * Bug Fix: The 'Find All Valid Math Expressions' Coding Contract should now properly ignore whitespace in answers + * Bug Fix: The 'Merge Overlapping Intervals' Coding Contract should now properly accept 2D arrays when being attempted through Netscript ` } diff --git a/src/NetscriptFunctions.js b/src/NetscriptFunctions.js index 9b7e6a56a..e2e585616 100644 --- a/src/NetscriptFunctions.js +++ b/src/NetscriptFunctions.js @@ -53,9 +53,6 @@ import {StockMarket, StockSymbols, SymbolToStockMap, PositionTypes, placeOrder, cancelOrder} from "./StockMarket/StockMarket"; import { getStockmarket4SDataCost, getStockMarket4STixApiCost } from "./StockMarket/StockMarketCosts"; -import {numeralWrapper} from "./ui/numeralFormat"; -import {post} from "./ui/postToTerminal"; -import { setTimeoutRef } from "./utils/SetTimeoutRef"; import {TextFile, getTextFile, createTextFile} from "./TextFile"; import {unknownBladeburnerActionErrorMessage, @@ -68,8 +65,12 @@ import {makeRuntimeRejectMsg, netscriptDelay, runScriptFromScript} from "./NetscriptEvaluator"; import {NetscriptPort} from "./NetscriptPort"; -import Decimal from "decimal.js"; import {Page, routing} from "./ui/navigationTracking"; +import {numeralWrapper} from "./ui/numeralFormat"; +import {post} from "./ui/postToTerminal"; +import { setTimeoutRef } from "./utils/SetTimeoutRef"; +import { is2DArray } from "./utils/helpers/is2DArray"; + import {dialogBoxCreate} from "../utils/DialogBox"; import {isPowerOfTwo} from "../utils/helpers/isPowerOfTwo"; import {arrayToString} from "../utils/helpers/arrayToString"; @@ -4686,7 +4687,20 @@ function NetscriptFunctions(workerScript) { workerScript.log(`ERROR: codingcontract.getData() failed because it could find the specified contract ${fn} on server ${ip}`); return false; } - answer = String(answer); + + // Convert answer to string. If the answer is a 2D array, then we have to + // manually add brackets for the inner arrays + if (is2DArray(answer)) { + let answerComponents = []; + for (let i = 0; i < answer.length; ++i) { + answerComponents.push(["[", answer[i].toString(), "]"].join("")); + } + + answer = answerComponents.join(","); + } else { + answer = String(answer); + } + const serv = safeGetServer(ip, "codingcontract.attempt()"); if (contract.isSolution(answer)) { const reward = Player.gainCodingContractReward(contract.reward, contract.getDifficulty()); diff --git a/src/PersonObjects/Sleeve/SleeveAugmentationsUI.ts b/src/PersonObjects/Sleeve/SleeveAugmentationsUI.ts index 280b8b37b..3fc5b76a7 100644 --- a/src/PersonObjects/Sleeve/SleeveAugmentationsUI.ts +++ b/src/PersonObjects/Sleeve/SleeveAugmentationsUI.ts @@ -16,14 +16,9 @@ import { numeralWrapper } from "../../ui/numeralFormat"; import { dialogBoxCreate } from "../../../utils/DialogBox"; -import { clearEventListeners } from "../../../utils/uiHelpers/clearEventListeners"; import { createElement } from "../../../utils/uiHelpers/createElement"; import { createPopup } from "../../../utils/uiHelpers/createPopup"; import { createPopupCloseButton } from "../../../utils/uiHelpers/createPopupCloseButton"; -import { getSelectValue } from "../../../utils/uiHelpers/getSelectData"; -import { removeChildrenFromElement } from "../../../utils/uiHelpers/removeChildrenFromElement"; -import { removeElement } from "../../../utils/uiHelpers/removeElement"; -import { removeElementById } from "../../../utils/uiHelpers/removeElementById"; export function createSleevePurchaseAugsPopup(sleeve: Sleeve, p: IPlayer) { // You can only purchase Augmentations that are actually available from @@ -44,6 +39,8 @@ export function createSleevePurchaseAugsPopup(sleeve: Sleeve, p: IPlayer) { } } + // Create popup + const popupId = "purchase-sleeve-augs-popup"; // General info about buying Augmentations const info = createElement("p", { @@ -58,8 +55,10 @@ export function createSleevePurchaseAugsPopup(sleeve: Sleeve, p: IPlayer) { ].join(" "), }); - const popupId = "purchase-sleeve-augs-popup"; - const popupElems: HTMLElement[] = [info]; + // Close popup + const closeBtn = createPopupCloseButton(popupId, { innerText: "Cancel" }); + + const popupElems: HTMLElement[] = [closeBtn, info]; for (const aug of availableAugs) { const div = createElement("div", { diff --git a/src/PersonObjects/Sleeve/SleeveUI.ts b/src/PersonObjects/Sleeve/SleeveUI.ts index a9a0197fd..b8ee967a0 100644 --- a/src/PersonObjects/Sleeve/SleeveUI.ts +++ b/src/PersonObjects/Sleeve/SleeveUI.ts @@ -1,6 +1,7 @@ /** * Module for handling the Sleeve UI */ +import { createSleevePurchaseAugsPopup } from "./SleeveAugmentationsUI"; import { Sleeve } from "./Sleeve"; import { SleeveTaskType } from "./SleeveTaskTypesEnum"; import { SleeveFaq } from "./data/SleeveFaq"; @@ -277,7 +278,7 @@ function createSleeveUi(sleeve: Sleeve, allSleeves: Sleeve[]): ISleeveUIElems { display: "block", innerText: "Purchase Augmentations", clickListener: () => { - + createSleevePurchaseAugsPopup(sleeve, playerRef!); } }); elems.statsPanel.appendChild(elems.stats); diff --git a/src/data/codingcontracttypes.ts b/src/data/codingcontracttypes.ts index 3e13799db..f687d688a 100644 --- a/src/data/codingcontracttypes.ts +++ b/src/data/codingcontracttypes.ts @@ -898,7 +898,8 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ const sanitizedPlayerAns: string = removeBracketsFromArrayString(ans); const sanitizedPlayerAnsArr: string[] = sanitizedPlayerAns.split(","); for (let i = 0; i < sanitizedPlayerAnsArr.length; ++i) { - sanitizedPlayerAnsArr[i] = removeQuotesFromString(sanitizedPlayerAnsArr[i]); + sanitizedPlayerAnsArr[i] = removeQuotesFromString(sanitizedPlayerAnsArr[i]) + .replace(/\s/g, "");; } if (num == null || num.length === 0) { diff --git a/src/ui/displayCharacterInfo.ts b/src/ui/displayCharacterInfo.ts index 4328329c0..0eb464032 100644 --- a/src/ui/displayCharacterInfo.ts +++ b/src/ui/displayCharacterInfo.ts @@ -55,7 +55,7 @@ export function displayCharacterInfo(elem: HTMLElement, p: IPlayer) { if (src.bladeburner) { parts.push(`Bladeburner: ${numeralWrapper.formatMoney(src.bladeburner)}`) }; if (src.codingcontract) { parts.push(`Coding Contracts: ${numeralWrapper.formatMoney(src.codingcontract)}`) }; if (src.work) { parts.push(`Company Work: ${numeralWrapper.formatMoney(src.work)}`) }; - if (src.corporation) { parts.push(`Corporation: ${numeralWrapper.formatMoney(src.corporation)}}`) }; + if (src.corporation) { parts.push(`Corporation: ${numeralWrapper.formatMoney(src.corporation)}`) }; if (src.crime) { parts.push(`Crimes: ${numeralWrapper.formatMoney(src.crime)}`) }; if (src.gang) { parts.push(`Gang: ${numeralWrapper.formatMoney(src.gang)}`) }; if (src.hacking) { parts.push(`Hacking: ${numeralWrapper.formatMoney(src.hacking)}`) }; diff --git a/src/utils/helpers/is2DArray.ts b/src/utils/helpers/is2DArray.ts new file mode 100644 index 000000000..f8763921b --- /dev/null +++ b/src/utils/helpers/is2DArray.ts @@ -0,0 +1,8 @@ +// Checks whether an array is a 2D array. +// For this, a 2D array is an array which contains only other arrays. +// If one element in the array is a number or string, it is NOT a 2D array +export function is2DArray(arr: any[]): boolean { + if (arr.constructor !== Array) { return false; } + + return arr.every((e) => { return e.constructor === Array; }); +} diff --git a/utils/README.md b/utils/README.md new file mode 100644 index 000000000..7a8bd8365 --- /dev/null +++ b/utils/README.md @@ -0,0 +1,4 @@ +This directory contains anything that does not represent an actual component of +the game. Instead, it contains utility classes, functions, etc. + +The `/helper` directory contains helper functions. From 8e4c7beb1abdb6af9a6fb1227b4459fba486058f Mon Sep 17 00:00:00 2001 From: danielyxie Date: Sat, 2 Mar 2019 19:08:54 -0800 Subject: [PATCH 5/7] v0.44.1 Minor Update - Added Augs to Duplicate Sleeves and updated documentation --- doc/source/advancedgameplay/sleeves.rst | 12 +- doc/source/basicgameplay/augmentations.rst | 4 + doc/source/basicgameplay/hacking.rst | 4 + doc/source/basicgameplay/scripts.rst | 2 + doc/source/basicgameplay/terminal.rst | 10 +- ...tingstartedguideforbeginnerprogrammers.rst | 842 +++++++++- .../getBitNodeMultipliers.rst | 20 + .../getHackGrowWeakenTimes.rst | 15 + .../netscript/basicfunctions/brutessh.rst | 13 + doc/source/netscript/basicfunctions/clear.rst | 13 + .../netscript/basicfunctions/clearLog.rst | 8 + .../netscript/basicfunctions/deleteServer.rst | 14 + .../netscript/basicfunctions/disableLog.rst | 16 + .../netscript/basicfunctions/enableLog.rst | 10 + doc/source/netscript/basicfunctions/exec.rst | 34 + doc/source/netscript/basicfunctions/exit.rst | 8 + .../netscript/basicfunctions/fileExists.rst | 25 + .../netscript/basicfunctions/ftpcrack.rst | 13 + .../basicfunctions/getFavorToDonate.rst | 8 + .../netscript/basicfunctions/getGrowTime.rst | 13 + .../netscript/basicfunctions/getHackTime.rst | 13 + .../basicfunctions/getHackingLevel.rst | 8 + .../basicfunctions/getHackingMultipliers.rst | 22 + .../basicfunctions/getHacknetMultipliers.rst | 23 + .../netscript/basicfunctions/getHostname.rst | 8 + .../basicfunctions/getPortHandle.rst | 11 + .../basicfunctions/getPurchasedServerCost.rst | 16 + .../getPurchasedServerLimit.rst | 8 + .../getPurchasedServerMaxRam.rst | 8 + .../basicfunctions/getPurchasedServers.rst | 11 + .../basicfunctions/getScriptExpGain.rst | 14 + .../basicfunctions/getScriptIncome.rst | 18 + .../basicfunctions/getScriptLogs.rst | 33 + .../basicfunctions/getScriptName.rst | 8 + .../netscript/basicfunctions/getScriptRam.rst | 11 + .../getServerBaseSecurityLevel.rst | 12 + .../basicfunctions/getServerGrowth.rst | 12 + .../basicfunctions/getServerMaxMoney.rst | 9 + .../getServerMinSecurityLevel.rst | 9 + .../getServerMoneyAvailable.rst | 15 + .../getServerNumPortsRequired.rst | 9 + .../netscript/basicfunctions/getServerRam.rst | 17 + .../getServerRequiredHackingLevel.rst | 9 + .../basicfunctions/getServerSecurityLevel.rst | 10 + .../basicfunctions/getTimeSinceLastAug.rst | 8 + .../basicfunctions/getWeakenTime.rst | 13 + doc/source/netscript/basicfunctions/grow.rst | 21 + .../basicfunctions/growthAnalyze.rst | 24 + doc/source/netscript/basicfunctions/hack.rst | 22 + .../basicfunctions/hackAnalyzePercent.rst | 20 + .../basicfunctions/hackAnalyzeThreads.rst | 24 + .../netscript/basicfunctions/hackChance.rst | 11 + .../basicfunctions/hasRootAccess.rst | 15 + .../netscript/basicfunctions/httpworm.rst | 13 + .../netscript/basicfunctions/isLogEnabled.rst | 10 + .../netscript/basicfunctions/isRunning.rst | 29 + doc/source/netscript/basicfunctions/kill.rst | 29 + .../netscript/basicfunctions/killall.rst | 10 + doc/source/netscript/basicfunctions/ls.rst | 11 + .../netscript/basicfunctions/nFormat.rst | 19 + doc/source/netscript/basicfunctions/nuke.rst | 13 + doc/source/netscript/basicfunctions/peek.rst | 12 + doc/source/netscript/basicfunctions/print.rst | 9 + .../netscript/basicfunctions/prompt.rst | 10 + doc/source/netscript/basicfunctions/ps.rst | 28 + .../basicfunctions/purchaseServer.rst | 30 + doc/source/netscript/basicfunctions/read.rst | 16 + .../netscript/basicfunctions/relaysmtp.rst | 13 + doc/source/netscript/basicfunctions/rm.rst | 11 + doc/source/netscript/basicfunctions/run.rst | 33 + doc/source/netscript/basicfunctions/scan.rst | 11 + doc/source/netscript/basicfunctions/scp.rst | 29 + .../netscript/basicfunctions/scriptKill.rst | 11 + .../basicfunctions/scriptRunning.rst | 24 + .../netscript/basicfunctions/serverExists.rst | 9 + doc/source/netscript/basicfunctions/sleep.rst | 9 + doc/source/netscript/basicfunctions/spawn.rst | 20 + .../netscript/basicfunctions/sprintf.rst | 8 + .../netscript/basicfunctions/sqlinject.rst | 13 + .../netscript/basicfunctions/tprint.rst | 9 + .../netscript/basicfunctions/tryWrite.rst | 12 + .../netscript/basicfunctions/vsprintf.rst | 8 + .../netscript/basicfunctions/weaken.rst | 20 + doc/source/netscript/basicfunctions/wget.rst | 31 + doc/source/netscript/basicfunctions/write.rst | 20 + .../bladeburnerapi/getActionAutolevel.rst | 11 + .../getActionCountRemaining.rst | 12 + .../bladeburnerapi/getActionCurrentLevel.rst | 11 + .../getActionEstimatedSuccessChance.rst | 11 + .../bladeburnerapi/getActionMaxLevel.rst | 11 + .../bladeburnerapi/getActionRepGain.rst | 12 + .../bladeburnerapi/getActionTime.rst | 9 + .../bladeburnerapi/getBlackOpNames.rst | 6 + .../netscript/bladeburnerapi/getBonusTime.rst | 14 + .../netscript/bladeburnerapi/getCity.rst | 6 + .../netscript/bladeburnerapi/getCityChaos.rst | 8 + .../getCityEstimatedCommunities.rst | 9 + .../getCityEstimatedPopulation.rst | 9 + .../bladeburnerapi/getContractNames.rst | 6 + .../bladeburnerapi/getCurrentAction.rst | 14 + .../bladeburnerapi/getGeneralActionNames.rst | 6 + .../bladeburnerapi/getOperationNames.rst | 6 + .../netscript/bladeburnerapi/getRank.rst | 6 + .../bladeburnerapi/getSkillLevel.rst | 10 + .../bladeburnerapi/getSkillNames.rst | 6 + .../bladeburnerapi/getSkillPoints.rst | 6 + .../bladeburnerapi/getSkillUpgradeCost.rst | 11 + .../netscript/bladeburnerapi/getStamina.rst | 15 + .../netscript/bladeburnerapi/getTeamSize.rst | 13 + .../joinBladeburnerDivision.rst | 11 + .../bladeburnerapi/joinBladeburnerFaction.rst | 11 + .../bladeburnerapi/setActionAutolevel.rst | 10 + .../bladeburnerapi/setActionLevel.rst | 10 + .../netscript/bladeburnerapi/setTeamSize.rst | 12 + .../netscript/bladeburnerapi/startAction.rst | 10 + .../bladeburnerapi/stopBladeburnerAction.rst | 6 + .../netscript/bladeburnerapi/switchCity.rst | 10 + .../netscript/bladeburnerapi/upgradeSkill.rst | 9 + .../netscript/codingcontractapi/attempt.rst | 13 + .../codingcontractapi/getContractType.rst | 13 + .../netscript/codingcontractapi/getData.rst | 14 + .../codingcontractapi/getDescription.rst | 12 + .../getNumTriesRemaining.rst | 13 + doc/source/netscript/gangapi/ascendMember.rst | 22 + .../netscript/gangapi/canRecruitMember.rst | 6 + doc/source/netscript/gangapi/getBonusTime.rst | 13 + .../netscript/gangapi/getChanceToWinClash.rst | 9 + .../netscript/gangapi/getEquipmentCost.rst | 12 + .../netscript/gangapi/getEquipmentNames.rst | 9 + .../netscript/gangapi/getEquipmentType.rst | 16 + .../netscript/gangapi/getGangInformation.rst | 23 + .../gangapi/getMemberInformation.rst | 36 + .../netscript/gangapi/getMemberNames.rst | 8 + .../gangapi/getOtherGangInformation.rst | 26 + doc/source/netscript/gangapi/getTaskNames.rst | 8 + .../netscript/gangapi/purchaseEquipment.rst | 12 + .../netscript/gangapi/recruitMember.rst | 14 + .../netscript/gangapi/setMemberTask.rst | 12 + .../netscript/gangapi/setTerritoryWarfare.rst | 8 + .../hacknetnodeapi/getCoreUpgradeCost.rst | 12 + .../hacknetnodeapi/getLevelUpgradeCost.rst | 12 + .../netscript/hacknetnodeapi/getNodeStats.rst | 18 + .../hacknetnodeapi/getPurchaseNodeCost.rst | 6 + .../hacknetnodeapi/getRamUpgradeCost.rst | 12 + .../netscript/hacknetnodeapi/numNodes.rst | 6 + .../netscript/hacknetnodeapi/purchaseNode.rst | 11 + .../netscript/hacknetnodeapi/upgradeCore.rst | 14 + .../netscript/hacknetnodeapi/upgradeLevel.rst | 14 + .../netscript/hacknetnodeapi/upgradeRam.rst | 16 + .../netscript/netscriptadvancedfunctions.rst | 38 +- .../netscript/netscriptbladeburnerapi.rst | 388 +---- .../netscript/netscriptcodingcontractapi.rst | 74 +- doc/source/netscript/netscriptfunctions.rst | 1354 +---------------- doc/source/netscript/netscriptgangapi.rst | 271 +--- .../netscript/netscripthacknetnodeapi.rst | 168 +- doc/source/netscript/netscriptixapi.rst | 343 +---- .../netscriptsingularityfunctions.rst | 635 +------- .../singularityfunctions/applyToCompany.rst | 31 + .../checkFactionInvitations.rst | 8 + .../singularityfunctions/commitCrime.rst | 34 + .../singularityfunctions/createProgram.rst | 30 + .../singularityfunctions/donateToFaction.rst | 12 + .../getAugmentationCost.rst | 13 + .../getAugmentationPrereq.rst | 13 + .../getAugmentationsFromFaction.rst | 10 + .../getCharacterInformation.rst | 50 + .../singularityfunctions/getCompanyFavor.rst | 11 + .../getCompanyFavorGain.rst | 11 + .../singularityfunctions/getCompanyRep.rst | 11 + .../singularityfunctions/getCrimeChance.rst | 12 + .../singularityfunctions/getFactionFavor.rst | 10 + .../getFactionFavorGain.rst | 10 + .../singularityfunctions/getFactionRep.rst | 10 + .../getOwnedAugmentations.rst | 12 + .../getOwnedSourceFiles.rst | 9 + .../singularityfunctions/getStats.rst | 23 + .../getUpgradeHomeRamCost.rst | 8 + .../singularityfunctions/gymWorkout.rst | 30 + .../installAugmentations.rst | 14 + .../netscript/singularityfunctions/isBusy.rst | 9 + .../singularityfunctions/joinFaction.rst | 10 + .../purchaseAugmentation.rst | 14 + .../singularityfunctions/purchaseProgram.rst | 18 + .../singularityfunctions/purchaseTor.rst | 11 + .../singularityfunctions/stopAction.rst | 18 + .../singularityfunctions/travelToCity.rst | 20 + .../singularityfunctions/universityCourse.rst | 30 + .../singularityfunctions/upgradeHomeRam.rst | 10 + .../singularityfunctions/workForCompany.rst | 24 + .../singularityfunctions/workForFaction.rst | 32 + doc/source/netscript/tixapi/buyStock.rst | 16 + doc/source/netscript/tixapi/cancelOrder.rst | 24 + doc/source/netscript/tixapi/getOrders.rst | 68 + .../netscript/tixapi/getStockForecast.rst | 21 + .../netscript/tixapi/getStockMaxShares.rst | 11 + .../netscript/tixapi/getStockPosition.rst | 27 + doc/source/netscript/tixapi/getStockPrice.rst | 14 + .../netscript/tixapi/getStockSymbols.rst | 8 + .../netscript/tixapi/getStockVolatility.rst | 17 + doc/source/netscript/tixapi/placeOrder.rst | 26 + .../netscript/tixapi/purchase4SMarketData.rst | 11 + .../tixapi/purchase4SMarketDataTixApi.rst | 11 + doc/source/netscript/tixapi/sellShort.rst | 18 + doc/source/netscript/tixapi/sellStock.rst | 20 + doc/source/netscript/tixapi/shortStock.rst | 18 + src/Constants.ts | 231 +-- src/InteractiveTutorial.js | 3 +- src/PersonObjects/Sleeve/Sleeve.ts | 1 + .../Sleeve/SleeveAugmentationsUI.ts | 47 +- src/PersonObjects/Sleeve/SleeveUI.ts | 4 +- src/PersonObjects/Sleeve/data/SleeveFaq.ts | 17 +- src/engine.js | 92 -- src/index.html | 62 +- 213 files changed, 4024 insertions(+), 3405 deletions(-) create mode 100644 doc/source/netscript/advancedfunctions/getBitNodeMultipliers.rst create mode 100644 doc/source/netscript/advancedfunctions/getHackGrowWeakenTimes.rst create mode 100644 doc/source/netscript/basicfunctions/brutessh.rst create mode 100644 doc/source/netscript/basicfunctions/clear.rst create mode 100644 doc/source/netscript/basicfunctions/clearLog.rst create mode 100644 doc/source/netscript/basicfunctions/deleteServer.rst create mode 100644 doc/source/netscript/basicfunctions/disableLog.rst create mode 100644 doc/source/netscript/basicfunctions/enableLog.rst create mode 100644 doc/source/netscript/basicfunctions/exec.rst create mode 100644 doc/source/netscript/basicfunctions/exit.rst create mode 100644 doc/source/netscript/basicfunctions/fileExists.rst create mode 100644 doc/source/netscript/basicfunctions/ftpcrack.rst create mode 100644 doc/source/netscript/basicfunctions/getFavorToDonate.rst create mode 100644 doc/source/netscript/basicfunctions/getGrowTime.rst create mode 100644 doc/source/netscript/basicfunctions/getHackTime.rst create mode 100644 doc/source/netscript/basicfunctions/getHackingLevel.rst create mode 100644 doc/source/netscript/basicfunctions/getHackingMultipliers.rst create mode 100644 doc/source/netscript/basicfunctions/getHacknetMultipliers.rst create mode 100644 doc/source/netscript/basicfunctions/getHostname.rst create mode 100644 doc/source/netscript/basicfunctions/getPortHandle.rst create mode 100644 doc/source/netscript/basicfunctions/getPurchasedServerCost.rst create mode 100644 doc/source/netscript/basicfunctions/getPurchasedServerLimit.rst create mode 100644 doc/source/netscript/basicfunctions/getPurchasedServerMaxRam.rst create mode 100644 doc/source/netscript/basicfunctions/getPurchasedServers.rst create mode 100644 doc/source/netscript/basicfunctions/getScriptExpGain.rst create mode 100644 doc/source/netscript/basicfunctions/getScriptIncome.rst create mode 100644 doc/source/netscript/basicfunctions/getScriptLogs.rst create mode 100644 doc/source/netscript/basicfunctions/getScriptName.rst create mode 100644 doc/source/netscript/basicfunctions/getScriptRam.rst create mode 100644 doc/source/netscript/basicfunctions/getServerBaseSecurityLevel.rst create mode 100644 doc/source/netscript/basicfunctions/getServerGrowth.rst create mode 100644 doc/source/netscript/basicfunctions/getServerMaxMoney.rst create mode 100644 doc/source/netscript/basicfunctions/getServerMinSecurityLevel.rst create mode 100644 doc/source/netscript/basicfunctions/getServerMoneyAvailable.rst create mode 100644 doc/source/netscript/basicfunctions/getServerNumPortsRequired.rst create mode 100644 doc/source/netscript/basicfunctions/getServerRam.rst create mode 100644 doc/source/netscript/basicfunctions/getServerRequiredHackingLevel.rst create mode 100644 doc/source/netscript/basicfunctions/getServerSecurityLevel.rst create mode 100644 doc/source/netscript/basicfunctions/getTimeSinceLastAug.rst create mode 100644 doc/source/netscript/basicfunctions/getWeakenTime.rst create mode 100644 doc/source/netscript/basicfunctions/grow.rst create mode 100644 doc/source/netscript/basicfunctions/growthAnalyze.rst create mode 100644 doc/source/netscript/basicfunctions/hack.rst create mode 100644 doc/source/netscript/basicfunctions/hackAnalyzePercent.rst create mode 100644 doc/source/netscript/basicfunctions/hackAnalyzeThreads.rst create mode 100644 doc/source/netscript/basicfunctions/hackChance.rst create mode 100644 doc/source/netscript/basicfunctions/hasRootAccess.rst create mode 100644 doc/source/netscript/basicfunctions/httpworm.rst create mode 100644 doc/source/netscript/basicfunctions/isLogEnabled.rst create mode 100644 doc/source/netscript/basicfunctions/isRunning.rst create mode 100644 doc/source/netscript/basicfunctions/kill.rst create mode 100644 doc/source/netscript/basicfunctions/killall.rst create mode 100644 doc/source/netscript/basicfunctions/ls.rst create mode 100644 doc/source/netscript/basicfunctions/nFormat.rst create mode 100644 doc/source/netscript/basicfunctions/nuke.rst create mode 100644 doc/source/netscript/basicfunctions/peek.rst create mode 100644 doc/source/netscript/basicfunctions/print.rst create mode 100644 doc/source/netscript/basicfunctions/prompt.rst create mode 100644 doc/source/netscript/basicfunctions/ps.rst create mode 100644 doc/source/netscript/basicfunctions/purchaseServer.rst create mode 100644 doc/source/netscript/basicfunctions/read.rst create mode 100644 doc/source/netscript/basicfunctions/relaysmtp.rst create mode 100644 doc/source/netscript/basicfunctions/rm.rst create mode 100644 doc/source/netscript/basicfunctions/run.rst create mode 100644 doc/source/netscript/basicfunctions/scan.rst create mode 100644 doc/source/netscript/basicfunctions/scp.rst create mode 100644 doc/source/netscript/basicfunctions/scriptKill.rst create mode 100644 doc/source/netscript/basicfunctions/scriptRunning.rst create mode 100644 doc/source/netscript/basicfunctions/serverExists.rst create mode 100644 doc/source/netscript/basicfunctions/sleep.rst create mode 100644 doc/source/netscript/basicfunctions/spawn.rst create mode 100644 doc/source/netscript/basicfunctions/sprintf.rst create mode 100644 doc/source/netscript/basicfunctions/sqlinject.rst create mode 100644 doc/source/netscript/basicfunctions/tprint.rst create mode 100644 doc/source/netscript/basicfunctions/tryWrite.rst create mode 100644 doc/source/netscript/basicfunctions/vsprintf.rst create mode 100644 doc/source/netscript/basicfunctions/weaken.rst create mode 100644 doc/source/netscript/basicfunctions/wget.rst create mode 100644 doc/source/netscript/basicfunctions/write.rst create mode 100644 doc/source/netscript/bladeburnerapi/getActionAutolevel.rst create mode 100644 doc/source/netscript/bladeburnerapi/getActionCountRemaining.rst create mode 100644 doc/source/netscript/bladeburnerapi/getActionCurrentLevel.rst create mode 100644 doc/source/netscript/bladeburnerapi/getActionEstimatedSuccessChance.rst create mode 100644 doc/source/netscript/bladeburnerapi/getActionMaxLevel.rst create mode 100644 doc/source/netscript/bladeburnerapi/getActionRepGain.rst create mode 100644 doc/source/netscript/bladeburnerapi/getActionTime.rst create mode 100644 doc/source/netscript/bladeburnerapi/getBlackOpNames.rst create mode 100644 doc/source/netscript/bladeburnerapi/getBonusTime.rst create mode 100644 doc/source/netscript/bladeburnerapi/getCity.rst create mode 100644 doc/source/netscript/bladeburnerapi/getCityChaos.rst create mode 100644 doc/source/netscript/bladeburnerapi/getCityEstimatedCommunities.rst create mode 100644 doc/source/netscript/bladeburnerapi/getCityEstimatedPopulation.rst create mode 100644 doc/source/netscript/bladeburnerapi/getContractNames.rst create mode 100644 doc/source/netscript/bladeburnerapi/getCurrentAction.rst create mode 100644 doc/source/netscript/bladeburnerapi/getGeneralActionNames.rst create mode 100644 doc/source/netscript/bladeburnerapi/getOperationNames.rst create mode 100644 doc/source/netscript/bladeburnerapi/getRank.rst create mode 100644 doc/source/netscript/bladeburnerapi/getSkillLevel.rst create mode 100644 doc/source/netscript/bladeburnerapi/getSkillNames.rst create mode 100644 doc/source/netscript/bladeburnerapi/getSkillPoints.rst create mode 100644 doc/source/netscript/bladeburnerapi/getSkillUpgradeCost.rst create mode 100644 doc/source/netscript/bladeburnerapi/getStamina.rst create mode 100644 doc/source/netscript/bladeburnerapi/getTeamSize.rst create mode 100644 doc/source/netscript/bladeburnerapi/joinBladeburnerDivision.rst create mode 100644 doc/source/netscript/bladeburnerapi/joinBladeburnerFaction.rst create mode 100644 doc/source/netscript/bladeburnerapi/setActionAutolevel.rst create mode 100644 doc/source/netscript/bladeburnerapi/setActionLevel.rst create mode 100644 doc/source/netscript/bladeburnerapi/setTeamSize.rst create mode 100644 doc/source/netscript/bladeburnerapi/startAction.rst create mode 100644 doc/source/netscript/bladeburnerapi/stopBladeburnerAction.rst create mode 100644 doc/source/netscript/bladeburnerapi/switchCity.rst create mode 100644 doc/source/netscript/bladeburnerapi/upgradeSkill.rst create mode 100644 doc/source/netscript/codingcontractapi/attempt.rst create mode 100644 doc/source/netscript/codingcontractapi/getContractType.rst create mode 100644 doc/source/netscript/codingcontractapi/getData.rst create mode 100644 doc/source/netscript/codingcontractapi/getDescription.rst create mode 100644 doc/source/netscript/codingcontractapi/getNumTriesRemaining.rst create mode 100644 doc/source/netscript/gangapi/ascendMember.rst create mode 100644 doc/source/netscript/gangapi/canRecruitMember.rst create mode 100644 doc/source/netscript/gangapi/getBonusTime.rst create mode 100644 doc/source/netscript/gangapi/getChanceToWinClash.rst create mode 100644 doc/source/netscript/gangapi/getEquipmentCost.rst create mode 100644 doc/source/netscript/gangapi/getEquipmentNames.rst create mode 100644 doc/source/netscript/gangapi/getEquipmentType.rst create mode 100644 doc/source/netscript/gangapi/getGangInformation.rst create mode 100644 doc/source/netscript/gangapi/getMemberInformation.rst create mode 100644 doc/source/netscript/gangapi/getMemberNames.rst create mode 100644 doc/source/netscript/gangapi/getOtherGangInformation.rst create mode 100644 doc/source/netscript/gangapi/getTaskNames.rst create mode 100644 doc/source/netscript/gangapi/purchaseEquipment.rst create mode 100644 doc/source/netscript/gangapi/recruitMember.rst create mode 100644 doc/source/netscript/gangapi/setMemberTask.rst create mode 100644 doc/source/netscript/gangapi/setTerritoryWarfare.rst create mode 100644 doc/source/netscript/hacknetnodeapi/getCoreUpgradeCost.rst create mode 100644 doc/source/netscript/hacknetnodeapi/getLevelUpgradeCost.rst create mode 100644 doc/source/netscript/hacknetnodeapi/getNodeStats.rst create mode 100644 doc/source/netscript/hacknetnodeapi/getPurchaseNodeCost.rst create mode 100644 doc/source/netscript/hacknetnodeapi/getRamUpgradeCost.rst create mode 100644 doc/source/netscript/hacknetnodeapi/numNodes.rst create mode 100644 doc/source/netscript/hacknetnodeapi/purchaseNode.rst create mode 100644 doc/source/netscript/hacknetnodeapi/upgradeCore.rst create mode 100644 doc/source/netscript/hacknetnodeapi/upgradeLevel.rst create mode 100644 doc/source/netscript/hacknetnodeapi/upgradeRam.rst create mode 100644 doc/source/netscript/singularityfunctions/applyToCompany.rst create mode 100644 doc/source/netscript/singularityfunctions/checkFactionInvitations.rst create mode 100644 doc/source/netscript/singularityfunctions/commitCrime.rst create mode 100644 doc/source/netscript/singularityfunctions/createProgram.rst create mode 100644 doc/source/netscript/singularityfunctions/donateToFaction.rst create mode 100644 doc/source/netscript/singularityfunctions/getAugmentationCost.rst create mode 100644 doc/source/netscript/singularityfunctions/getAugmentationPrereq.rst create mode 100644 doc/source/netscript/singularityfunctions/getAugmentationsFromFaction.rst create mode 100644 doc/source/netscript/singularityfunctions/getCharacterInformation.rst create mode 100644 doc/source/netscript/singularityfunctions/getCompanyFavor.rst create mode 100644 doc/source/netscript/singularityfunctions/getCompanyFavorGain.rst create mode 100644 doc/source/netscript/singularityfunctions/getCompanyRep.rst create mode 100644 doc/source/netscript/singularityfunctions/getCrimeChance.rst create mode 100644 doc/source/netscript/singularityfunctions/getFactionFavor.rst create mode 100644 doc/source/netscript/singularityfunctions/getFactionFavorGain.rst create mode 100644 doc/source/netscript/singularityfunctions/getFactionRep.rst create mode 100644 doc/source/netscript/singularityfunctions/getOwnedAugmentations.rst create mode 100644 doc/source/netscript/singularityfunctions/getOwnedSourceFiles.rst create mode 100644 doc/source/netscript/singularityfunctions/getStats.rst create mode 100644 doc/source/netscript/singularityfunctions/getUpgradeHomeRamCost.rst create mode 100644 doc/source/netscript/singularityfunctions/gymWorkout.rst create mode 100644 doc/source/netscript/singularityfunctions/installAugmentations.rst create mode 100644 doc/source/netscript/singularityfunctions/isBusy.rst create mode 100644 doc/source/netscript/singularityfunctions/joinFaction.rst create mode 100644 doc/source/netscript/singularityfunctions/purchaseAugmentation.rst create mode 100644 doc/source/netscript/singularityfunctions/purchaseProgram.rst create mode 100644 doc/source/netscript/singularityfunctions/purchaseTor.rst create mode 100644 doc/source/netscript/singularityfunctions/stopAction.rst create mode 100644 doc/source/netscript/singularityfunctions/travelToCity.rst create mode 100644 doc/source/netscript/singularityfunctions/universityCourse.rst create mode 100644 doc/source/netscript/singularityfunctions/upgradeHomeRam.rst create mode 100644 doc/source/netscript/singularityfunctions/workForCompany.rst create mode 100644 doc/source/netscript/singularityfunctions/workForFaction.rst create mode 100644 doc/source/netscript/tixapi/buyStock.rst create mode 100644 doc/source/netscript/tixapi/cancelOrder.rst create mode 100644 doc/source/netscript/tixapi/getOrders.rst create mode 100644 doc/source/netscript/tixapi/getStockForecast.rst create mode 100644 doc/source/netscript/tixapi/getStockMaxShares.rst create mode 100644 doc/source/netscript/tixapi/getStockPosition.rst create mode 100644 doc/source/netscript/tixapi/getStockPrice.rst create mode 100644 doc/source/netscript/tixapi/getStockSymbols.rst create mode 100644 doc/source/netscript/tixapi/getStockVolatility.rst create mode 100644 doc/source/netscript/tixapi/placeOrder.rst create mode 100644 doc/source/netscript/tixapi/purchase4SMarketData.rst create mode 100644 doc/source/netscript/tixapi/purchase4SMarketDataTixApi.rst create mode 100644 doc/source/netscript/tixapi/sellShort.rst create mode 100644 doc/source/netscript/tixapi/sellStock.rst create mode 100644 doc/source/netscript/tixapi/shortStock.rst diff --git a/doc/source/advancedgameplay/sleeves.rst b/doc/source/advancedgameplay/sleeves.rst index 8bc9cfedd..a3db25f26 100644 --- a/doc/source/advancedgameplay/sleeves.rst +++ b/doc/source/advancedgameplay/sleeves.rst @@ -50,6 +50,16 @@ no shock. Shock affects the amount of experience earned by the sleeve. Sleeve shock slowly decreases over time. You can further increase the rate at which it decreases by assigning sleeves to the 'Shock Recovery' task. +Obtaining Duplicate Sleeves +~~~~~~~~~~~~~~~~~~~~~~~~~~~ +There are two methods of obtaining Duplicate Sleeves: + +1. Destroy BitNode-10. Each completion give you one additional Duplicate Sleeve +2. Purchase Duplicate Sleeves from :ref:`the faction The Covenant `. + This is only available in BitNodes-10 and above, and is only available after defeating + BitNode-10 at least once. Sleeves purchased this way are permanent. You can purchase + up to 5 Duplicate Sleeves from The Covenant. + Re-sleeving ^^^^^^^^^^^ Re-sleeving is the process of digitizing and transferring your consciousness into a @@ -64,4 +74,4 @@ Note that resleeving **REMOVES** all of your currently-installed Augmentations, and replaces them with the ones provided by the purchased sleeve. However, Augmentations that are purchased but not installed will **not** be removed. If you have purchased an Augmentation and then re-sleeve into a body which already has that Augmentation, -it will be removed since you cannot have duplicate Augmentations. +it will be removed since you cannot have duplicate Augmentations. diff --git a/doc/source/basicgameplay/augmentations.rst b/doc/source/basicgameplay/augmentations.rst index 483bb5168..a79dce68f 100644 --- a/doc/source/basicgameplay/augmentations.rst +++ b/doc/source/basicgameplay/augmentations.rst @@ -23,6 +23,8 @@ enough reputation in it, you will be able to purchase its Augmentations. Different Factions offer different Augmentations. Augmentations must be purchased in order to be installed, and they are fairly expensive. +.. _gameplay_augmentations_installing: + Installing Augmentations ^^^^^^^^^^^^^^^^^^^^^^^^ You will not gain the benefits of your purchased Augmentations until you @@ -57,6 +59,8 @@ Here is everything you will KEEP when you install an Augmentation: * RAM Upgrades on your home computer * World Stock Exchange account and TIX API Access +.. _gameplay_augmentations_purchasingmultiple: + Purchasing Multiple Augmentations ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ You do not have to install an Augmentation right after you purchase it. diff --git a/doc/source/basicgameplay/hacking.rst b/doc/source/basicgameplay/hacking.rst index cf7f837b8..6673ed695 100644 --- a/doc/source/basicgameplay/hacking.rst +++ b/doc/source/basicgameplay/hacking.rst @@ -49,6 +49,8 @@ on a server in order to successfully NUKE it:** Once you have enough ports opened on a server and have ran the NUKE virus to gain root access, you will be able to hack it. +.. _gameplay_hacking_generalhackingmechanics: + General Hacking Mechanics ^^^^^^^^^^^^^^^^^^^^^^^^^ When you execute the hack command, either manually through the terminal @@ -73,6 +75,8 @@ in your hacking (since you are only hacking a certain percentage). You can increase the amount of money on a server using a script and the :js:func:`grow` function in Netscript. +.. _gameplay_hacking_serversecurity: + Server Security ^^^^^^^^^^^^^^^ Each server has a security level, typically between 1 and 100. diff --git a/doc/source/basicgameplay/scripts.rst b/doc/source/basicgameplay/scripts.rst index f44919429..2eec791a5 100644 --- a/doc/source/basicgameplay/scripts.rst +++ b/doc/source/basicgameplay/scripts.rst @@ -37,6 +37,8 @@ name and the arguments that it was run with.** The arguments must be an **exact** match. This means that both the order and type of the arguments matter. +.. _gameplay_scripts_multithreadingscripts: + Multithreading scripts ^^^^^^^^^^^^^^^^^^^^^^ A script can be run with multiple threads. This is also called multithreading. diff --git a/doc/source/basicgameplay/terminal.rst b/doc/source/basicgameplay/terminal.rst index da1da41c3..c2f06d8b0 100644 --- a/doc/source/basicgameplay/terminal.rst +++ b/doc/source/basicgameplay/terminal.rst @@ -126,6 +126,8 @@ Both 'clear' and 'cls' do the same thing:: $ clear $ cls +.. _connect_terminal_command: + connect ^^^^^^^ @@ -165,8 +167,6 @@ Examples:: $ expr 3 ** 3 -Evalutes a - free ^^^^ @@ -193,6 +193,7 @@ detailed information about the Terminal command. Examples:: $ help alias $ help scan-analyze +.. _home_terminal_command: home ^^^^ @@ -346,6 +347,9 @@ scan Prints all immediately-available network connections. This will print a list of all servers that you can currently connect to using the 'connect' Terminal command. + +.. _scan_analyze_terminal_command: + scan-analyze ^^^^^^^^^^^^ @@ -364,6 +368,8 @@ The information 'scan-analyze' displays about each server includes whether or not you have root access to it, its required hacking level, the number of open ports required to run NUKE.exe on it, and how much RAM it has. +.. _scp_terminal_command: + scp ^^^ diff --git a/doc/source/guidesandtips/gettingstartedguideforbeginnerprogrammers.rst b/doc/source/guidesandtips/gettingstartedguideforbeginnerprogrammers.rst index 7d17e78b5..b2a1df285 100644 --- a/doc/source/guidesandtips/gettingstartedguideforbeginnerprogrammers.rst +++ b/doc/source/guidesandtips/gettingstartedguideforbeginnerprogrammers.rst @@ -28,20 +28,850 @@ entire "quest-line". First Steps ----------- I'm going to assume you followed the introductory tutorial when you first began the game. -In this introductory tutorial you created a script called `foodnstuff.script` and ran it -on the `foodnstuff` server. Right now, we'll kill this script. There are two ways +In this introductory tutorial you created a script called :code:`foodnstuff.script` and ran it +on the :code:`foodnstuff` server. Right now, we'll kill this script. There are two ways to do this: 1. You can go to the Terminal and enter:: $ kill foodnstuff.script -2. You can go to the "Active Scripts" page (:ref:`Keyboard shortcut ` Alt + s) and - press the "Kill Script" button for `foodnstuff.script`. +2. You can go to the :code:`Active Scripts` page (|Keyboard shortcut| Alt + s) and + press the "Kill Script" button for :code:`foodnstuff.script`. If you skipped the introductory tutorial, then ignore the part above. Instead, go to the -"Hacknet Nodes" page (:ref:`Keyboard shortcut ` Alt + h) and purchase a +:code:`Hacknet Nodes` page (|Keyboard shortcut| Alt + h) and purchase a Hacknet Node to start generating some passive income. -Creating our First Scripts +Creating our First Script +------------------------- +Now, we'll create a generic hacking script that can be used early on in the game (or throughout the +entire game, if you want). + +Before we write the script, here are some things you'll want to familiarize yourself with: + +* :ref:`gameplay_hacking_generalhackingmechanics` +* :ref:`gameplay_hacking_serversecurity` +* :js:func:`hack` +* :js:func:`grow` +* :js:func:`weaken` +* :js:func:`brutessh` +* :js:func:`nuke` + +To briefly summarize the information from the links above: Each server has a +security level that affects how difficult it is to hack. Each server also has a +certain amount of money, as well as a maximum amount of money it can hold. Hacking a +server steals a percentage of that server's money. The :js:func:`hack` Netscript function +is used to hack server. The :js:func:`grow` Netscript function is used to increase +the amount of money available on a server. The :js:func:`weaken` Netscript function is +used to decrease a server's security level. + +Now let's move on to actually creating the script. +Go to your home computer and then create a script called :code:`early-hack-template.script` by +going to Terminal and entering the following two commands:: + + $ home + $ nano early-hack-template.script + +This will take you to the script editor, which you can use to code and create +:ref:`gameplay_scripts`. It will be helpful to consult the :ref:`netscript` documentation. +Specifically, you'll want to take a look at :ref:`netscriptfunctions`. + +Enter the following code in the script editor: + +.. code:: javascript + + // Defines the "target server", which is the server + // that we're going to hack. In this case, it's "foodnstuff" + var target = "foodnstuff"; + + // Defines how much money a server should have before we hack it + // In this case, it is set to 75% of the server's max money + var moneyThresh = getServerMaxMoney(target) * 0.75; + + // Defines the maximum security level the target server can + // have. If the target's security level is higher than this, + // we'll weaken it before doing anything else + var securityThresh = getServerMinSecurityLevel(target) + 5; + + // If we have the BruteSSH.exe program, use it to open the SSH Port + // on the target server + if (fileExists("BruteSSH.exe", "home")) { + brutessh(target); + } + + // Get root access to target server + nuke(target); + + // Infinite loop that continously hacks/grows/weakens the target server + while(true) { + if (getServerSecurityLevel(target) > securityThresh) { + // If the server's security level is above our threshold, weaken it + weaken(target); + } else if (getServerMoneyAvailable(target) < moneyThresh) { + // If the server's money is less than our threshold, grow it + grow(target); + } else { + // Otherwise, hack it + hack(target); + } + } + +The script above contains comments that document what it does, but let's go through it +step-by-step anyways. + +.. code:: javascript + + var target = "foodnstuff"; + +This first command defines a string which contains our target server. That's the server +that we're going to hack. For now, it's set to `foodnstuff` because that's the only +server with a required hacking level of 1. If you want to hack a different server, +simply change this +variable to be the hostname of another server. + +.. code:: javascript + + var moneyThresh = getServerMaxMoney(target) * 0.75; + +This second command defines a numerical value representing the minimum +amount of money that must be available on the target server in order for our script +to hack it. If the money available on the target server is less than this value, +then our script will :js:func:`grow` the server rather than hacking it. +It is set to 75% of the maximum amount of money that can be available on the server. +The :js:func:`getServerMaxMoney` Netscript function is used to find this value + +.. code:: javascript + + var securityThresh = getServerMinSecurityLevel(target) + 5; + +This third command defines a numerical value representing the maximum security level +the target server can have. If the target server's security level is higher than +this value, then our script will :js:func:`weaken` the script before doing anything else. + +.. code:: javascript + + if (fileExists("BruteSSH.exe", "home")) { + brutessh(target); + } + + nuke(target); + +This section of code is used to gain root access on the target server. This is +necessary for hacking. See :ref:`here for more details `. + +.. code:: javascript + + while (true) { + if (getServerSecurityLevel(target) > securityThresh) { + // If the server's security level is above our threshold, weaken it + weaken(target); + } else if (getServerMoneyAvailable(target) < moneyThresh) { + // Otherwise, if the server's money is less than our threshold, grow it + grow(target); + } else { + // Otherwise, hack it + hack(target); + } + } + +This is the main section that drives our script. It dictates the script's logic +and carries out the hacking operations. The `while (true)` creates an infinite loop +that will continuously run the hacking logic until the the script is killed. + +Running our Scripts +------------------- +Now we want to start running our hacking script so that it can start earning us +money and experience. Our home computer only has 8GB of RAM and we'll be using it for +something else later. So instead, we'll take advantage of the RAM on other machines. + +Go to |Terminal| and enter the following command:: + + $ scan-analyze 2 + +This will show detailed information about some servers on the network. The +**network is randomized so it will be different for every person**. +Here's what mine showed at the time I made this:: + + [home ~]> scan-analyze 2 + ~~~~~~~~~~ Beginning scan-analyze ~~~~~~~~~~ + + >foodnstuff + --Root Access: NO, Required hacking skill: 1 + --Number of open ports required to NUKE: 0 + --RAM: 16 + + >sigma-cosmetics + --Root Access: NO, Required hacking skill: 5 + --Number of open ports required to NUKE: 0 + --RAM: 16 + + >joesguns + --Root Access: NO, Required hacking skill: 10 + --Number of open ports required to NUKE: 0 + --RAM: 16 + + ---->max-hardware + ------Root Access: NO, Required hacking skill: 80 + ------Number of open ports required to NUKE: 1 + ------RAM: 32 + + >hong-fang-tea + --Root Access: NO, Required hacking skill: 30 + --Number of open ports required to NUKE: 0 + --RAM: 16 + + ---->nectar-net + ------Root Access: NO, Required hacking skill: 20 + ------Number of open ports required to NUKE: 0 + ------RAM: 16 + + >harakiri-sushi + --Root Access: NO, Required hacking skill: 40 + --Number of open ports required to NUKE: 0 + --RAM: 16 + + >iron-gym + --Root Access: NO, Required hacking skill: 100 + --Number of open ports required to NUKE: 1 + --RAM: 32 + + ---->zer0 + ------Root Access: NO, Required hacking skill: 75 + ------Number of open ports required to NUKE: 1 + ------RAM: 32 + + ---->CSEC + ------Root Access: NO, Required hacking skill: 54 + ------Number of open ports required to NUKE: 1 + ------RAM: 8 + +Take note of the following servers: + +* |foodnstuff| +* |sigma-cosmetics| +* |joesguns| +* |nectar-net| +* |hong-fang-tea| +* |harakiri-sushi| + +All of these servers have 16GB of RAM. Furthermore, all of these servers do not require +any open ports in order to NUKE. In other words, we can gain root access to all of these +servers and then run scripts on them. + +First, let's determine how many threads of our hacking script we can run. +:ref:`Read more about multithreading scripts here ` +The script we wrote +uses 2.6GB of RAM. You can check this using the following |Terminal| command:: + + $ mem early-hack-template.script + +This means we can run 6 threads on a 16GB server. Now, to run our scripts on all of these +servers, we have to do the following: + +1. Use the :ref:`scp_terminal_command` |Terminal| command to copy our script to each server. +2. Use the :ref:`connect_terminal_command` |Terminal| command to connect to a server. +3. Use the :ref:`run_terminal_command` |Terminal| command to run the `NUKE.exe` program and + gain root access. +4. Use the :ref:`run_terminal_command` |Terminal| command again to run our script. +5. Repeat steps 2-4 for each server. + +Here's the sequence of |Terminal| commands I used in order to achieve this:: + + $ home + $ scp early-hack-template.script foodnstuff + $ scp early-hack-template.script sigma-cosmetics + $ scp early-hack-template.script joesguns + $ scp early-hack-template.script nectar-net + $ scp early-hack-template.script hong-fang-tea + $ scp early-hack-template.script harakiri-sushi + $ connect foodnstuff + $ run NUKE.exe + $ run early-hack-template.script -t 6 + $ home + $ connect sigma-cosmetics + $ run NUKE.exe + $ run early-hack-template.script -t 6 + $ home + $ connect joesguns + $ run NUKE.exe + $ run early-hack-template.script -t 6 + $ home + $ connect hong-fang-tea + $ run NUKE.exe + $ run early-hack-template.script -t 6 + $ home + $ connect harakiri-sushi + $ run NUKE.exe + $ run early-hack-template.script -t 6 + $ home + $ connect hong-fang-tea + $ connect nectar-net + $ run NUKE.exe + $ run early-hack-template.script -t 6 + +.. note:: + + Pressing the :code:`Tab` key in the middle of a Terminal command will attempt to + auto-complete the command. For example, if you type in :code:`scp ea` and then + hit :code:`Tab`, the rest of the script's name should automatically be filled in. + This works for most commands in the game! + +The :ref:`home_terminal_command` |Terminal| command is used to connect to the home +computer. When running our scripts with the :code:`run early-hack-template.script -t 6` +command, the :code:`-t 6` specifies that the script should be run with 6 threads. + +Note that the |nectar-net| server isn't in the home computer's immediate network. +This means you can't directly connect to it from home. You will have to search for it +inside the network. The results of the `scan-analyze 2` command we ran before +will show where it is. In my case, I could connect to it by going from +`hong-fang-tea -> nectar-net`. However, this will probably be different for you. + +After running all of these |Terminal| commands, our scripts are now up and running. +These will earn money and hacking experience over time. These gains will be +really slow right now, but they will increase once our hacking skill rises and +we start running more scripts. + +Increasing Hacking Level +------------------------ +There are many servers besides |foodnstuff| that can be hacked, but they have +higher required hacking levels. Therefore, we should raise our hacking level. Not only +will this let us hack more servers, but it will also increase the effectiveness of our hacking +against |foodnstuff|. + +The easiest way to train your hacking level is to visit Rothman University. You can do this by +clicking the `City` tab on the left-hand navigation menu, or you can use the +:ref:`keyboard shortcut ` Alt + w. Rothman University should be one of the buttons +near the top. Click the button to go to the location. + +Once you go to Rothman University, you should see a screen with several options. These +options describe different courses you can take. You should click the first button, which +says: "Study Computer Science (free)". + +After you click the button, you will start studying and earning hacking experience. While you +are doing this, you cannot interact with any other part of the game until you click the button +that says "Stop taking course". + +Right now, we want a hacking level of 10. You need approximately 174 hacking experience to reach +level 10. You can check how much hacking experience you have by clicking the `Stats` tab +on the left-hand navigation menu, or by using |Keyboard shortcut| Alt + c. +Since studying at Rothman University earns you 1 experience per second, this will take +174 seconds, or approximately 3 minutes. Feel free to do something in the meantime! + +Editing our Hacking Script -------------------------- +Now that we have a hacking level of 10, we can hack the :code:`joesguns` server. This server +will be slightly more profitable than :code:`foodnstuff`. Therefore, we want to change our hacking +script to target :code:`joesguns` instead of :code:`foodnstuff`. + +Go to |Terminal| and edit the hacking script by entering:: + + $ home + $ nano early-hack-template.script + +At the top of the script, change the `target` variable to be `joesguns`: + +.. code:: javascript + + var target = "joesguns"; + +Note that this will **NOT** affect any instances of the script that are already running. +This will only affect instances of the script that are ran from this point forward. + +Creating a New Script to Purchase New Servers +--------------------------------------------- +Next, we're going to create a script that automatically purchases additional servers. These +servers will be used to run many scripts. Running this script will initially be very +expensive since purchasing a server costs money, but it will pay off in the long run. + +In order to create this script, you should familiarize yourself with the following +Netscript functions: + +* :js:func:`purchaseServer` +* :js:func:`getPurchasedServerCost` +* :js:func:`getPurchasedServerLimit` +* :js:func:`getServerMoneyAvailable` +* :js:func:`scp` +* :js:func:`exec` + +Create the script by going to |Terminal| and typing:: + + $ home + $ nano purchase-server-8gb.script + +Paste the following code into the script editor: + +.. code:: javascript + + // How much RAM each purchased server will have. In this case, it'll + // be 8GB. + var ram = 8; + + // Iterator we'll use for our loop + var i = 0; + + // Continuously try to purchase servers until we've reached the maximum + // amount of servers + while (i < getPurchasedServerLimit()) { + // Check if we have enough money to purchase a server + if (getServerMoneyAvailable("home") > getPurchasedServerCost(ram)) { + // If we have enough money, then: + // 1. Purchase the server + // 2. Copy our hacking script onto the newly-purchased server + // 3. Run our hacking script on the newly-purchased server with 3 threads + // 4. Increment our iterator to indicate that we've bought a new server + var hostname = purchaseServer("pserv-" + i, ram); + scp("early-hack-template.script", hostname); + exec("early-hack-template.script", hostname, 3); + ++i; + } + } + +This code uses a while loop to purchase the maximum amount of servers using the +:js:func:`purchaseServer` Netscript function. Each of these servers will have +8GB of RAM, as defined in the :code:`ram` variable. Note that the script uses the command +:code:`getServerMoneyAvailable("home")` to get the amount of money you currently have. +This is then used to check if you can afford to purchase a server. + +Whenever the script purchases a new server, it uses the :js:func:`scp` function to copy +our script onto that new server, and then it uses the :js:func:`exec` function to +execute it on that server. + +To run this script, go to |Terminal| and type:: + + $ run purchase-server-8gb.script + +This purchase will continuously run until it has purchased the maximum number of servers. +When this happens, it'll mean that you have a bunch of new servers that are all running +hacking scripts against the :code:`joesguns` server! + +.. note:: + + The reason we're using so many scripts to hack :code:`joesguns` instead of targeting other + servers is because it's more effective. This early in the game, we don't have enough RAM + to efficiently hack multiple targets, and trying to do so would be slow as we'd be spread + too thin. You should definitely do this later on, though! + +Note that purchasing a server is fairly expensive, and purchasing the maximum amount of +servers even more so. At the time of writing this guide, the script above requires +$11 million in order to finish purchasing all of the 8GB servers. +Therefore, we need to find additional ways to make money to speed +up the process! These are covered in the next section. + +Additional Sources of Income +---------------------------- +There are other ways to gain money in this game besides scripts & hacking. + +Hacknet Nodes +^^^^^^^^^^^^^ +If you completed the introductory tutorial, you were already introduced to this method: Hacknet Nodes. +Once you have enough money, you can start upgrading your Hacknet Nodes in order to increase +your passive income stream. This is completely optional. Since each Hacknet Node upgrade +takes a certain amount of time to "pay itself off", it may not necessarily be in your best +interest to use these. + +Nonetheless, Hacknet Nodes are a good source of income early in the game, although +their effectiveness tapers off later on. If you do wind up purchasing and upgrading Hacknet Nodes, +I would suggest only upgrading their levels for now. I wouldn't bother with RAM and Core +upgrades until later on. + +Crime +^^^^^ +The best source of income right now is from :ref:`committing crimes `. +This is because it not only gives you a large amount of money, but it also raises your +hacking level. To commit crimes, click on the :code:`City` tab on the left-hand +navigation menu or use the |Keyboard shortcut| Alt + w. +Then, click on the link that says :code:`The Slums`. + +In the Slums, you can attempt to commit a variety of crimes, each of which gives certain +types of experience and money if successful. See :ref:`gameplay_crimes` for more details. + +.. note:: + + You are not always successful when you attempt to commit a crime. Nothing bad happens + if you fail a crime, but you won't earn any money and the experience gained will be + reduced. Raising your stats improves your chance of successfully committing a crime. + +Right now, the best option is the :code:`Rob Store` crime. This takes 60 seconds to attempt +and gives $400k if successful. I suggest this crime because you don't have to click or check +in too often since it takes a whole minute to attempt. Furthermore, it gives hacking experience, +which is very important right now. + +Alternatively, you can also use the :code:`Shoplift` crime. This takes 2 seconds to attempt +and gives $15k if successful. This crime is slightly easier and is more profitable +than :code:`Rob Store`, but it requires constant clicking and it doesn't give +hacking experience. + +Work for a Company +^^^^^^^^^^^^^^^^^^ +If you don't want to constantly check in on the game to commit crimes, there's another option +that's much more passive: working for a :ref:`company `. +This will not be nearly as profitable as crimes, but it's completely passive. + +Go to the :code:`City` tab on the left-hand navigation menu and then go to +:code:`Joe's Guns`. At :code:`Joe's Guns`, there will be an option that says +:code:`Apply to be an Employee`. Click this to get the job. Then, a new option +will appear that simply says :code:`Work`. Click this to start working. +Working at :code:`Joe's Guns` earns $110 per second and also grants some experience +for every stat except hacking. + +Working for a company is completely passive. However, you will not be able to do anything +else in the game while you work. You can cancel working at any time. You'll notice that +cancelling your work early causes you to lose out on some reputation gains, but +you shouldn't worry about this. Company reputation isn't important right now. + +Once your hacking hits level 75, you can visit :code:`Carmichael Security` in the city +and get a software job there. This job offers higher pay and also earns you +hacking experience. + +There are many more companies in the |City tab| that offer more pay and also more gameplay +features. Feel free to explore! + +After you Purchase your New Servers +----------------------------------- +After you've made a total of $11 million, your automatic server-purchasing script should +finish running. This will free up some RAM on your home computer. We don't want this RAM +to go to waste, so we'll make use of it. Go to |Terminal| and enter the following commands:: + + $ home + $ run early-hack-template.script -t 3 + +Reaching a Hacking Level of 50 +------------------------------ +Once you reach a hacking level of 50, two new important parts of the game open up. + +Creating your first program: BruteSSH.exe +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +On the left-hand navigation menu you will notice a :code:`Create Programs` tab with a +red notification icon. This indicates that there are programs available to be created. +Click on that tab (or use |Keyboard shortcut| Alt + p) and you'll see a +list of all the programs you can currently create. Hovering over a program will give a +brief description of its function. Simply click on a program to start creating it. + +Right now, the program we want to create is :code:`BruteSSH.exe`. This program is used +to open up SSH ports on servers. This will allow you to hack more servers, +as many servers in the game require a certain number of opened ports in order for +:code:`NUKE.exe` to gain root access. + +When you are creating a program, you cannot interact with any other part of the game. +Feel free to cancel your work on creating a program at any time, as your progress will +be saved and can be picked back up later. :code:`BruteSSH.exe` takes about +10 minutes to complete. + +Optional: Create AutoLink.exe +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +On the :code:`Create Programs` page, you will notice another program you can create +called :code:`AutoLink.exe`. If you don't mind waiting another 10-15 minutes, you should +go ahead and create this program. It makes it much less tedious to connect to other servers, +but it's not necessary for progressing. + +Joining your first faction: CyberSec +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Shortly after you reached level 50 hacking, you should have received a message that +said this:: + + Message received from unknown sender: + + 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 + + This message was saved as csec-test.msg onto your home computer. + +If you didn't, or if you accidentally closed it, that's okay! Messages get saved onto +your home computer. Enter the following |Terminal| commands to view the message:: + + $ home + $ cat csec-test.msg + +This message is part of the game's main "quest-line". It is a message from the +|CyberSec faction| that is asking you to pass their test. +Passing their test is simple, you just have to find their server and hack it through +the |Terminal|. Their server is called :code:`CSEC`. +To do this, we'll use the :ref:`scan_analyze_terminal_command` +Terminal command, just like we did before:: + + $ home + $ scan-analyze 2 + +This will show you the network for all servers that are up to 2 "nodes" away from +your home computer. Remember that the network is randomly generated so it'll look +different for everyone. Here's the relevant part of my :code:`scan-analyze` results:: + + >iron-gym + --Root Access: NO, Required hacking skill: 100 + --Number of open ports required to NUKE: 1 + --RAM: 32 + + ---->zer0 + ------Root Access: NO, Required hacking skill: 75 + ------Number of open ports required to NUKE: 1 + ------RAM: 32 + + ---->CSEC + ------Root Access: NO, Required hacking skill: 54 + ------Number of open ports required to NUKE: 1 + ------RAM: 8 + +This tells me that I can reach :code:`CSEC` by going through :code:`iron-gym`:: + + $ connect iron-gym + $ connect CSEC + +.. note:: + + If you created the :code:`AutoLink.exe` program earlier, then there is an easier + method of connecting to :code:`CSEC`. You'll notice that in the :code:`scan-analyze` + results, all of the server hostnames are white and underlined. You can simply + click one of the server hostnames in order to connect to it. So, simply click + :code:`CSEC`! + +.. note:: + + Make sure you notice the required hacking skill for the :code:`CSEC` server. + This is a random value between 51 and 60. Although you receive the message + from CSEC once you hit 50 hacking, you cannot actually pass their test + until your hacking is high enough to hack their server. + +After you are connected to the :code:`CSEC` server, you can hack it. Note that this +server requires one open port in order to gain root access. We can open the SSH port +using the :code:`BruteSSH.exe` program we created earlier. In |Terminal|:: + + $ run BruteSSH.exe + $ run NUKE.exe + $ hack + +Keep hacking the server until you are successful. After you successfully hack it, you should +receive a faction invitation from |CyberSec| shortly afterwards. Accept it. If you accidentally +reject the invitation, that's okay. Just go to the :code:`Factions` tab +(|Keyboard shortcut| Alt + f) and you should see an option that lets you +accept the invitation. + +Congrats! You just joined your first faction. Don't worry about doing anything +with this faction yet, we can come back to it later. + +Using Additional Servers to Hack Joesguns +----------------------------------------- +Once you have the |BruteSSH| program, you will be able to gain root access +to several additional servers. These servers have more RAM that you can use to +run scripts. We'll use the RAM on these servers to run more scripts that target +:code:`joesguns`. + +Copying our Scripts +^^^^^^^^^^^^^^^^^^^ +The server's we'll be using to run our scripts are: + +* :code:`neo-net` +* :code:`zer0` +* :code:`max-hardware` +* :code:`iron-gym` + +All of these servers have 32GB of RAM. You can use the |Terminal| command +:code:`scan-analyze 3` to see for yourself. To copy our hacking scripts onto these servers, +go to |Terminal| and run:: + + $ home + $ scp early-hack-template.script neo-net + $ scp early-hack-template.script zer0 + $ scp early-hack-template.script max-hardware + $ scp early-hack-template.script iron-gym + +Since each of these servers has 32GB of RAM, we can run our hacking script with 12 threads +on each server. By now, you should know how to connect to servers. So find and connect to +each of the servers above using the :code:`scan-analyze 3` |Terminal| command. Then, use +following |Terminal| command to run our hacking +script with 12 threads:: + + $ run early-hack-template.script -t 12 + +Remember that if you have the |AutoLink| program, you can simply click on the hostname of a server +after running :ref:`scan_analyze_terminal_command` to connect to it. + +Profiting from Scripts & Gaining Reputation with CyberSec +--------------------------------------------------------- +Now it's time to play the waiting game. It will take some time for your scripts to start +earning money. Remember that most of your scripts are targeting |joesguns|. It will take a +bit for them to :js:func:`grow` and :js:func:`weaken` the server to the appropriate values +before they start hacking it. Once they do, however, the scripts will be very profitable. + +.. note:: + + For reference, in about two hours after starting my first script, my scripts had a + production rate of $20k per second and had earned a total of $70 million. + (You can see these stats on the :code:`Active Scripts` tab). + + After another 15 minutes, the production rate had increased to $25k per second + and the scripts had made an additional $55 million. + + Your results will vary based on how fast you earned money from crime/working/hacknet nodes, + but this will hopefully give you a good indication of how much the scripts can earn. + +In the meantime, we are going to be gaining reputation with the |CyberSec faction|. +Go to the |Factions tab| on the left-hand +navigation menu, and from there select |CyberSec|. In the middle of +the page there should be a button for :code:`Hacking Contracts`. +Click it to start earning reputation for the |CyberSec| faction (as well +as some hacking experience). The higher your hacking level, the more reputation you +will gain. Note that while you are working for a faction, you cannot interact with +the rest of the game in any way. You can cancel your faction work at any time +with no penalty. + +Purchasing Upgrades and Augmentations +------------------------------------- +As I mentioned before, within 1-2 hours I had earned over $200 million. Now, it's time +to spend all of this money on some persistent upgrades to help progress! + +Upgrading RAM on Home computer +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The most important thing to upgrade right now is the RAM on your home computer. This +will allow you to run more scripts. + +To upgrade your RAM, go to the |City tab| and visit the company |Alpha Enterprises|. +There will be an option that says :code:`Purchase additional RAM for Home Computer`. +Click it and follow the dialog box to upgrade your RAM. + +I recommend getting your home computer's RAM to *at least* 128GB. Getting it even +higher would be better. + +Purchasing your First Augmentations +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Once you get ~1000 reputation with the |CyberSec faction|, you can purchase +your first :ref:`Augmentation ` from them. + +To do this, go to the |Factions tab| on the left-hand navigation menu +(|Keyboard shortcut| Alt + f) and select |CyberSec|. There is an button +near the bottom that says :code:`Purchase Augmentations`. This will bring up a +page that displays all of the Augmentations available from |CyberSec|. Some of them +may be locked right now. To unlock these, you will need to earn more +reputation with |CyberSec|. + +Augmentations give persistent upgrades in the form of multipliers. These aren't very +powerful early in the game because the multipliers are small. However, the effects +of Augmentations stack multiplicatively **with each other**, so as you continue to install +many Augmentations their effects will increase significantly. + +Because of this, I would recommend investing more in RAM upgrades for your home computer rather +than Augmentations early on. Having enough RAM to run many scripts will allow you to make +much more money, and then you can come back later on and get all these Augmentations. + +Right now, I suggest purchasing at the very least the :code:`Neurotrainer I` Augmentation from +|CyberSec|. If you have the money to spare, I would also suggest getting :code:`BitWire` and +several levels of the :code:`NeuroFlux Governor` Augmentations. Note that each time +you purchase an Augmentation, +:ref:`the price of purchasing another increases by 90% `, +so make sure you buy the most expensive Augmentation first. Don't worry, once you choose to +install Augmentations, their prices will reset back to their original values. + +Next Steps +---------- +That's the end of the walkthrough portion of this guide! You should continue to explore +what the game has to offer. There's quite a few features that aren't covered or mentioned +in this guide, and even more that get unlocked as you continue to play! + +Also, check out the :ref:`netscript` documentation to see what it has to offer. Writing +scripts to perform and automate various tasks is where most of the fun in the game comes +from (in my opinion)! + +The following are a few things you may want to consider doing in the near future. + +Installing Augmentations (and Resetting) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +If you've purchased any :ref:`gameplay_augmentations`, you'll need to install them before you +actually gain their effects. Installing Augmentations is the game's "soft-reset" or "prestige" +mechanic. You can :ref:`read more details about it here `. + +To install your Augmentations, click the |Augmentations tab| on the left-hand navigation +menu (|Keyboard shortcut| Alt + a). You will see a list of all of the Augmentations +you have purchased. Below that, you will see a button that says :code:`Install Augmentations`. +Be warned, after clicking this there is no way to undo it (unless you load an earlier save). + +Automating the Script Startup Process +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Whenever you install Augmentations, all of your scripts are killed and you'll have to +re-run them. Doing this every time you install Augmentations would be very tedious and annoying, +so you should write a script to automate the process. Here's a simple example for a +startup script. Feel free to adjust it to your liking. + +.. code:: javascript + + // Array of all servers that don't need any ports opened + // to gain root access. These have 16 GB of RAM + var servers0Port = ["foodnstuff", + "sigma-cosmetics", + "joesguns", + "nectar-net", + "hong-fang-tea", + "harakiri-sushi"]; + + // Array of all servers that only need 1 port opened + // to gain root access. These have 32 GB of RAM + var servers1Port = ["neo-net", + "zer0", + "max-hardware", + "iron-gym"]; + + // Copy our scripts onto each server that requires 0 ports + // to gain root access. Then use nuke() to gain admin access and + // run the scripts. + for (var i = 0; i < servers0Port.length; ++i) { + var serv = servers0Port[i]; + + scp("early-hack-template.script", serv); + nuke(serv); + exec("early-hack-template.script", serv, 6); + } + + // Wait until we acquire the "BruteSSH.exe" program + while (!fileExists("BruteSSH.exe")) { + sleep(60000); + } + + // Copy our scripts onto each server that requires 1 port + // to gain root access. Then use brutessh() and nuke() + // to gain admin access and run the scripts. + for (var i = 0; i < servers1Port.length; ++i) { + var serv = servers1Port[i]; + + scp("early-hack-template.script", serv); + brutessh(serv); + nuke(serv); + exec("early-hack-template.script", serv, 12); + } + +Random Tips +----------- +* Early on in the game, it's better to spend your money on upgrading RAM and purchasing + new servers rather than spending it on Augmentations +* The more money available on a server, the more effective the :js:func:`hack` and + :js:func:`grow` Netscript functions will be. This is because both of these functions + use percentages rather than flat values. :js:func:`hack` steals a percentage of a server's + total available money, and :js:func:`grow` increases a server's money by X%. +* There is a limit to how much money can exist on a server. This value is different for each + server. The :js:func:`getServerMaxMoney` function will tell you this maximum value. +* At this stage in the game, your combat stats (strength, defense, etc.) are not nearly + as useful as your hacking stat. Do not invest too much time or money into gaining combat + stat exp. + + + +.. Substitution definitions +.. |Alpha Enterprises| replace:: :code:`Alpha Enterprises` +.. |Augmentations tab| replace:: :code:`Augmentations` tab +.. |AutoLink| replace:: :code:`NUKE.exe` +.. |BruteSSH| replace:: :code:`BruteSSH.exe` +.. |City tab| replace:: :code:`City` tab +.. |CyberSec| replace:: :code:`CyberSec` +.. |CyberSec faction| replace:: :code:`CyberSec` :ref:`faction ` +.. |Factions tab| replace:: :code:`Factions` tab +.. |Keyboard shortcut| replace:: :ref:`Keyboard shortcut ` +.. |NUKE| replace:: :code:`NUKE.exe` +.. |Terminal| replace:: :code:`Terminal` +.. |foodnstuff| replace:: :code:`foodnstuff` +.. |harakiri-sushi| replace:: :code:`harakiri-sushi` +.. |hong-fang-tea| replace:: :code:`hong-fang-tea` +.. |joesguns| replace:: :code:`joesguns` +.. |nectar-net| replace:: :code:`nectar-net` +.. |sigma-cosmetics| replace:: :code:`sigma-cosmetics` diff --git a/doc/source/netscript/advancedfunctions/getBitNodeMultipliers.rst b/doc/source/netscript/advancedfunctions/getBitNodeMultipliers.rst new file mode 100644 index 000000000..9ac808ee1 --- /dev/null +++ b/doc/source/netscript/advancedfunctions/getBitNodeMultipliers.rst @@ -0,0 +1,20 @@ +getBitNodeMultipliers() Netscript Function +========================================== + +.. js:function:: getBitNodeMultipliers() + + Returns an object containing the current BitNode multipliers. This function requires Source-File 5 in order + to run. The multipliers are returned in decimal forms (e.g. 1.5 instead of 150%). The multipliers represent + the difference between the current BitNode and the original BitNode (BitNode-1). For example, if the + *CrimeMoney* multiplier has a value of 0.1, then that means that committing crimes in the current BitNode + will only give 10% of the money you would have received in BitNode-1. + + The structure of the returned object is subject to change as BitNode multipliers get added to the game. + Refer to the `source code here `_ + to see the name of the BitNode multipliers. + + Example:: + + mults = getBitNodeMultipliers(); + print(mults.ServerMaxMoney); + print(mults.HackExpGain); diff --git a/doc/source/netscript/advancedfunctions/getHackGrowWeakenTimes.rst b/doc/source/netscript/advancedfunctions/getHackGrowWeakenTimes.rst new file mode 100644 index 000000000..d07130126 --- /dev/null +++ b/doc/source/netscript/advancedfunctions/getHackGrowWeakenTimes.rst @@ -0,0 +1,15 @@ +getHackTime(), getGrowTime(), & getWeakenTime() +=============================================== + +The :js:func:`getHackTime`, :js:func:`getGrowTime`, and :js:func:`getWeakenTime` +all take an additional third optional parameter for specifying a specific intelligence +level to see how that would affect the hack/grow/weaken times. This parameter +defaults to your current intelligence level. + +(Intelligence is unlocked after obtaining Source-File 5). + +The function signatures are then:: + + getHackTime(hostname/ip[, hackLvl=current level, intLvl=current level]) + getGrowTime(hostname/ip[, hackLvl=current level, intLvl=current level]) + getWeakenTime(hostname/ip[, hackLvl=current level, intLvl=current level]) diff --git a/doc/source/netscript/basicfunctions/brutessh.rst b/doc/source/netscript/basicfunctions/brutessh.rst new file mode 100644 index 000000000..0b90ef061 --- /dev/null +++ b/doc/source/netscript/basicfunctions/brutessh.rst @@ -0,0 +1,13 @@ +brutessh() Netscript Function +============================= + +.. js:function:: brutessh(hostname/ip) + + :param string hostname/ip: IP or hostname of the target server + :RAM cost: 0 GB + + Runs the BruteSSH.exe program on the target server. BruteSSH.exe must exist on your home computer. + + Example:: + + brutessh("foodnstuff"); diff --git a/doc/source/netscript/basicfunctions/clear.rst b/doc/source/netscript/basicfunctions/clear.rst new file mode 100644 index 000000000..13f5393eb --- /dev/null +++ b/doc/source/netscript/basicfunctions/clear.rst @@ -0,0 +1,13 @@ +clear() Netscript Function +========================== + +.. js:function:: clear(port/fn) + + :param string/number port/fn: Port or text file to clear + :RAM cost: 1 GB + + This function is used to clear data in a `Netscript Ports `_ or a text file. + + If the *port/fn* argument is a number between 1 and 20, then it specifies a port and will clear it (deleting all data from the underlying queue). + + If the *port/fn* argument is a string, then it specifies the name of a text file (.txt) and will delete all data from that text file. diff --git a/doc/source/netscript/basicfunctions/clearLog.rst b/doc/source/netscript/basicfunctions/clearLog.rst new file mode 100644 index 000000000..96bcc694f --- /dev/null +++ b/doc/source/netscript/basicfunctions/clearLog.rst @@ -0,0 +1,8 @@ +clearLog() Netscript Function +============================= + +.. js:function:: clearLog() + + :RAM cost: 0 GB + + Clears the script's logs diff --git a/doc/source/netscript/basicfunctions/deleteServer.rst b/doc/source/netscript/basicfunctions/deleteServer.rst new file mode 100644 index 000000000..e1c400f62 --- /dev/null +++ b/doc/source/netscript/basicfunctions/deleteServer.rst @@ -0,0 +1,14 @@ +deleteServer() Netscript Function +================================= + +.. js:function:: deleteServer(hostname) + + :param string hostname: Hostname of the server to delete + :RAM cost: 2.25 GB + + Deletes one of your purchased servers, which is specified by its hostname. + + The *hostname* argument can be any data type, but it will be converted to a string. Whitespace is automatically removed from + the string. This function will not delete a server that still has scripts running on it. + + Returns true if successful, and false otherwise. diff --git a/doc/source/netscript/basicfunctions/disableLog.rst b/doc/source/netscript/basicfunctions/disableLog.rst new file mode 100644 index 000000000..dba73c24d --- /dev/null +++ b/doc/source/netscript/basicfunctions/disableLog.rst @@ -0,0 +1,16 @@ +disableLog() Netscript Function +=============================== + +.. js:function:: disableLog(fn) + + :param string fn: Name of function for which to disable logging + :RAM cost: 0 GB + + Disables logging for the given function. Logging can be disabled for + all functions by passing 'ALL' as the argument. + + Note that this does not completely remove all logging functionality. + This only stops a function from logging + when the function is successful. If the function fails, it will still log the reason for failure. + + Notable functions that cannot have their logs disabled: run, exec, exit diff --git a/doc/source/netscript/basicfunctions/enableLog.rst b/doc/source/netscript/basicfunctions/enableLog.rst new file mode 100644 index 000000000..46b445d53 --- /dev/null +++ b/doc/source/netscript/basicfunctions/enableLog.rst @@ -0,0 +1,10 @@ +enableLog() Netscript Function +============================= + +.. js:function:: enableLog(fn) + + :param string fn: Name of function for which to enable logging + :RAM cost: 0 GB + + Re-enables logging for the given function. If 'ALL' is passed into this function + as an argument, then it will revert the effects of disableLog('ALL') diff --git a/doc/source/netscript/basicfunctions/exec.rst b/doc/source/netscript/basicfunctions/exec.rst new file mode 100644 index 000000000..95967d933 --- /dev/null +++ b/doc/source/netscript/basicfunctions/exec.rst @@ -0,0 +1,34 @@ +exec() Netscript Function +========================= + +.. js:function:: exec(script, hostname/ip, [numThreads=1], [args...]) + + :param string script: Filename of script to execute + :param string hostname/ip: IP or hostname of the 'target server' on which to execute the script + :param number numThreads: Optional thread count for new script. Set to 1 by default. Will be rounded to nearest integer + :param args...: + Additional arguments to pass into the new script that is being run. Note that if any arguments are being + passed into the new script, then the third argument *numThreads* must be filled in with a value. + :RAM cost: 1.3 GB + + Run a script as a separate process on a specified server. This is similar to the *run* function except + that it can be used to run a script on any server, instead of just the current server. + + Returns true if the script is successfully started, and false otherwise. + + Running this function with a *numThreads* argument of 0 will return false without running the script. + However, running this function with a negative *numThreads* argument will cause a runtime error. + + The simplest way to use the *exec* command is to call it with just the script name and the target server. + The following example will try to run *generic-hack.script* on the *foodnstuff* server:: + + exec("generic-hack.script", "foodnstuff"); + + The following example will try to run the script *generic-hack.script* on the *joesguns* server with 10 threads:: + + exec("generic-hack.script", "joesguns", 10); + + This last example will try to run the script *foo.script* on the *foodnstuff* server with 5 threads. It will also pass + the number 1 and the string "test" in as arguments to the script:: + + exec("foo.script", "foodnstuff", 5, 1, "test"); diff --git a/doc/source/netscript/basicfunctions/exit.rst b/doc/source/netscript/basicfunctions/exit.rst new file mode 100644 index 000000000..64b8f4c44 --- /dev/null +++ b/doc/source/netscript/basicfunctions/exit.rst @@ -0,0 +1,8 @@ +exit() Netscript Function +========================= + +.. js:function:: exit() + + :RAM cost: 0 GB + + Terminates the current script immediately diff --git a/doc/source/netscript/basicfunctions/fileExists.rst b/doc/source/netscript/basicfunctions/fileExists.rst new file mode 100644 index 000000000..a14478a94 --- /dev/null +++ b/doc/source/netscript/basicfunctions/fileExists.rst @@ -0,0 +1,25 @@ +fileExists() Netscript Function +=============================== + +.. js:function:: fileExists(filename, [hostname/ip]) + + :param string filename: Filename of file to check + :param string hostname/ip: + Hostname or IP of target server. This is optional. If it is not specified then the + function will use the current server as the target server + :RAM cost: 0.1 GB + + Returns a boolean indicating whether the specified file exists on the target server. The filename + for scripts is case-sensitive, but for other types of files it is not. For example, *fileExists("brutessh.exe")* + will work fine, even though the actual program is named "BruteSSH.exe". + + If the *hostname/ip* argument is omitted, then the function will search through the current server (the server + running the script that calls this function) for the file. + + Examples:: + + fileExists("foo.script", "foodnstuff"); + fileExists("ftpcrack.exe"); + + The first example above will return true if the script named *foo.script* exists on the *foodnstuff* server, and false otherwise. + The second example above will return true if the current server contains the *FTPCrack.exe* program, and false otherwise. diff --git a/doc/source/netscript/basicfunctions/ftpcrack.rst b/doc/source/netscript/basicfunctions/ftpcrack.rst new file mode 100644 index 000000000..c3301a155 --- /dev/null +++ b/doc/source/netscript/basicfunctions/ftpcrack.rst @@ -0,0 +1,13 @@ +ftpcrack() Netscript Function +============================= + +.. js:function:: ftpcrack(hostname/ip) + + :param string hostname/ip: IP or hostname of the target server + :RAM cost: 0 GB + + Runs the FTPCrack.exe program on the target server. FTPCrack.exe must exist on your home computer. + + Example:: + + ftpcrack("foodnstuff"); diff --git a/doc/source/netscript/basicfunctions/getFavorToDonate.rst b/doc/source/netscript/basicfunctions/getFavorToDonate.rst new file mode 100644 index 000000000..8c9feb203 --- /dev/null +++ b/doc/source/netscript/basicfunctions/getFavorToDonate.rst @@ -0,0 +1,8 @@ +getFavorToDonate() Netscript Function +===================================== + +.. js:function:: getFavorToDonate() + + :RAM cost: 0.1 GB + + Returns the amount of Faction favor required to be able to donate to a faction. diff --git a/doc/source/netscript/basicfunctions/getGrowTime.rst b/doc/source/netscript/basicfunctions/getGrowTime.rst new file mode 100644 index 000000000..adaf4f842 --- /dev/null +++ b/doc/source/netscript/basicfunctions/getGrowTime.rst @@ -0,0 +1,13 @@ +getGrowTime() Netscript Function +================================ + +.. js:function:: getGrowTime(hostname/ip[, hackLvl=current level]) + + :param string hostname/ip: Hostname or IP of target server + :param number hackLvl: Optional hacking level for the calculation. Defaults to player's current hacking level + :RAM cost: 0.05 GB + + Returns the amount of time in seconds it takes to execute the *grow()* Netscript function on the target server. + + The function takes in an optional *hackLvl* parameter that can be specified + to see what the grow time would be at different hacking levels. diff --git a/doc/source/netscript/basicfunctions/getHackTime.rst b/doc/source/netscript/basicfunctions/getHackTime.rst new file mode 100644 index 000000000..1372111e3 --- /dev/null +++ b/doc/source/netscript/basicfunctions/getHackTime.rst @@ -0,0 +1,13 @@ +getHackTime() Netscript Function +================================ + +.. js:function:: getHackTime(hostname/ip[, hackLvl=current level]) + + :param string hostname/ip: Hostname or IP of target server + :param number hackLvl: Optional hacking level for the calculation. Defaults to player's current hacking level + :RAM cost: 0.05 GB + + Returns the amount of time in seconds it takes to execute the *hack()* Netscript function on the target server. + + The function takes in an optional *hackLvl* parameter that can be specified + to see what the hack time would be at different hacking levels. diff --git a/doc/source/netscript/basicfunctions/getHackingLevel.rst b/doc/source/netscript/basicfunctions/getHackingLevel.rst new file mode 100644 index 000000000..f87e324b6 --- /dev/null +++ b/doc/source/netscript/basicfunctions/getHackingLevel.rst @@ -0,0 +1,8 @@ +getHackingLevel() Netscript Function +==================================== + +.. js:function:: getHackingLevel() + + :RAM cost: 0.05 GB + + Returns the player's current hacking level diff --git a/doc/source/netscript/basicfunctions/getHackingMultipliers.rst b/doc/source/netscript/basicfunctions/getHackingMultipliers.rst new file mode 100644 index 000000000..37032122e --- /dev/null +++ b/doc/source/netscript/basicfunctions/getHackingMultipliers.rst @@ -0,0 +1,22 @@ +getHackingMultipliers() Netscript Function +========================================== + +.. js:function:: getHackingMultipliers() + + :RAM cost: 4 GB + + Returns an object containing the Player's hacking related multipliers. These multipliers are + returned in decimal forms, not percentages (e.g. 1.5 instead of 150%). The object has the following structure:: + + { + chance: Player's hacking chance multiplier, + speed: Player's hacking speed multiplier, + money: Player's hacking money stolen multiplier, + growth: Player's hacking growth multiplier + } + + Example of how this can be used:: + + mults = getHackingMultipliers(); + print(mults.chance); + print(mults.growth); diff --git a/doc/source/netscript/basicfunctions/getHacknetMultipliers.rst b/doc/source/netscript/basicfunctions/getHacknetMultipliers.rst new file mode 100644 index 000000000..d37eda610 --- /dev/null +++ b/doc/source/netscript/basicfunctions/getHacknetMultipliers.rst @@ -0,0 +1,23 @@ +getHacknetMultipliers() Netscript Function +========================================== + +.. js:function:: getHacknetMultipliers() + + :RAM cost: 4 GB + + Returns an object containing the Player's hacknet related multipliers. These multipliers are + returned in decimal forms, not percentages (e.g. 1.5 instead of 150%). The object has the following structure:: + + { + production: Player's hacknet production multiplier, + purchaseCost: Player's hacknet purchase cost multiplier, + ramCost: Player's hacknet ram cost multiplier, + coreCost: Player's hacknet core cost multiplier, + levelCost: Player's hacknet level cost multiplier + } + + Example of how this can be used:: + + mults = getHacknetMultipliers(); + print(mults.production); + print(mults.purchaseCost); diff --git a/doc/source/netscript/basicfunctions/getHostname.rst b/doc/source/netscript/basicfunctions/getHostname.rst new file mode 100644 index 000000000..6e14224cd --- /dev/null +++ b/doc/source/netscript/basicfunctions/getHostname.rst @@ -0,0 +1,8 @@ +getHostname() Netscript Function +================================ + +.. js:function:: getHostname() + + :RAM cost: 0.05 GB + + Returns a string with the hostname of the server that the script is running on diff --git a/doc/source/netscript/basicfunctions/getPortHandle.rst b/doc/source/netscript/basicfunctions/getPortHandle.rst new file mode 100644 index 000000000..a0a6ed05c --- /dev/null +++ b/doc/source/netscript/basicfunctions/getPortHandle.rst @@ -0,0 +1,11 @@ +getPortHandle() Netscript Function +================================== + +.. js:function:: getPortHandle(port) + + :param number port: Port number + :RAM cost: 10 GB + + Get a handle to a Netscript Port. See more details here: :ref:`netscript_ports` + + **WARNING:** Port Handles only work in :ref:`netscriptjs`. They will not work in :ref:`netscript1`. diff --git a/doc/source/netscript/basicfunctions/getPurchasedServerCost.rst b/doc/source/netscript/basicfunctions/getPurchasedServerCost.rst new file mode 100644 index 000000000..764baa309 --- /dev/null +++ b/doc/source/netscript/basicfunctions/getPurchasedServerCost.rst @@ -0,0 +1,16 @@ +getPurchasedServerCost() Netscript Function +=========================================== + +.. js:function:: getPurchasedServerCost(ram) + + :RAM cost: 0.25 GB + + :param number ram: Amount of RAM of a potential purchased server. Must be a power of 2 (2, 4, 8, 16, etc.). Maximum value of 1048576 (2^20) + + Returns the cost to purchase a server with the specified amount of *ram*. + + Examples:: + + for (i = 1; i <= 20; i++) { + tprint(i + " -- " + getPurchasedServerCost(Math.pow(2, i))); + } diff --git a/doc/source/netscript/basicfunctions/getPurchasedServerLimit.rst b/doc/source/netscript/basicfunctions/getPurchasedServerLimit.rst new file mode 100644 index 000000000..7784203dc --- /dev/null +++ b/doc/source/netscript/basicfunctions/getPurchasedServerLimit.rst @@ -0,0 +1,8 @@ +getPurchasedServerLimit() Netscript Function +============================================ + +.. js:function:: getPurchasedServerLimit() + + :RAM cost: 0.05 GB + + Returns the maximum number of servers you can purchase diff --git a/doc/source/netscript/basicfunctions/getPurchasedServerMaxRam.rst b/doc/source/netscript/basicfunctions/getPurchasedServerMaxRam.rst new file mode 100644 index 000000000..844e7ba18 --- /dev/null +++ b/doc/source/netscript/basicfunctions/getPurchasedServerMaxRam.rst @@ -0,0 +1,8 @@ +getPurchasedServerMaxRam() Netscript Function +============================================= + +.. js:function:: getPurchasedServerMaxRam() + + :RAM cost: 0.05 GB + + Returns the maximum RAM that a purchased server can have diff --git a/doc/source/netscript/basicfunctions/getPurchasedServers.rst b/doc/source/netscript/basicfunctions/getPurchasedServers.rst new file mode 100644 index 000000000..89b3cfedc --- /dev/null +++ b/doc/source/netscript/basicfunctions/getPurchasedServers.rst @@ -0,0 +1,11 @@ +getPurchasedServers() Netscript Function +======================================== + +.. js:function:: getPurchasedServers([hostname=true]) + + :param boolean hostname: + Specifies whether hostnames or IP addresses should be returned. If it's true then hostnames will be returned, and if false + then IPs will be returned. If this argument is omitted then it is true by default + :RAM cost: 2.25 GB + + Returns an array with either the hostnames or IPs of all of the servers you have purchased. diff --git a/doc/source/netscript/basicfunctions/getScriptExpGain.rst b/doc/source/netscript/basicfunctions/getScriptExpGain.rst new file mode 100644 index 000000000..65f6f9c86 --- /dev/null +++ b/doc/source/netscript/basicfunctions/getScriptExpGain.rst @@ -0,0 +1,14 @@ +getScriptExpGain() Netscript Function +===================================== + +.. js:function:: getScriptExpGain([scriptname], [hostname/ip], [args...]) + + :param string scriptname: Filename of script + :param string hostname/ip: Server on which script is running + :param args...: Arguments that the script is running with + :RAM cost: 0.1 GB + + Returns the amount of hacking experience the specified script generates while online (when the game is open, does not apply for offline experience gains). + Remember that a script is uniquely identified by both its name and its arguments. + + This function can also return the total experience gain rate of all of your active scripts by running the function with no arguments. diff --git a/doc/source/netscript/basicfunctions/getScriptIncome.rst b/doc/source/netscript/basicfunctions/getScriptIncome.rst new file mode 100644 index 000000000..e3496c015 --- /dev/null +++ b/doc/source/netscript/basicfunctions/getScriptIncome.rst @@ -0,0 +1,18 @@ +getScriptIncome() Netscript Function +==================================== + +.. js:function:: getScriptIncome([scriptname], [hostname/ip], [args...]) + + :param string scriptname: Filename of script + :param string hostname/ip: Server on which script is running + :param args...: Arguments that the script is running with + :RAM cost: 0.1 GB + + Returns the amount of income the specified script generates while online (when the game is open, does not apply for offline income). + Remember that a script is uniquely identified by both its name and its arguments. So for example if you ran a script with the arguments + "foodnstuff" and "5" then in order to use this function to get that script's income you must specify those same arguments in the same order + in this function call. + + This function can also be called with no arguments. If called with no arguments, then this function will return an array of two values. The + first value is the total income ($ / second) of all of your active scripts (scripts that are currently running on any server). The second value + is the total income ($ / second) that you've earned from scripts since you last installed Augmentations. diff --git a/doc/source/netscript/basicfunctions/getScriptLogs.rst b/doc/source/netscript/basicfunctions/getScriptLogs.rst new file mode 100644 index 000000000..ac721c4d3 --- /dev/null +++ b/doc/source/netscript/basicfunctions/getScriptLogs.rst @@ -0,0 +1,33 @@ +getScriptLogs() Netscript Function +================================== + +.. js:function:: getScriptLogs([fn], [hostname/ip=current ip], [args...]) + + :param string fn: Optional. Filename of script to get logs from. + :param string ip: Optional. IP or hostname of the server that the script is on + :param args...: Arguments to identify which scripts to get logs for + :RAM cost: 0 GB + + Returns a script's logs. The logs are returned as an array, where each + line is an element in the array. The most recently logged line is at the + end of the array. + + Note that there is a maximum number of lines that a script stores in its logs. + This is configurable in the game's options. + + If the function is called with no arguments, it will return the current script's logs. + + Otherwise, the `fn`, `hostname/ip,` and `args...` arguments can be used to get the logs + from another script. Remember that scripts are uniquely identified by both + their names and arguments. + + Examples:: + + // Get logs from foo.script on the current server that was run with no args + getScriptLogs("foo.script"); + + // Get logs from foo.script on the foodnstuff server that was run with no args + getScriptLogs("foo.script", "foodnstuff"); + + // Get logs from foo.script on the foodnstuff server that was run with the arguments [1, "test"] + getScriptLogs("foo.script", "foodnstuff", 1, "test"); diff --git a/doc/source/netscript/basicfunctions/getScriptName.rst b/doc/source/netscript/basicfunctions/getScriptName.rst new file mode 100644 index 000000000..cc7de660b --- /dev/null +++ b/doc/source/netscript/basicfunctions/getScriptName.rst @@ -0,0 +1,8 @@ +getScriptName() Netscript Function +================================== + +.. js:function:: getScriptName() + + :RAM cost: 0 GB + + Returns the current script name diff --git a/doc/source/netscript/basicfunctions/getScriptRam.rst b/doc/source/netscript/basicfunctions/getScriptRam.rst new file mode 100644 index 000000000..373599c37 --- /dev/null +++ b/doc/source/netscript/basicfunctions/getScriptRam.rst @@ -0,0 +1,11 @@ +getScriptRam() Netscript Function +=========================== + +.. js:function:: getScriptRam(scriptname[, hostname/ip]) + + :param string scriptname: Filename of script. This is case-sensitive. + :param string hostname/ip: Hostname or IP of target server the script is located on. This is optional, If it is not specified then the function will set the current server as the target server. + :RAM cost: 0.1 GB + + Returns the amount of RAM required to run the specified script on the target server. Returns + 0 if the script does not exist. diff --git a/doc/source/netscript/basicfunctions/getServerBaseSecurityLevel.rst b/doc/source/netscript/basicfunctions/getServerBaseSecurityLevel.rst new file mode 100644 index 000000000..162ee4c38 --- /dev/null +++ b/doc/source/netscript/basicfunctions/getServerBaseSecurityLevel.rst @@ -0,0 +1,12 @@ +getServerBaseSecurityLevel() Netscript Function +=============================================== + +.. js:function:: getServerBaseSecurityLevel(hostname/ip) + + :param string hostname/ip: Hostname or IP of target server + :RAM cost: 0.1 GB + + Returns the base security level of the target server. This is the security level that the server starts out with. + This is different than *getServerSecurityLevel()* because *getServerSecurityLevel()* returns the current + security level of a server, which can constantly change due to *hack()*, *grow()*, and *weaken()*, calls on that + server. The base security level will stay the same until you reset by installing an Augmentation(s). diff --git a/doc/source/netscript/basicfunctions/getServerGrowth.rst b/doc/source/netscript/basicfunctions/getServerGrowth.rst new file mode 100644 index 000000000..8fbdd3d45 --- /dev/null +++ b/doc/source/netscript/basicfunctions/getServerGrowth.rst @@ -0,0 +1,12 @@ +getServerGrowth() Netscript Function +==================================== + +.. js:function:: getServerGrowth(hostname/ip) + + :param string hostname/ip: Hostname or IP of target server + :RAM cost: 0.1 GB + + Returns the server's instrinsic "growth parameter". This growth parameter is a number + between 1 and 100 that represents how quickly the server's money grows. This parameter affects the + percentage by which the server's money is increased when using the *grow()* function. A higher + growth parameter will result in a higher percentage increase from *grow()*. diff --git a/doc/source/netscript/basicfunctions/getServerMaxMoney.rst b/doc/source/netscript/basicfunctions/getServerMaxMoney.rst new file mode 100644 index 000000000..c9feeb8be --- /dev/null +++ b/doc/source/netscript/basicfunctions/getServerMaxMoney.rst @@ -0,0 +1,9 @@ +getServerMaxMoney() Netscript Function +====================================== + +.. js:function:: getServerMaxMoney(hostname/ip) + + :param string hostname/ip: Hostname or IP of target server + :RAM cost: 0.1 GB + + Returns the maximum amount of money that can be available on a server diff --git a/doc/source/netscript/basicfunctions/getServerMinSecurityLevel.rst b/doc/source/netscript/basicfunctions/getServerMinSecurityLevel.rst new file mode 100644 index 000000000..7036c0f7e --- /dev/null +++ b/doc/source/netscript/basicfunctions/getServerMinSecurityLevel.rst @@ -0,0 +1,9 @@ +getServerMinSecurityLevel() Netscript Function +============================================== + +.. js:function:: getServerMinSecurityLevel(hostname/ip) + + :param string hostname/ip: Hostname or IP of target server + :RAM cost: 0.1 GB + + Returns the minimum security level of the target server diff --git a/doc/source/netscript/basicfunctions/getServerMoneyAvailable.rst b/doc/source/netscript/basicfunctions/getServerMoneyAvailable.rst new file mode 100644 index 000000000..55b909396 --- /dev/null +++ b/doc/source/netscript/basicfunctions/getServerMoneyAvailable.rst @@ -0,0 +1,15 @@ +getServerMoneyAvailable() Netscript Function +============================================ + +.. js:function:: getServerMoneyAvailable(hostname/ip) + + :param string hostname/ip: Hostname or IP of target server + :RAM cost: 0.1 GB + + Returns the amount of money available on a server. **Running this function on the home computer will return + the player's money.** + + Example:: + + getServerMoneyAvailable("foodnstuff"); + getServerMoneyAvailable("home"); //Returns player's money diff --git a/doc/source/netscript/basicfunctions/getServerNumPortsRequired.rst b/doc/source/netscript/basicfunctions/getServerNumPortsRequired.rst new file mode 100644 index 000000000..1f05a6141 --- /dev/null +++ b/doc/source/netscript/basicfunctions/getServerNumPortsRequired.rst @@ -0,0 +1,9 @@ +getServerNumPortsRequired() Netscript Function +============================================== + +.. js:function:: getServerNumPortsRequired(hostname/ip) + + :param string hostname/ip: Hostname or IP of target server + :RAM cost: 0.1 GB + + Returns the number of open ports required to successfully run NUKE.exe on the specified server. diff --git a/doc/source/netscript/basicfunctions/getServerRam.rst b/doc/source/netscript/basicfunctions/getServerRam.rst new file mode 100644 index 000000000..a8a8cb200 --- /dev/null +++ b/doc/source/netscript/basicfunctions/getServerRam.rst @@ -0,0 +1,17 @@ +getServerRam() Netscript Function +================================= + +.. js:function:: getServerRam(hostname/ip) + + :param string hostname/ip: Hostname or IP of target server + :RAM cost: 0.1 GB + + Returns an array with two elements that gives information about a server's memory (RAM). The first + element in the array is the amount of RAM that the server has total (in GB). The second element in + the array is the amount of RAM that is currently being used on the server (in GB). + + Example:: + + res = getServerRam("helios"); + totalRam = res[0]; + ramUsed = res[1]; diff --git a/doc/source/netscript/basicfunctions/getServerRequiredHackingLevel.rst b/doc/source/netscript/basicfunctions/getServerRequiredHackingLevel.rst new file mode 100644 index 000000000..122c5b41e --- /dev/null +++ b/doc/source/netscript/basicfunctions/getServerRequiredHackingLevel.rst @@ -0,0 +1,9 @@ +getServerRequiredHackingLevel() Netscript Function +================================================== + +.. js:function:: getServerRequiredHackingLevel(hostname/ip) + + :param string hostname/ip: Hostname or IP of target server + :RAM cost: 0.1 GB + + Returns the required hacking level of the target server diff --git a/doc/source/netscript/basicfunctions/getServerSecurityLevel.rst b/doc/source/netscript/basicfunctions/getServerSecurityLevel.rst new file mode 100644 index 000000000..a2c612170 --- /dev/null +++ b/doc/source/netscript/basicfunctions/getServerSecurityLevel.rst @@ -0,0 +1,10 @@ +getServerSecurityLevel() Netscript Function +=========================================== + +.. js:function:: getServerSecurityLevel(hostname/ip) + + :param string hostname/ip: Hostname or IP of target server + :RAM cost: 0.1 GB + + Returns the security level of the target server. A server's security level is denoted by a number, typically + between 1 and 100 (but it can go above 100). diff --git a/doc/source/netscript/basicfunctions/getTimeSinceLastAug.rst b/doc/source/netscript/basicfunctions/getTimeSinceLastAug.rst new file mode 100644 index 000000000..b81d48482 --- /dev/null +++ b/doc/source/netscript/basicfunctions/getTimeSinceLastAug.rst @@ -0,0 +1,8 @@ +getTimeSinceLastAug() Netscript Function +======================================== + +.. js:function:: getTimeSinceLastAug() + + :RAM cost: 0.05 GB + + Returns the amount of time in milliseconds that have passed since you last installed Augmentations diff --git a/doc/source/netscript/basicfunctions/getWeakenTime.rst b/doc/source/netscript/basicfunctions/getWeakenTime.rst new file mode 100644 index 000000000..e13e7408e --- /dev/null +++ b/doc/source/netscript/basicfunctions/getWeakenTime.rst @@ -0,0 +1,13 @@ +getWeakenTime() Netscript Function +================================== + +.. js:function:: getWeakenTime(hostname/ip[, hackLvl=current level]) + + :param string hostname/ip: Hostname or IP of target server + :param number hackLvl: Optional hacking level for the calculation. Defaults to player's current hacking level + :RAM cost: 0.05 GB + + Returns the amount of time in seconds it takes to execute the *weaken()* Netscript function on the target server. + + The function takes in an optional *hackLvl* parameter that can be specified + to see what the weaken time would be at different hacking levels. diff --git a/doc/source/netscript/basicfunctions/grow.rst b/doc/source/netscript/basicfunctions/grow.rst new file mode 100644 index 000000000..9ab819462 --- /dev/null +++ b/doc/source/netscript/basicfunctions/grow.rst @@ -0,0 +1,21 @@ +grow() Netscript Function +========================= + +.. js:function:: grow(hostname/ip) + + :param string hostname/ip: IP or hostname of the target server to grow + :returns: The number by which the money on the server was multiplied for the growth + :RAM cost: 0.15 GB + + Use your hacking skills to increase the amount of money available on a server. The runtime for this command depends on your hacking + level and the target server's security level. When grow() completes, the money available on a target server will be increased by a + certain, fixed percentage. This percentage is determined by the target server's growth rate (which varies between servers) and security level. + Generally, higher-level servers have higher growth rates. The getServerGrowth() function can be used to obtain a server's growth rate. + + Like hack(), grow() can be called on any server, regardless of where the script is running. The grow() command requires + root access to the target server, but there is no required hacking level to run the command. It also raises the security level + of the target server by 0.004. + + Example:: + + grow("foodnstuff"); diff --git a/doc/source/netscript/basicfunctions/growthAnalyze.rst b/doc/source/netscript/basicfunctions/growthAnalyze.rst new file mode 100644 index 000000000..4414dbcfa --- /dev/null +++ b/doc/source/netscript/basicfunctions/growthAnalyze.rst @@ -0,0 +1,24 @@ +growthAnalyze() Netscript Function +================================== + +.. js:function:: growthAnalyze(hostname/ip, growthAmount) + + :param string hostname/ip: IP or hostname of server to analyze + :param number growthAmount: Multiplicative factor by which the server is grown. Decimal form. + :returns: The amount of grow() calls needed to grow the specified server by the specified amount + :RAM cost: 1 GB + + This function returns the number of "growths" needed in order to increase the amount + of money available on the specified server by the specified amount. + + The specified amount is multiplicative and is in decimal form, not percentage. + + For example, if you want to determine how many `grow()` calls you need + to double the amount of money on `foodnstuff`, you would use:: + + growthAnalyze("foodnstuff", 2); + + If this returns 100, then this means you need to call `grow()` 100 times + in order to double the money (or once with 100 threads). + + **Warning**: The value returned by this function isn't necessarily a whole number. diff --git a/doc/source/netscript/basicfunctions/hack.rst b/doc/source/netscript/basicfunctions/hack.rst new file mode 100644 index 000000000..a62c85a3d --- /dev/null +++ b/doc/source/netscript/basicfunctions/hack.rst @@ -0,0 +1,22 @@ +hack() Netscript Function +========================= + +.. js:function:: hack(hostname/ip) + + :param string hostname/ip: IP or hostname of the target server to hack + :returns: The amount of money stolen if the hack is successful, and zero otherwise + :RAM cost: 0.1 GB + + Function that is used to try and hack servers to steal money and gain hacking experience. The runtime for this command depends + on your hacking level and the target server's security level. In order to hack a server you must first gain root access + to that server and also have the required hacking level. + + A script can hack a server from anywhere. It does not need to be running on the same server to hack that server. For example, + you can create a script that hacks the 'foodnstuff' server and run that script on any server in the game. + + A successful hack() on a server will raise that server's security level by 0.002. + + Example:: + + hack("foodnstuff"); + hack("10.1.2.3"); diff --git a/doc/source/netscript/basicfunctions/hackAnalyzePercent.rst b/doc/source/netscript/basicfunctions/hackAnalyzePercent.rst new file mode 100644 index 000000000..b0a64236c --- /dev/null +++ b/doc/source/netscript/basicfunctions/hackAnalyzePercent.rst @@ -0,0 +1,20 @@ +hackAnalyzePercent() Netscript Function +======================================= + +.. js:function:: hackAnalyzePercent(hostname/ip) + + :param string hostname/ip: IP or hostname of target server + :returns: The percentage of money you will steal from the target server with a single hack + :RAM cost: 1 GB + + Returns the percentage of the specified server's money you will steal with a + single hack. This value is returned in **percentage form, not decimal (Netscript + functions typically return in decimal form, but not this one).** + + For example, assume the following returns 1:: + + hackAnalyzePercent("foodnstuff"); + + This means that if hack the `foodnstuff` server, then you will steal 1% of its + total money. If you `hack()` using N threads, then you will steal N% of its total + money. diff --git a/doc/source/netscript/basicfunctions/hackAnalyzeThreads.rst b/doc/source/netscript/basicfunctions/hackAnalyzeThreads.rst new file mode 100644 index 000000000..97ae1803c --- /dev/null +++ b/doc/source/netscript/basicfunctions/hackAnalyzeThreads.rst @@ -0,0 +1,24 @@ +hackAnalyzeThreads() Netscript Function +======================================= + +.. js:function:: hackAnalyzeThreads(hostname/ip, hackAmount) + + :param string hostname/ip: IP or hostname of server to analyze + :param number hackAmount: Amount of money you want to hack from the server + :returns: The number of threads needed to hack() the server for *hackAmount* money + :RAM cost: 1 GB + + This function returns the number of script threads you need when running + the `hack()` command to steal the specified amount of money from the target server. + + If `hackAmount` is less than zero or greater than the amount of money available + on the server, then this function returns -1. + + For example, let's say the `foodnstuff` server has $10m and you run:: + + hackAnalyzeThreads("foodnstuff", 1e6); + + If this function returns 50, this means that if your next `hack()` call + is run on a script with 50 threads, it will steal $1m from the `foodnstuff` server. + + **Warning**: The value returned by this function isn't necessarily a whole number. diff --git a/doc/source/netscript/basicfunctions/hackChance.rst b/doc/source/netscript/basicfunctions/hackChance.rst new file mode 100644 index 000000000..714b8ef44 --- /dev/null +++ b/doc/source/netscript/basicfunctions/hackChance.rst @@ -0,0 +1,11 @@ +hackChance() Netscript Function +=============================== + +.. js:function:: hackChance(hostname/ip) + + :param string hostname/ip: IP or hostname of target server + :returns: The chance you have of successfully hacking the target server + :RAM cost: 1 GB + + Returns the chance you have of successfully hacking the specified server. This + returned value is in decimal form, not percentage. diff --git a/doc/source/netscript/basicfunctions/hasRootAccess.rst b/doc/source/netscript/basicfunctions/hasRootAccess.rst new file mode 100644 index 000000000..ee561eb7b --- /dev/null +++ b/doc/source/netscript/basicfunctions/hasRootAccess.rst @@ -0,0 +1,15 @@ +hasRootAccess() Netscript Function +================================== + +.. js:function:: hasRootAccess(hostname/ip) + + :param string hostname/ip: Hostname or IP of the target server + :RAM cost: 0.05 GB + + Returns a boolean indicating whether or not the player has root access to the specified target server. + + Example:: + + if (hasRootAccess("foodnstuff") == false) { + nuke("foodnstuff"); + } diff --git a/doc/source/netscript/basicfunctions/httpworm.rst b/doc/source/netscript/basicfunctions/httpworm.rst new file mode 100644 index 000000000..599c25ca8 --- /dev/null +++ b/doc/source/netscript/basicfunctions/httpworm.rst @@ -0,0 +1,13 @@ +httpworm() Netscript Function +============================= + +.. js:function:: httpworm(hostname/ip) + + :param string hostname/ip: IP or hostname of the target server + :RAM cost: 0 GB + + Runs the HTTPWorm.exe program on the target server. HTTPWorm.exe must exist on your home computer. + + Example:: + + httpworm("foodnstuff"); diff --git a/doc/source/netscript/basicfunctions/isLogEnabled.rst b/doc/source/netscript/basicfunctions/isLogEnabled.rst new file mode 100644 index 000000000..8967b4cf7 --- /dev/null +++ b/doc/source/netscript/basicfunctions/isLogEnabled.rst @@ -0,0 +1,10 @@ +isLogEnabled() Netscript Function +================================= + +.. js:function:: isLogEnabled(fn) + + :param string fn: Name of function to check + :RAM cost: 0 GB + + Returns a boolean indicating whether or not logging is enabled for that + function (or 'ALL') diff --git a/doc/source/netscript/basicfunctions/isRunning.rst b/doc/source/netscript/basicfunctions/isRunning.rst new file mode 100644 index 000000000..41afdd46a --- /dev/null +++ b/doc/source/netscript/basicfunctions/isRunning.rst @@ -0,0 +1,29 @@ +isRunning() Netscript Function +============================== + +.. js:function:: isRunning(filename, hostname/ip, [args...]) + + :param string filename: Filename of script to check. This is case-sensitive. + :param string hostname/ip: Hostname or IP of target server + :param args...: Arguments to specify/identify which scripts to search for + :RAM cost: 0.1 GB + + Returns a boolean indicating whether the specified script is running on the target server. Remember that a script is + uniquely identified by both its name and its arguments. + + **Examples:** + + In this first example below, the function call will return true if there is a script named *foo.script* with no arguments + running on the *foodnstuff* server, and false otherwise:: + + isRunning("foo.script", "foodnstuff"); + + In this second example below, the function call will return true if there is a script named *foo.script* with no arguments + running on the current server, and false otherwise:: + + isRunning("foo.script", getHostname()); + + In this next example below, the function call will return true if there is a script named *foo.script* running with the arguments + 1, 5, and "test" (in that order) on the *joesguns* server, and false otherwise:: + + isRunning("foo.script", "joesguns", 1, 5, "test"); diff --git a/doc/source/netscript/basicfunctions/kill.rst b/doc/source/netscript/basicfunctions/kill.rst new file mode 100644 index 000000000..3c3579836 --- /dev/null +++ b/doc/source/netscript/basicfunctions/kill.rst @@ -0,0 +1,29 @@ +kill() Netscript Function +========================= + +.. js:function:: kill(script, hostname/ip, [args...]) + + :param string script: Filename of the script to kill + :param string hostname/ip: IP or hostname of the server on which to kill the script + :param args...: Arguments to identify which script to kill + :RAM cost: 0.5 GB + + Kills the script on the target server specified by the script's name and arguments. Remember that scripts + are uniquely identified by both their name and arguments. For example, if *foo.script* is run with the argument 1, then this + is not the same as *foo.script* run with the argument 2, even though they have the same code. + + If this function successfully kills the specified script, then it will return true. Otherwise, it will return false. + + Examples: + + The following example will try to kill a script named *foo.script* on the *foodnstuff* server that was ran with no arguments:: + + kill("foo.script", "foodnstuff"); + + The following will try to kill a script named *foo.script* on the current server that was ran with no arguments:: + + kill("foo.script", getHostname()); + + The following will try to kill a script named *foo.script* on the current server that was ran with the arguments 1 and "foodnstuff":: + + kill("foo.script", getHostname(), 1, "foodnstuff"); diff --git a/doc/source/netscript/basicfunctions/killall.rst b/doc/source/netscript/basicfunctions/killall.rst new file mode 100644 index 000000000..5e1cd87a0 --- /dev/null +++ b/doc/source/netscript/basicfunctions/killall.rst @@ -0,0 +1,10 @@ +killall() Netscript Function +============================ + +.. js:function:: killall(hostname/ip) + + :param string hostname/ip: IP or hostname of the server on which to kill all scripts + :RAM cost: 0.5 GB + + Kills all running scripts on the specified server. This function returns true if any scripts were killed, and + false otherwise. In other words, it will return true if there are any scripts running on the target server. diff --git a/doc/source/netscript/basicfunctions/ls.rst b/doc/source/netscript/basicfunctions/ls.rst new file mode 100644 index 000000000..6055dece3 --- /dev/null +++ b/doc/source/netscript/basicfunctions/ls.rst @@ -0,0 +1,11 @@ +ls() Netscript Function +======================= + +.. js:function:: ls(hostname/ip, [grep]) + + :param string hostname/ip: Hostname or IP of the target server + :param string grep: a substring to search for in the filename + :RAM cost: 0 GB + + Returns an array with the filenames of all files on the specified server (as strings). The returned array + is sorted in alphabetic order diff --git a/doc/source/netscript/basicfunctions/nFormat.rst b/doc/source/netscript/basicfunctions/nFormat.rst new file mode 100644 index 000000000..280d1ca80 --- /dev/null +++ b/doc/source/netscript/basicfunctions/nFormat.rst @@ -0,0 +1,19 @@ +nFormat() Netscript Function +============================ + +.. js:function:: nFormat(n, format) + + :param number n: Number to format + :param string format: Formatter + + Converts a number into a string with the specified formatter. This uses the + `numeraljs `_ library, so the formatters must be compatible + with that. + + This is the same function that the game itself uses to display numbers. + + Examples:: + + nFormat(1.23e9, "$0.000a"); // Returns "$1.230b" + nFormat(12345.678, "0,0"); // Returns "12,346" + nFormat(0.84, "0.0%"); // Returns "84.0% diff --git a/doc/source/netscript/basicfunctions/nuke.rst b/doc/source/netscript/basicfunctions/nuke.rst new file mode 100644 index 000000000..ec951bcc1 --- /dev/null +++ b/doc/source/netscript/basicfunctions/nuke.rst @@ -0,0 +1,13 @@ +nuke() Netscript Function +========================= + +.. js:function:: nuke(hostname/ip) + + :param string hostname/ip: IP or hostname of the target server + :RAM cost: 0 GB + + Runs the NUKE.exe program on the target server. NUKE.exe must exist on your home computer. + + Example:: + + nuke("foodnstuff"); diff --git a/doc/source/netscript/basicfunctions/peek.rst b/doc/source/netscript/basicfunctions/peek.rst new file mode 100644 index 000000000..c118f4307 --- /dev/null +++ b/doc/source/netscript/basicfunctions/peek.rst @@ -0,0 +1,12 @@ +peek() Netscript Function +========================= + +.. js:function:: peek(port) + + :param number port: Port to peek. Must be an integer between 1 and 20 + :RAM cost: 1 GB + + This function is used to peek at the data from a port. It returns the first element in the specified port + without removing that element. If the port is empty, the string "NULL PORT DATA" will be returned. + + Read about how :ref:`netscript_ports` work here diff --git a/doc/source/netscript/basicfunctions/print.rst b/doc/source/netscript/basicfunctions/print.rst new file mode 100644 index 000000000..b50ec4666 --- /dev/null +++ b/doc/source/netscript/basicfunctions/print.rst @@ -0,0 +1,9 @@ +print() Netscript Function +=========================== + +.. js:function:: print(x) + + :param x: Value to be printed + :RAM cost: 0 GB + + Prints a value or a variable to the script's logs. diff --git a/doc/source/netscript/basicfunctions/prompt.rst b/doc/source/netscript/basicfunctions/prompt.rst new file mode 100644 index 000000000..24c2cc7cf --- /dev/null +++ b/doc/source/netscript/basicfunctions/prompt.rst @@ -0,0 +1,10 @@ +prompt() Netscript Function +=========================== + +.. js:function:: prompt(txt) + + :param string txt: Text to appear in the prompt dialog box + :RAM cost: 0 GB + + Prompts the player with a dialog box with two options: "Yes" and "No". This function will return true if the player click "Yes" and + false if the player clicks "No". The script's execution is halted until the player selects one of the options. diff --git a/doc/source/netscript/basicfunctions/ps.rst b/doc/source/netscript/basicfunctions/ps.rst new file mode 100644 index 000000000..fcdf2583a --- /dev/null +++ b/doc/source/netscript/basicfunctions/ps.rst @@ -0,0 +1,28 @@ +ps() Netscript Function +======================= + +.. js:function:: ps(hostname/ip=current ip) + + :param string ip: Hostname or IP address of the target server. + If not specified, it will be the current server's IP by default + :RAM cost: 0.2 GB + + Returns an array with general information about all scripts running on the specified + target server. The information for each server is given in an object with + the following structure:: + + { + filename: Script name, + threads: Number of threads script is running with, + args: Script's arguments + } + + Example usage (using :ref:`netscriptjs`):: + + export async function main(ns) { + const ps = ns.ps("home"); + for (let i = 0; i < ps.length; ++i) { + ns.tprint(ps[i].filename + ' ' + ps[i].threads); + ns.tprint(ps[i].args); + } + } diff --git a/doc/source/netscript/basicfunctions/purchaseServer.rst b/doc/source/netscript/basicfunctions/purchaseServer.rst new file mode 100644 index 000000000..caa316550 --- /dev/null +++ b/doc/source/netscript/basicfunctions/purchaseServer.rst @@ -0,0 +1,30 @@ +purchaseServer() Netscript Function +=================================== + +.. js:function:: purchaseServer(hostname, ram) + + :param string hostname: Hostname of the purchased server + :param number ram: Amount of RAM of the purchased server. Must be a power of 2 (2, 4, 8, 16, etc.). Maximum value of 1048576 (2^20) + :RAM cost: 2.25 GB + + Purchased a server with the specified hostname and amount of RAM. + + The *hostname* argument can be any data type, but it will be converted to a string and have whitespace removed. Anything that resolves to an empty string will + cause the function to fail. If there is already a server with the specified hostname, then the function will automatically append + a number at the end of the *hostname* argument value until it finds a unique hostname. For example, if the script calls + *purchaseServer("foo", 4)* but a server named "foo" already exists, the it will automatically change the hostname to "foo-0". If there is already + a server with the hostname "foo-0", then it will change the hostname to "foo-1", and so on. + + Note that there is a maximum limit to the amount of servers you can purchase. + + Returns the hostname of the newly purchased server as a string. If the function fails to purchase a server, then it will return an + empty string. The function will fail if the arguments passed in are invalid, if the player does not have enough money to purchase + the specified server, or if the player has exceeded the maximum amount of servers. + + Example:: + + ram = 64; + hn = "pserv-"; + for (i = 0; i < 5; ++i) { + purchaseServer(hn + i, ram); + } diff --git a/doc/source/netscript/basicfunctions/read.rst b/doc/source/netscript/basicfunctions/read.rst new file mode 100644 index 000000000..21f1cd693 --- /dev/null +++ b/doc/source/netscript/basicfunctions/read.rst @@ -0,0 +1,16 @@ +read() Netscript Function +========================= + +.. js:function:: read(port/fn) + + :param string/number port/fn: Port or text file to read from + :RAM cost: 1 GB + + This function is used to read data from a port, a text file (.txt), or a script (.script, .js, .ns) + + If the argument *port/fn* is a number between 1 and 20, then it specifies a port and it will read data from that port. Read + about how :ref:`netscript_ports` work here. A port is a serialized queue. This function + will remove the first element from that queue and return it. If the queue is empty, then the string "NULL PORT DATA" will be returned. + + If the argument *port/fn* is a string, then it specifies the name of a text file or script and this function will return the data in the specified text file/script. If + the text file does not exist, an empty string will be returned. diff --git a/doc/source/netscript/basicfunctions/relaysmtp.rst b/doc/source/netscript/basicfunctions/relaysmtp.rst new file mode 100644 index 000000000..b3f4a95f2 --- /dev/null +++ b/doc/source/netscript/basicfunctions/relaysmtp.rst @@ -0,0 +1,13 @@ +relaysmtp() Netscript Function +============================== + +.. js:function:: relaysmtp(hostname/ip) + + :param string hostname/ip: IP or hostname of the target server + :RAM cost: 0 GB + + Runs the relaySMTP.exe program on the target server. relaySMTP.exe must exist on your home computer. + + Example:: + + relaysmtp("foodnstuff"); diff --git a/doc/source/netscript/basicfunctions/rm.rst b/doc/source/netscript/basicfunctions/rm.rst new file mode 100644 index 000000000..e5c64bdfc --- /dev/null +++ b/doc/source/netscript/basicfunctions/rm.rst @@ -0,0 +1,11 @@ +rm() Netscript Function +======================= + +.. js:function:: rm(fn[, hostname/ip=current server]) + + :param string fn: Filename of file to remove. Must include the extension + :param string hostname/ip: Hostname or IP Address of the server on which to delete the file. Optional. Defaults to current server + :returns: True if it successfully deletes the file, and false otherwise + :RAM cost: 1 GB + + Removes the specified file from the current server. This function works for every file type except message (.msg) files. diff --git a/doc/source/netscript/basicfunctions/run.rst b/doc/source/netscript/basicfunctions/run.rst new file mode 100644 index 000000000..b4b9a414e --- /dev/null +++ b/doc/source/netscript/basicfunctions/run.rst @@ -0,0 +1,33 @@ +run() Netscript Function +======================== + +.. js:function:: run(script, [numThreads=1], [args...]) + + :param string script: Filename of script to run + :param number numThreads: Optional thread count for new script. Set to 1 by default. Will be rounded to nearest integer + :param args...: + Additional arguments to pass into the new script that is being run. Note that if any arguments are being + passed into the new script, then the second argument *numThreads* must be filled in with a value. + :RAM cost: 1 GB + + Run a script as a separate process. This function can only be used to run scripts located on the current server (the server + running the script that calls this function). + + Returns true if the script is successfully started, and false otherwise. + + Running this function with a *numThreads* argument of 0 will return false without running the script. + However, running this function with a negative *numThreads* argument will cause a runtime error. + + The simplest way to use the *run* command is to call it with just the script name. The following example will run + 'foo.script' single-threaded with no arguments:: + + run("foo.script"); + + The following example will run 'foo.script' but with 5 threads instead of single-threaded:: + + run("foo.script", 5); + + This next example will run 'foo.script' single-threaded, and will pass the string 'foodnstuff' into the script + as an argument:: + + run("foo.script", 1, 'foodnstuff'); diff --git a/doc/source/netscript/basicfunctions/scan.rst b/doc/source/netscript/basicfunctions/scan.rst new file mode 100644 index 000000000..a3412d260 --- /dev/null +++ b/doc/source/netscript/basicfunctions/scan.rst @@ -0,0 +1,11 @@ +scan() Netscript Function +========================= + +.. js:function:: scan(hostname/ip=current ip[, hostnames=true]) + + :param string hostname/ip: IP or hostname of the server to scan + :param boolean: Optional boolean specifying whether the function should output hostnames (if true) or IP addresses (if false) + :RAM cost: 0.2 GB + + Returns an array containing the hostnames or IPs of all servers that are one node way from the specified target server. The + hostnames/IPs in the returned array are strings. diff --git a/doc/source/netscript/basicfunctions/scp.rst b/doc/source/netscript/basicfunctions/scp.rst new file mode 100644 index 000000000..a290083fa --- /dev/null +++ b/doc/source/netscript/basicfunctions/scp.rst @@ -0,0 +1,29 @@ +scp() Netscript Function +======================== + +.. js:function:: scp(files, [source], destination) + + :param string/array files: Filename or an array of filenames of script/literature files to copy + :param string source: + Hostname or IP of the source server, which is the server from which the file will be copied. + This argument is optional and if it's omitted the source will be the current server. + :param string destination: Hostname or IP of the destination server, which is the server to which the file will be copied. + :RAM cost: 0.6 GB + + Copies a script or literature (.lit) file(s) to another server. The *files* argument can be either a string specifying a + single file to copy, or an array of strings specifying multiple files to copy. + + Returns true if the script/literature file is successfully copied over and false otherwise. If the *files* argument is an array + then this function will return true if at least one of the files in the array is successfully copied. + + Examples:: + + //Copies hack-template.script from the current server to foodnstuff + scp("hack-template.script", "foodnstuff"); + + //Copies foo.lit from the helios server to the home computer + scp("foo.lit", "helios", "home"); + + //Tries to copy three files from rothman-uni to home computer + files = ["foo1.lit", "foo2.script", "foo3.script"]; + scp(files, "rothman-uni", "home"); diff --git a/doc/source/netscript/basicfunctions/scriptKill.rst b/doc/source/netscript/basicfunctions/scriptKill.rst new file mode 100644 index 000000000..767e48322 --- /dev/null +++ b/doc/source/netscript/basicfunctions/scriptKill.rst @@ -0,0 +1,11 @@ +scriptKill() Netscript Function +=============================== + +.. js:function:: scriptKill(scriptname, hostname/ip) + + :param string scriptname: Filename of script to kill. This is case-sensitive. + :param string hostname/ip: Hostname or IP of target server + :RAM cost: 1 GB + + Kills all scripts with the specified filename on the target server specified by *hostname/ip*, regardless of arguments. Returns + true if one or more scripts were successfully killed, and false if none were. diff --git a/doc/source/netscript/basicfunctions/scriptRunning.rst b/doc/source/netscript/basicfunctions/scriptRunning.rst new file mode 100644 index 000000000..a384ea35e --- /dev/null +++ b/doc/source/netscript/basicfunctions/scriptRunning.rst @@ -0,0 +1,24 @@ +scriptRunning() Netscript Function +================================== + +.. js:function:: scriptRunning(scriptname, hostname/ip) + + :param string scriptname: Filename of script to check. This is case-sensitive. + :param string hostname/ip: Hostname or IP of target server + :RAM cost: 1 GB + + Returns a boolean indicating whether any instance of the specified script is running on the target server, regardless of + its arguments. + + This is different than the *isRunning()* function because it does not try to identify a specific instance of a running script + by its arguments. + + **Examples:** + + The example below will return true if there is any script named *foo.script* running on the *foodnstuff* server, and false otherwise:: + + scriptRunning("foo.script", "foodnstuff"); + + The example below will return true if there is any script named "foo.script" running on the current server, and false otherwise:: + + scriptRunning("foo.script", getHostname()); diff --git a/doc/source/netscript/basicfunctions/serverExists.rst b/doc/source/netscript/basicfunctions/serverExists.rst new file mode 100644 index 000000000..c32dab411 --- /dev/null +++ b/doc/source/netscript/basicfunctions/serverExists.rst @@ -0,0 +1,9 @@ +serverExists() Netscript Function +================================= + +.. js:function:: serverExists(hostname/ip) + + :param string hostname/ip: Hostname or IP of target server + :RAM cost: 0.1 GB + + Returns a boolean denoting whether or not the specified server exists diff --git a/doc/source/netscript/basicfunctions/sleep.rst b/doc/source/netscript/basicfunctions/sleep.rst new file mode 100644 index 000000000..b9109a9cb --- /dev/null +++ b/doc/source/netscript/basicfunctions/sleep.rst @@ -0,0 +1,9 @@ +sleep() Netscript Function +========================== + +.. js:function:: sleep(n) + + :param number n: Number of milliseconds to sleep + :RAM cost: 0 GB + + Suspends the script for n milliseconds. diff --git a/doc/source/netscript/basicfunctions/spawn.rst b/doc/source/netscript/basicfunctions/spawn.rst new file mode 100644 index 000000000..c0fe044ce --- /dev/null +++ b/doc/source/netscript/basicfunctions/spawn.rst @@ -0,0 +1,20 @@ +spawn() Netscript Function +========================== + +.. js:function:: spawn(script, numThreads, [args...]) + + :param string script: Filename of script to execute + :param number numThreads: Number of threads to spawn new script with. Will be rounded to nearest integer + :param args...: + Additional arguments to pass into the new script that is being run. + :RAM cost: 2 GB + + Terminates the current script, and then after a delay of about 20 seconds it will execute the newly-specified script. + The purpose of this function is to execute a new script without being constrained by the RAM usage of the current one. + This function can only be used to run scripts on the local server. + + Because this function immediately terminates the script, it does not have a return value. + + The following example will execute the script 'foo.script' with 10 threads and the arguments 'foodnstuff' and 90:: + + spawn('foo.script', 10, 'foodnstuff', 90); diff --git a/doc/source/netscript/basicfunctions/sprintf.rst b/doc/source/netscript/basicfunctions/sprintf.rst new file mode 100644 index 000000000..2ea752682 --- /dev/null +++ b/doc/source/netscript/basicfunctions/sprintf.rst @@ -0,0 +1,8 @@ +sprintf() Netscript Function +============================ + +.. js:function:: sprintf() + + :RAM cost: 0 GB + + See `this link `_ for details. diff --git a/doc/source/netscript/basicfunctions/sqlinject.rst b/doc/source/netscript/basicfunctions/sqlinject.rst new file mode 100644 index 000000000..4eab8dd6a --- /dev/null +++ b/doc/source/netscript/basicfunctions/sqlinject.rst @@ -0,0 +1,13 @@ +sqlinject() Netscript Function +============================== + +.. js:function:: sqlinject(hostname/ip) + + :param string hostname/ip: IP or hostname of the target server + :RAM cost: 0 GB + + Runs the SQLInject.exe program on the target server. SQLInject.exe must exist on your home computer. + + Example:: + + sqlinject("foodnstuff"); diff --git a/doc/source/netscript/basicfunctions/tprint.rst b/doc/source/netscript/basicfunctions/tprint.rst new file mode 100644 index 000000000..271879c30 --- /dev/null +++ b/doc/source/netscript/basicfunctions/tprint.rst @@ -0,0 +1,9 @@ +tprint() Netscript Function +=========================== + +.. js:function:: tprint(x) + + :param x: Value to be printed + :RAM cost: 0 GB + + Prints a value or a variable to the Terminal diff --git a/doc/source/netscript/basicfunctions/tryWrite.rst b/doc/source/netscript/basicfunctions/tryWrite.rst new file mode 100644 index 000000000..3c9a54e84 --- /dev/null +++ b/doc/source/netscript/basicfunctions/tryWrite.rst @@ -0,0 +1,12 @@ +tryWrite() Netscript Function +============================= + +.. js:function:: tryWrite(port, data="") + + :param number port: Port to be written to + :param string data: Data to try to write + :returns: True if the data is successfully written to the port, and false otherwise + :RAM cost: 1 GB + + Attempts to write data to the specified Netscript Port. If the port is full, the data will + not be written. Otherwise, the data will be written normally diff --git a/doc/source/netscript/basicfunctions/vsprintf.rst b/doc/source/netscript/basicfunctions/vsprintf.rst new file mode 100644 index 000000000..1b7431de0 --- /dev/null +++ b/doc/source/netscript/basicfunctions/vsprintf.rst @@ -0,0 +1,8 @@ +vsprintf() Netscript Function +============================= + +.. js:function:: vsprintf() + + :RAM cost: 0 GB + + See `this link `_ for details. diff --git a/doc/source/netscript/basicfunctions/weaken.rst b/doc/source/netscript/basicfunctions/weaken.rst new file mode 100644 index 000000000..e1eebc1db --- /dev/null +++ b/doc/source/netscript/basicfunctions/weaken.rst @@ -0,0 +1,20 @@ +weaken() Netscript Function +=========================== + +.. js:function:: weaken(hostname/ip) + + :param string hostname/ip: IP or hostname of the target server to weaken + :returns: The amount by which the target server's security level was decreased. This is equivalent to 0.05 multiplied + by the number of script threads + :RAM cost: 0.15 GB + + Use your hacking skills to attack a server's security, lowering the server's security level. The runtime for this command + depends on your hacking level and the target server's security level. This function lowers the security level of the target + server by 0.05. + + Like hack() and grow(), weaken() can be called on any server, regardless of where the script is running. This command requires + root access to the target server, but there is no required hacking level to run the command. + + Example:: + + weaken("foodnstuff"); diff --git a/doc/source/netscript/basicfunctions/wget.rst b/doc/source/netscript/basicfunctions/wget.rst new file mode 100644 index 000000000..78db9950e --- /dev/null +++ b/doc/source/netscript/basicfunctions/wget.rst @@ -0,0 +1,31 @@ +wget() Netscript Function +========================= + +.. js:function:: wget(url, target[, hostname/ip=current ip]) + + :param string url: URL to pull data from + :param string target: Filename to write data to. Must be script or text file + :param string ip: Optional hostname/ip of server for target file. + :RAM cost: 0 GB + + Retrieves data from a URL and downloads it to a file on the specified server. The data can only + be downloaded to a script (.script, .ns, .js) or a text file (.txt). If the file already exists, + it will be overwritten by this command. + + Note that it will not be possible to download data from many websites because they do not allow + cross-origin resource sharing (CORS). Example:: + + wget("https://raw.githubusercontent.com/danielyxie/bitburner/master/README.md", "game_readme.txt"); + + **IMPORTANT:** This is an asynchronous function that returns a Promise. The Promise's resolved + value will be a boolean indicating whether or not the data was successfully + retrieved from the URL. Because the function is async and returns a Promise, + it is recommended you use :code:`wget` in :ref:`netscriptjs`. + + In NetscriptJS, you must preface any call to + :code:`wget` with the :code:`await` keyword (like you would :code:`hack` or :code:`sleep`). + + :code:`wget` will still work in :ref:`netscript1`, but the functions execution will not + be synchronous (i.e. it may not execute when you expect/want it to). Furthermore, since Promises are not + supported in ES5, you will not be able to process the returned value of :code:`wget` in + Netscript 1.0. diff --git a/doc/source/netscript/basicfunctions/write.rst b/doc/source/netscript/basicfunctions/write.rst new file mode 100644 index 000000000..c492ea51d --- /dev/null +++ b/doc/source/netscript/basicfunctions/write.rst @@ -0,0 +1,20 @@ +write() Netscript Function +=========================== + +.. js:function:: write(port/fn, data="", mode="a") + + :param string/number port/fn: Port or text file/script that will be written to + :param string data: Data to write + :param string mode: Defines the write mode. Only valid when writing to text files or scripts. + :RAM cost: 1 GB + + This function can be used to either write data to a port, a text file (.txt), or a script (.script, .js, .ns) + + If the first argument is a number between 1 and 20, then it specifies a port and this function will write *data* to that port. Read + about how :ref:`netscript_ports` work here. The third argument, *mode*, is not used + when writing to a port. + + If the first argument is a string, then it specifies the name of a text file or script and this function will write *data* to that text file/script. If the + specified text file/script does not exist, then it will be created. The third argument *mode*, defines how the data will be written. If *mode* + is set to "w", then the data is written in "write" mode which means that it will overwrite all existing data on the text file/script. If *mode* is set to + any other value then the data will be written in "append" mode which means that the data will be added at the end of the file. diff --git a/doc/source/netscript/bladeburnerapi/getActionAutolevel.rst b/doc/source/netscript/bladeburnerapi/getActionAutolevel.rst new file mode 100644 index 000000000..77c504d67 --- /dev/null +++ b/doc/source/netscript/bladeburnerapi/getActionAutolevel.rst @@ -0,0 +1,11 @@ +getActionAutolevel() Netscript Function +======================================= + +.. js:function:: getActionAutolevel(type, name) + + :param string type: Type of action. See :ref:`bladeburner_action_types` + :param string name: Name of action. Must be an exact match + + Return a boolean indicating whether or not this action is currently set to autolevel. + + Returns false if an invalid action is specified. diff --git a/doc/source/netscript/bladeburnerapi/getActionCountRemaining.rst b/doc/source/netscript/bladeburnerapi/getActionCountRemaining.rst new file mode 100644 index 000000000..af50a19d5 --- /dev/null +++ b/doc/source/netscript/bladeburnerapi/getActionCountRemaining.rst @@ -0,0 +1,12 @@ +getActionCountRemaining() Netscript Function +============================================ + +.. js:function:: getActionCountRemaining(type, name) + + :param string type: Type of action. See :ref:`bladeburner_action_types` + :param string name: Name of action. Must be an exact match + + Returns the remaining count of the specified action. + + Note that this is meant to be used for Contracts and Operations. + This function will return 'Infinity' for actions such as Training and Field Analysis. diff --git a/doc/source/netscript/bladeburnerapi/getActionCurrentLevel.rst b/doc/source/netscript/bladeburnerapi/getActionCurrentLevel.rst new file mode 100644 index 000000000..c3476096d --- /dev/null +++ b/doc/source/netscript/bladeburnerapi/getActionCurrentLevel.rst @@ -0,0 +1,11 @@ +getActionCurrentLevel() Netscript Function +========================================== + +.. js:function:: getActionCurrentLevel(type, name) + + :param string type: Type of action. See :ref:`bladeburner_action_types` + :param string name: Name of action. Must be an exact match + + Returns the current level of this action. + + Returns -1 if an invalid action is specified. diff --git a/doc/source/netscript/bladeburnerapi/getActionEstimatedSuccessChance.rst b/doc/source/netscript/bladeburnerapi/getActionEstimatedSuccessChance.rst new file mode 100644 index 000000000..26c1b610a --- /dev/null +++ b/doc/source/netscript/bladeburnerapi/getActionEstimatedSuccessChance.rst @@ -0,0 +1,11 @@ +getActionEstimatedSuccessChance() Netscript Function +==================================================== + +.. js:function:: getActionEstimatedSuccessChance(type, name) + + :param string type: Type of action. See :ref:`bladeburner_action_types` + :param string name: Name of action. Must be an exact match + + Returns the estimated success chance for the specified action. This chance + is returned as a decimal value, NOT a percentage (e.g. if you have an estimated + success chance of 80%, then this function will return 0.80, NOT 80). diff --git a/doc/source/netscript/bladeburnerapi/getActionMaxLevel.rst b/doc/source/netscript/bladeburnerapi/getActionMaxLevel.rst new file mode 100644 index 000000000..dec0076fb --- /dev/null +++ b/doc/source/netscript/bladeburnerapi/getActionMaxLevel.rst @@ -0,0 +1,11 @@ +getActionMaxLevel() Netscript Function +====================================== + +.. js:function:: getActionMaxLevel(type, name) + + :param string type: Type of action. See :ref:`bladeburner_action_types` + :param string name: Name of action. Must be an exact match + + Returns the maximum level for this action. + + Returns -1 if an invalid action is specified. diff --git a/doc/source/netscript/bladeburnerapi/getActionRepGain.rst b/doc/source/netscript/bladeburnerapi/getActionRepGain.rst new file mode 100644 index 000000000..3846acec8 --- /dev/null +++ b/doc/source/netscript/bladeburnerapi/getActionRepGain.rst @@ -0,0 +1,12 @@ +getActionRepGain() Netscript Function +===================================== + +.. js:function:: getActionRepGain(type, name[, level=current level]) + + :param string type: Type of action. See :ref:`bladeburner_action_types` + :param string name: Name of action. Must be an exact match + :param number level: Optional action level at which to calculate the gain + + Returns the average Bladeburner reputation gain for successfully completing + the specified action. Note that this value is an 'average' and the real + reputation gain may vary slightly from this value. diff --git a/doc/source/netscript/bladeburnerapi/getActionTime.rst b/doc/source/netscript/bladeburnerapi/getActionTime.rst new file mode 100644 index 000000000..8189edf79 --- /dev/null +++ b/doc/source/netscript/bladeburnerapi/getActionTime.rst @@ -0,0 +1,9 @@ +getActionTime() Netscript Function +================================== + +.. js:function:: getActionTime(type, name) + + :param string type: Type of action. See :ref:`bladeburner_action_types` + :param string name: Name of action. Must be an exact match + + Returns the number of seconds it takes to complete the specified action diff --git a/doc/source/netscript/bladeburnerapi/getBlackOpNames.rst b/doc/source/netscript/bladeburnerapi/getBlackOpNames.rst new file mode 100644 index 000000000..164904a23 --- /dev/null +++ b/doc/source/netscript/bladeburnerapi/getBlackOpNames.rst @@ -0,0 +1,6 @@ +getBlackOpNames() Netscript Function +==================================== + +.. js:function:: getBlackOpNames() + + Returns an array of strings containing the names of all Bladeburner Black Ops diff --git a/doc/source/netscript/bladeburnerapi/getBonusTime.rst b/doc/source/netscript/bladeburnerapi/getBonusTime.rst new file mode 100644 index 000000000..c6aa0e088 --- /dev/null +++ b/doc/source/netscript/bladeburnerapi/getBonusTime.rst @@ -0,0 +1,14 @@ +getBonusTime() Netscript Function +================================= + +.. js:function:: getBonusTime() + + Returns the amount of accumulated "bonus time" (seconds) for the Bladeburner mechanic. + + "Bonus time" is accumulated when the game is offline or if the game is + inactive in the browser. + + "Bonus time" makes the game progress faster, up to 5x the normal speed. + For example, if an action takes 30 seconds to complete but you've accumulated + over 30 seconds in bonus time, then the action will only take 6 seconds + in real life to complete. diff --git a/doc/source/netscript/bladeburnerapi/getCity.rst b/doc/source/netscript/bladeburnerapi/getCity.rst new file mode 100644 index 000000000..265ee604d --- /dev/null +++ b/doc/source/netscript/bladeburnerapi/getCity.rst @@ -0,0 +1,6 @@ +getCity() Netscript Function +============================ + +.. js:function:: getCity() + + Returns the city that the player is currently in (for Bladeburner). diff --git a/doc/source/netscript/bladeburnerapi/getCityChaos.rst b/doc/source/netscript/bladeburnerapi/getCityChaos.rst new file mode 100644 index 000000000..65df242ca --- /dev/null +++ b/doc/source/netscript/bladeburnerapi/getCityChaos.rst @@ -0,0 +1,8 @@ +getCityChaos() Netscript Function +================================= + +.. js:function:: getCityChaos(cityName) + + :param string cityName: Name of city. Case-sensitive + + Returns the chaos in the specified city, or -1 if an invalid city was specified diff --git a/doc/source/netscript/bladeburnerapi/getCityEstimatedCommunities.rst b/doc/source/netscript/bladeburnerapi/getCityEstimatedCommunities.rst new file mode 100644 index 000000000..c9862fbeb --- /dev/null +++ b/doc/source/netscript/bladeburnerapi/getCityEstimatedCommunities.rst @@ -0,0 +1,9 @@ +getCityEstimatedCommunities() Netscript Function +================================================ + +.. js:function:: getCityEstimatedCommunities(cityName) + + :param string cityName: Name of city. Case-sensitive + + Returns the estimated number of Synthoid communities in the specified city, + or -1 if an invalid city was specified. diff --git a/doc/source/netscript/bladeburnerapi/getCityEstimatedPopulation.rst b/doc/source/netscript/bladeburnerapi/getCityEstimatedPopulation.rst new file mode 100644 index 000000000..d796feebf --- /dev/null +++ b/doc/source/netscript/bladeburnerapi/getCityEstimatedPopulation.rst @@ -0,0 +1,9 @@ +getCityEstimatedPopulation() Netscript Function +=============================================== + +.. js:function:: getCityEstimatedPopulation(cityName) + + :param string cityName: Name of city. Case-sensitive + + Returns the estimated number of Synthoids in the specified city, or -1 + if an invalid city was specified. diff --git a/doc/source/netscript/bladeburnerapi/getContractNames.rst b/doc/source/netscript/bladeburnerapi/getContractNames.rst new file mode 100644 index 000000000..7b94af4ab --- /dev/null +++ b/doc/source/netscript/bladeburnerapi/getContractNames.rst @@ -0,0 +1,6 @@ +getContractNames() Netscript Function +===================================== + +.. js:function:: getContractNames() + + Returns an array of strings containing the names of all Bladeburner contracts diff --git a/doc/source/netscript/bladeburnerapi/getCurrentAction.rst b/doc/source/netscript/bladeburnerapi/getCurrentAction.rst new file mode 100644 index 000000000..bfb16be69 --- /dev/null +++ b/doc/source/netscript/bladeburnerapi/getCurrentAction.rst @@ -0,0 +1,14 @@ +getCurrentAction() Netscript Function +===================================== + +.. js:function:: getCurrentAction() + + Returns an object that represents the player's current Bladeburner action:: + + { + type: Type of Action + name: Name of Action + } + + If the player is not performing an action, the function will return an object + with the 'type' property set to "Idle". diff --git a/doc/source/netscript/bladeburnerapi/getGeneralActionNames.rst b/doc/source/netscript/bladeburnerapi/getGeneralActionNames.rst new file mode 100644 index 000000000..96556b738 --- /dev/null +++ b/doc/source/netscript/bladeburnerapi/getGeneralActionNames.rst @@ -0,0 +1,6 @@ +getGeneralActionNames() Netscript Function +========================================== + +.. js:function:: getGeneralActionNames() + + Returns an array of strings containing the names of all general Bladeburner actions diff --git a/doc/source/netscript/bladeburnerapi/getOperationNames.rst b/doc/source/netscript/bladeburnerapi/getOperationNames.rst new file mode 100644 index 000000000..e740505f8 --- /dev/null +++ b/doc/source/netscript/bladeburnerapi/getOperationNames.rst @@ -0,0 +1,6 @@ +getOperationNames() Netscript Function +====================================== + +.. js:function:: getOperationNames() + + Returns an array of strings containing the names of all Bladeburner operations diff --git a/doc/source/netscript/bladeburnerapi/getRank.rst b/doc/source/netscript/bladeburnerapi/getRank.rst new file mode 100644 index 000000000..f5745801a --- /dev/null +++ b/doc/source/netscript/bladeburnerapi/getRank.rst @@ -0,0 +1,6 @@ +getRank() Netscript Function +============================ + +.. js:function:: getRank() + + Returns the player's Bladeburner Rank diff --git a/doc/source/netscript/bladeburnerapi/getSkillLevel.rst b/doc/source/netscript/bladeburnerapi/getSkillLevel.rst new file mode 100644 index 000000000..78000b893 --- /dev/null +++ b/doc/source/netscript/bladeburnerapi/getSkillLevel.rst @@ -0,0 +1,10 @@ +getSkillLevel() Netscript Function +================================== + +.. js:function:: getSkillLevel(skillName="") + + :param string skillName: Name of skill. Case-sensitive and must be an exact match + + This function returns your level in the specified skill. + + The function returns -1 if an invalid skill name is passed in diff --git a/doc/source/netscript/bladeburnerapi/getSkillNames.rst b/doc/source/netscript/bladeburnerapi/getSkillNames.rst new file mode 100644 index 000000000..e6893d2a9 --- /dev/null +++ b/doc/source/netscript/bladeburnerapi/getSkillNames.rst @@ -0,0 +1,6 @@ +getSkillNames() Netscript Function +================================== + +.. js:function:: getSkillNames() + + Returns an array of strings containing the names of all Bladeburner skills diff --git a/doc/source/netscript/bladeburnerapi/getSkillPoints.rst b/doc/source/netscript/bladeburnerapi/getSkillPoints.rst new file mode 100644 index 000000000..18ea7f16b --- /dev/null +++ b/doc/source/netscript/bladeburnerapi/getSkillPoints.rst @@ -0,0 +1,6 @@ +getSkillPoints() Netscript Function +=================================== + +.. js:function:: getSkillPoints() + + Returns the number of Bladeburner skill points you have diff --git a/doc/source/netscript/bladeburnerapi/getSkillUpgradeCost.rst b/doc/source/netscript/bladeburnerapi/getSkillUpgradeCost.rst new file mode 100644 index 000000000..6216d4e7a --- /dev/null +++ b/doc/source/netscript/bladeburnerapi/getSkillUpgradeCost.rst @@ -0,0 +1,11 @@ +getSkillUpgradeCost() Netscript Function +======================================== + +.. js:function:: getSkillUpgradeCost(skillName="") + + :param string skillName: Name of skill. Case-sensitive and must be an exact match + + This function returns the number of skill points needed to upgrade the + specified skill. + + The function returns -1 if an invalid skill name is passed in. diff --git a/doc/source/netscript/bladeburnerapi/getStamina.rst b/doc/source/netscript/bladeburnerapi/getStamina.rst new file mode 100644 index 000000000..c2d1f8a05 --- /dev/null +++ b/doc/source/netscript/bladeburnerapi/getStamina.rst @@ -0,0 +1,15 @@ +getStamina() Netscript Function +=============================== + +.. js:function:: getStamina() + + Returns an array with two elements: + + [Current stamina, Max stamina] + + Example usage:: + + function getStaminaPercentage() { + let res = bladeburner.getStamina(); + return res[0] / res[1]; + } diff --git a/doc/source/netscript/bladeburnerapi/getTeamSize.rst b/doc/source/netscript/bladeburnerapi/getTeamSize.rst new file mode 100644 index 000000000..617b0488f --- /dev/null +++ b/doc/source/netscript/bladeburnerapi/getTeamSize.rst @@ -0,0 +1,13 @@ +getTeamSize() Netscript Function +================================ + +.. js:function:: getTeamSize(type, name) + + :param string type: Type of action. See :ref:`bladeburner_action_types` + :param string name: Name of action. Must be an exact match + + Returns the number of Bladeburner team members you have assigned to the + specified action. + + Setting a team is only applicable for Operations and BlackOps. This function + will return 0 for other action types. diff --git a/doc/source/netscript/bladeburnerapi/joinBladeburnerDivision.rst b/doc/source/netscript/bladeburnerapi/joinBladeburnerDivision.rst new file mode 100644 index 000000000..ff524da8d --- /dev/null +++ b/doc/source/netscript/bladeburnerapi/joinBladeburnerDivision.rst @@ -0,0 +1,11 @@ +joinBladeburnerDivision() Netscript Function +============================================ + +.. js:function:: joinBladeburnerDivision() + + Attempts to join the Bladeburner division. + + Returns true if you successfully join the Bladeburner division, or if you + are already a member. + + Returns false otherwise diff --git a/doc/source/netscript/bladeburnerapi/joinBladeburnerFaction.rst b/doc/source/netscript/bladeburnerapi/joinBladeburnerFaction.rst new file mode 100644 index 000000000..58fc32786 --- /dev/null +++ b/doc/source/netscript/bladeburnerapi/joinBladeburnerFaction.rst @@ -0,0 +1,11 @@ +joinBladeburnerFaction() Netscript Function +=========================================== + +.. js:function:: joinBladeburnerFaction() + + Attempts to join the Bladeburner faction. + + Returns true if you successfully join the Bladeburner faction, or if + you are already a member. + + Returns false otherwise. diff --git a/doc/source/netscript/bladeburnerapi/setActionAutolevel.rst b/doc/source/netscript/bladeburnerapi/setActionAutolevel.rst new file mode 100644 index 000000000..d650c551c --- /dev/null +++ b/doc/source/netscript/bladeburnerapi/setActionAutolevel.rst @@ -0,0 +1,10 @@ +setActionAutolevel() Netscript Function +======================================= + +.. js:function:: setActionAutolevel(type, name, autoLevel) + + :param string type: Type of action. See :ref:`bladeburner_action_types` + :param string name: Name of action. Must be an exact match + :param boolean autoLevel: Whether or not to autolevel this action + + Enable/disable autoleveling for the specified action. diff --git a/doc/source/netscript/bladeburnerapi/setActionLevel.rst b/doc/source/netscript/bladeburnerapi/setActionLevel.rst new file mode 100644 index 000000000..42bafa9eb --- /dev/null +++ b/doc/source/netscript/bladeburnerapi/setActionLevel.rst @@ -0,0 +1,10 @@ +setActionLevel() Netscript Function +=================================== + +.. js:function:: setActionLevel(type, name, level) + + :param string type: Type of action. See :ref:`bladeburner_action_types` + :param string name: Name of action. Must be an exact match + :param level int: Level to set this action to + + Set the level for the specified action. diff --git a/doc/source/netscript/bladeburnerapi/setTeamSize.rst b/doc/source/netscript/bladeburnerapi/setTeamSize.rst new file mode 100644 index 000000000..c40e33f8d --- /dev/null +++ b/doc/source/netscript/bladeburnerapi/setTeamSize.rst @@ -0,0 +1,12 @@ +setTeamSize() Netscript Function +================================ + +.. js:function:: setTeamSize(type, name, size) + + :param string type: Type of action. See :ref:`bladeburner_action_types` + :param string name: Name of action. Must be an exact match + :param int size: Number of team members to set. Will be converted using Math.round() + + Set the team size for the specified Bladeburner action. + + Returns the team size that was set, or -1 if the function failed. diff --git a/doc/source/netscript/bladeburnerapi/startAction.rst b/doc/source/netscript/bladeburnerapi/startAction.rst new file mode 100644 index 000000000..c3cb330a9 --- /dev/null +++ b/doc/source/netscript/bladeburnerapi/startAction.rst @@ -0,0 +1,10 @@ +startAction() Netscript Function +================================ + +.. js:function:: startAction(type, name) + + :param string type: Type of action. See :ref:`bladeburner_action_types` + :param string name: Name of action. Must be an exact match + + Attempts to start the specified Bladeburner action. Returns true if the action + was started successfully, and false otherwise. diff --git a/doc/source/netscript/bladeburnerapi/stopBladeburnerAction.rst b/doc/source/netscript/bladeburnerapi/stopBladeburnerAction.rst new file mode 100644 index 000000000..3ff0489a9 --- /dev/null +++ b/doc/source/netscript/bladeburnerapi/stopBladeburnerAction.rst @@ -0,0 +1,6 @@ +stopBladeburnerAction() Netscript Function +========================================== + +.. js:function:: stopBladeburnerAction() + + Stops the current Bladeburner action diff --git a/doc/source/netscript/bladeburnerapi/switchCity.rst b/doc/source/netscript/bladeburnerapi/switchCity.rst new file mode 100644 index 000000000..b0ff6ed53 --- /dev/null +++ b/doc/source/netscript/bladeburnerapi/switchCity.rst @@ -0,0 +1,10 @@ +switchCity() Netscript Function +=============================== + +.. js:function:: switchCity(cityName) + + :param string cityName: Name of city + + Attempts to switch to the specified city (for Bladeburner only). + + Returns true if successful, and false otherwise diff --git a/doc/source/netscript/bladeburnerapi/upgradeSkill.rst b/doc/source/netscript/bladeburnerapi/upgradeSkill.rst new file mode 100644 index 000000000..06d6d6bd7 --- /dev/null +++ b/doc/source/netscript/bladeburnerapi/upgradeSkill.rst @@ -0,0 +1,9 @@ +upgradeSkill() Netscript Function +================================= + +.. js:function:: upgradeSkill(skillName) + + :param string skillName: Name of Skill to be upgraded. Case-sensitive and must be an exact match + + Attempts to upgrade the specified Bladeburner skill. Returns true if the + skill is successfully upgraded, and false otherwise diff --git a/doc/source/netscript/codingcontractapi/attempt.rst b/doc/source/netscript/codingcontractapi/attempt.rst new file mode 100644 index 000000000..342349909 --- /dev/null +++ b/doc/source/netscript/codingcontractapi/attempt.rst @@ -0,0 +1,13 @@ +attempt() Netscript Function +============================ + +.. js:function:: attempt(answer, fn[, hostname/ip=current ip]) + + :param answer: Solution for the contract + :param string fn: Filename of the contract + :param string hostname/ip: Hostname or IP of the server containing the contract. + Optional. Defaults to current server if not provided + + Attempts to solve the Coding Contract with the provided solution. + + :returns: Boolean indicating whether the solution was correct diff --git a/doc/source/netscript/codingcontractapi/getContractType.rst b/doc/source/netscript/codingcontractapi/getContractType.rst new file mode 100644 index 000000000..5713d4405 --- /dev/null +++ b/doc/source/netscript/codingcontractapi/getContractType.rst @@ -0,0 +1,13 @@ +getContractType() Netscript Function +==================================== + +.. js:function:: getContractType(fn[, hostname/ip=current ip]) + + :param string fn: Filename of the contract + :param string hostname/ip: Hostname or IP of the server containing the contract. + Optional. Defaults to current server if not provided + + Returns a name describing the type of problem posed by the Coding Contract. + (e.g. Find Largest Prime Factor, Total Ways to Sum, etc.) + + :returns: A string with the contract's problem type diff --git a/doc/source/netscript/codingcontractapi/getData.rst b/doc/source/netscript/codingcontractapi/getData.rst new file mode 100644 index 000000000..0efe2d224 --- /dev/null +++ b/doc/source/netscript/codingcontractapi/getData.rst @@ -0,0 +1,14 @@ +getData() Netscript Function +============================ + +.. js:function:: getData(fn[, hostname/ip=current ip]) + + :param string fn: Filename of the contract + :param string hostname/ip: Hostname or IP of the server containing the contract. + Optional. Defaults to current server if not provided + + Get the data associated with the specific Coding Contract. Note that this is + not the same as the contract's description. This is just the data that + the contract wants you to act on in order to solve + + :returns: The specified contract's data diff --git a/doc/source/netscript/codingcontractapi/getDescription.rst b/doc/source/netscript/codingcontractapi/getDescription.rst new file mode 100644 index 000000000..08c11c356 --- /dev/null +++ b/doc/source/netscript/codingcontractapi/getDescription.rst @@ -0,0 +1,12 @@ +getDescription() Netscript Function +=================================== + +.. js:function:: getDescription(fn[, hostname/ip=current ip]) + + :param string fn: Filename of the contract + :param string hostname/ip: Hostname or IP of the server containing the contract. + Optional. Defaults to current server if not provided + + Get the full text description for the problem posed by the Coding Contract + + :returns: A string with the contract's text description diff --git a/doc/source/netscript/codingcontractapi/getNumTriesRemaining.rst b/doc/source/netscript/codingcontractapi/getNumTriesRemaining.rst new file mode 100644 index 000000000..5e8620398 --- /dev/null +++ b/doc/source/netscript/codingcontractapi/getNumTriesRemaining.rst @@ -0,0 +1,13 @@ +getNumTriesRemaining() Netscript Function +========================================= + +.. js:function:: getNumTriesRemaining(fn[, hostname/ip=current ip]) + + :param string fn: Filename of the contract + :param string hostname/ip: Hostname or IP of the server containing the contract. + Optional. Defaults to current server if not provided + + Get the number of tries remaining on the contract before it + self-destructs. + + :returns: Number indicating how many attempts are remaining diff --git a/doc/source/netscript/gangapi/ascendMember.rst b/doc/source/netscript/gangapi/ascendMember.rst new file mode 100644 index 000000000..204b5408c --- /dev/null +++ b/doc/source/netscript/gangapi/ascendMember.rst @@ -0,0 +1,22 @@ +ascendMember() Netscript Function +================================= + +.. js:function:: ascendMember(name) + + :param string name: Name of member to ascend + + Ascend the specified Gang Member. + + :returns: An object with info about the ascension results. + + The object has the following structure:: + + { + respect: Amount of respect lost from ascending + hack: Hacking multiplier gained from ascending. Decimal form + str: Strength multiplier gained from ascending. Decimal form + def: Defense multiplier gained from ascending. Decimal form + dex: Dexterity multiplier gained from ascending. Decimal form + agi: Agility multiplier gained from ascending. Decimal form + cha: Charisma multiplier gained from ascending. Decimal form + } diff --git a/doc/source/netscript/gangapi/canRecruitMember.rst b/doc/source/netscript/gangapi/canRecruitMember.rst new file mode 100644 index 000000000..2f0af2017 --- /dev/null +++ b/doc/source/netscript/gangapi/canRecruitMember.rst @@ -0,0 +1,6 @@ +canRecruitMember() Netscript Function +===================================== + +.. js:function:: canRecruitMember() + + :returns: Boolean indicating whether a member can currently be recruited diff --git a/doc/source/netscript/gangapi/getBonusTime.rst b/doc/source/netscript/gangapi/getBonusTime.rst new file mode 100644 index 000000000..2163cc4db --- /dev/null +++ b/doc/source/netscript/gangapi/getBonusTime.rst @@ -0,0 +1,13 @@ +getBonusTime() Netscript Function +================================= + +.. js:function:: getBonusTime() + + Returns the amount of accumulated "bonus time" (seconds) for the Gang mechanic. + + "Bonus time" is accumulated when the game is offline or if the game is + inactive in the browser. + + "Bonus time" makes the game progress faster, up to 10x the normal speed. + + :returns: Bonus time for the Gang mechanic in seconds diff --git a/doc/source/netscript/gangapi/getChanceToWinClash.rst b/doc/source/netscript/gangapi/getChanceToWinClash.rst new file mode 100644 index 000000000..501139d49 --- /dev/null +++ b/doc/source/netscript/gangapi/getChanceToWinClash.rst @@ -0,0 +1,9 @@ +getChanceToWinClash() Netscript Function +======================================== + +.. js:function:: getChanceToWinClash(gangName) + + :param string gangName: Target gang + + Returns the chance you have to win a clash with the specified gang. The chance + is returned in decimal form, not percentage diff --git a/doc/source/netscript/gangapi/getEquipmentCost.rst b/doc/source/netscript/gangapi/getEquipmentCost.rst new file mode 100644 index 000000000..dab58abca --- /dev/null +++ b/doc/source/netscript/gangapi/getEquipmentCost.rst @@ -0,0 +1,12 @@ +getEquipmentCost() Netscript Function +===================================== + +.. js:function:: getEquipmentCost(equipName) + + :param string equipName: Name of equipment + + Get the amount of money it takes to purchase a piece of Equipment or an Augmentation. + If an invalid Equipment/Augmentation is specified, this function will return Infinity. + + :returns: Cost to purchase the specified Equipment/Augmentation (number). Infinity + for invalid arguments diff --git a/doc/source/netscript/gangapi/getEquipmentNames.rst b/doc/source/netscript/gangapi/getEquipmentNames.rst new file mode 100644 index 000000000..ec5f74c30 --- /dev/null +++ b/doc/source/netscript/gangapi/getEquipmentNames.rst @@ -0,0 +1,9 @@ +getEquipmentNames() Netscript Function +====================================== + +.. js:function:: getEquipmentNames() + + Get the name of all possible equipment/upgrades you can purchase for your + Gang Members. This includes Augmentations. + + :returns: Array of strings of the names of all Equpiment/Augmentations diff --git a/doc/source/netscript/gangapi/getEquipmentType.rst b/doc/source/netscript/gangapi/getEquipmentType.rst new file mode 100644 index 000000000..bec9f9fdf --- /dev/null +++ b/doc/source/netscript/gangapi/getEquipmentType.rst @@ -0,0 +1,16 @@ +getEquipmentType() Netscript Function +===================================== + +.. js:function:: getEquipmentType(equipName) + + :param string equipName: Name of equipment + + Get the specified equipment type, which can be one of the following: + + * Weapon + * Armor + * Vehicle + * Rootkit + * Augmentation + + :returns: A string stating the type of the equipment diff --git a/doc/source/netscript/gangapi/getGangInformation.rst b/doc/source/netscript/gangapi/getGangInformation.rst new file mode 100644 index 000000000..008853d1d --- /dev/null +++ b/doc/source/netscript/gangapi/getGangInformation.rst @@ -0,0 +1,23 @@ +getGangInformation() Netscript Function +======================================== + +.. js:function:: getGangInformation() + + Get general information about the gang + + :returns: An object with the gang information. + + The object has the following structure:: + + { + faction: Name of faction that the gang belongs to ("Slum Snakes", etc.) + isHacking: Boolean indicating whether or not its a hacking gang + moneyGainRate: Money earned per second + power: Gang's power for territory warfare + respect: Gang's respect + respectGainRate: Respect earned per second + territory: Amount of territory held. Returned in decimal form, not percentage + territoryClashChance: Clash chance. Returned in decimal form, not percentage + wantedLevel: Gang's wanted level + wantedLevelGainRate: Wanted level gained/lost per second (negative for losses) + } diff --git a/doc/source/netscript/gangapi/getMemberInformation.rst b/doc/source/netscript/gangapi/getMemberInformation.rst new file mode 100644 index 000000000..356913237 --- /dev/null +++ b/doc/source/netscript/gangapi/getMemberInformation.rst @@ -0,0 +1,36 @@ +getMemberInformation() Netscript Function +========================================= + +.. js:function:: getMemberInformation(name) + + :param string name: Name of member + + Get stat and equipment-related information about a Gang Member + + :returns: An object with the gang member information. + + The object has the following structure:: + + { + agility: Agility stat + agilityEquipMult: Agility multiplier from equipment. Decimal form + agilityAscensionMult: Agility multiplier from ascension. Decimal form + augmentations: Array of names of all owned Augmentations + charisma: Charisma stat + charismaEquipMult: Charisma multiplier from equipment. Decimal form + charismaAscensionMult: Charisma multiplier from ascension. Decimal form + defense: Defense stat + defenseEquipMult: Defense multiplier from equipment. Decimal form + defenseAscensionMult: Defense multiplier from ascension. Decimal form + dexterity: Dexterity stat + dexterityEquipMult: Dexterity multiplier from equipment. Decimal form + dexterityAscensionMult: Dexterity multiplier from ascension. Decimal form + equipment: Array of names of all owned Non-Augmentation Equipment + hacking: Hacking stat + hackingEquipMult: Hacking multiplier from equipment. Decimal form + hackingAscensionMult: Hacking multiplier from ascension. Decimal form + strength: Strength stat + strengthEquipMult: Strength multiplier from equipment. Decimal form + strengthAscensionMult: Strength multiplier from ascension. Decimal form + task: Name of currently assigned task + } diff --git a/doc/source/netscript/gangapi/getMemberNames.rst b/doc/source/netscript/gangapi/getMemberNames.rst new file mode 100644 index 000000000..628df081e --- /dev/null +++ b/doc/source/netscript/gangapi/getMemberNames.rst @@ -0,0 +1,8 @@ +getMemberNames() Netscript Function +=================================== + +.. js:function:: getMemberNames() + + Get the names of all Gang members + + :returns: An array of the names of all Gang members as strings diff --git a/doc/source/netscript/gangapi/getOtherGangInformation.rst b/doc/source/netscript/gangapi/getOtherGangInformation.rst new file mode 100644 index 000000000..ffb2c913f --- /dev/null +++ b/doc/source/netscript/gangapi/getOtherGangInformation.rst @@ -0,0 +1,26 @@ +getOtherGangInformation() Netscript Function +============================================ + +.. js:function:: getOtherGangInformation() + + Get territory and power information about all gangs + + :returns: An object with information about all gangs + + The object has the following structure:: + + { + "Slum Snakes" : { + power: Slum Snakes' power + territory: Slum Snakes' territory, in decimal form + }, + "Tetrads" : { + power: ... + territory: ... + }, + "The Syndicate" : { + power: ... + territory: ... + }, + ... (for all six gangs) + } diff --git a/doc/source/netscript/gangapi/getTaskNames.rst b/doc/source/netscript/gangapi/getTaskNames.rst new file mode 100644 index 000000000..06adfe599 --- /dev/null +++ b/doc/source/netscript/gangapi/getTaskNames.rst @@ -0,0 +1,8 @@ +getTaskNames() Netscript Function +================================= + +.. js:function:: getTaskNames() + + Get the name of all valid tasks that Gang members can be assigned to + + :returns: Array of strings of all task names diff --git a/doc/source/netscript/gangapi/purchaseEquipment.rst b/doc/source/netscript/gangapi/purchaseEquipment.rst new file mode 100644 index 000000000..6e985589e --- /dev/null +++ b/doc/source/netscript/gangapi/purchaseEquipment.rst @@ -0,0 +1,12 @@ +purchaseEquipment() Netscript Function +====================================== + +.. js:function:: purchaseEquipment(memberName, equipName) + + :param string memberName: Name of Gang member to purchase the equipment for + :param string equipName: Name of Equipment/Augmentation to purchase + + Attempt to purchase the specified Equipment/Augmentation for the specified + Gang member. + + :returns: True if the equipment was successfully purchased. False otherwise diff --git a/doc/source/netscript/gangapi/recruitMember.rst b/doc/source/netscript/gangapi/recruitMember.rst new file mode 100644 index 000000000..71153a12e --- /dev/null +++ b/doc/source/netscript/gangapi/recruitMember.rst @@ -0,0 +1,14 @@ +recruitMember() Netscript Function +================================== + +.. js:function:: recruitMember(name) + + :param string name: Name of member to recruit + + Attempt to recruit a new gang member. + + Possible reasons for failure: + * Cannot currently recruit a new member + * There already exists a member with the specified name + + :returns: True if the member was successfully recruited. False otherwise diff --git a/doc/source/netscript/gangapi/setMemberTask.rst b/doc/source/netscript/gangapi/setMemberTask.rst new file mode 100644 index 000000000..c75eaefba --- /dev/null +++ b/doc/source/netscript/gangapi/setMemberTask.rst @@ -0,0 +1,12 @@ +setMemberTask() Netscript Function +================================== + +.. js:function:: setMemberTask(memberName, taskName) + + :param string memberName: Name of Gang member to assign + :param string taskName: Task to assign + + Attempts to assign the specified Gang Member to the specified task. + If an invalid task is specified, the Gang member will be set to idle ("Unassigned") + + :returns: True if the Gang Member was successfully assigned to the task. False otherwise diff --git a/doc/source/netscript/gangapi/setTerritoryWarfare.rst b/doc/source/netscript/gangapi/setTerritoryWarfare.rst new file mode 100644 index 000000000..607c8137c --- /dev/null +++ b/doc/source/netscript/gangapi/setTerritoryWarfare.rst @@ -0,0 +1,8 @@ +setTerritoryWarfare() Netscript Function +======================================== + +.. js:function:: setTerritoryWarfare(engage) + + :param bool engage: Whether or not to engage in territory warfare + + Set whether or not the gang should engage in territory warfare diff --git a/doc/source/netscript/hacknetnodeapi/getCoreUpgradeCost.rst b/doc/source/netscript/hacknetnodeapi/getCoreUpgradeCost.rst new file mode 100644 index 000000000..536d1a9ee --- /dev/null +++ b/doc/source/netscript/hacknetnodeapi/getCoreUpgradeCost.rst @@ -0,0 +1,12 @@ +getCoreUpgradeCost() Netscript Function +======================================= + +.. js:function:: getCoreUpgradeCost(i, n) + + :param number i: Index/Identifier of Hacknet Node. :ref:`See here for details ` + :param number n: Number of times to upgrade cores. Must be positive. Rounded to nearest integer + + Returns the cost of upgrading the number of cores of the specified Hacknet Node by *n*. + + If an invalid value for *n* is provided, then this function returns 0. If the + specified Hacknet Node is already at the max number of cores, then Infinity is returned. diff --git a/doc/source/netscript/hacknetnodeapi/getLevelUpgradeCost.rst b/doc/source/netscript/hacknetnodeapi/getLevelUpgradeCost.rst new file mode 100644 index 000000000..d2a933c38 --- /dev/null +++ b/doc/source/netscript/hacknetnodeapi/getLevelUpgradeCost.rst @@ -0,0 +1,12 @@ +getLevelUpgradeCost() Netscript Function +======================================== + +.. js:function:: getLevelUpgradeCost(i, n) + + :param number i: Index/Identifier of Hacknet Node. :ref:`See here for details ` + :param number n: Number of levels to upgrade. Must be positive. Rounded to nearest integer + + Returns the cost of upgrading the specified Hacknet Node by *n* levels. + + If an invalid value for *n* is provided, then this function returns 0. If the + specified Hacknet Node is already at max level, then Infinity is returned. diff --git a/doc/source/netscript/hacknetnodeapi/getNodeStats.rst b/doc/source/netscript/hacknetnodeapi/getNodeStats.rst new file mode 100644 index 000000000..74b7de5ad --- /dev/null +++ b/doc/source/netscript/hacknetnodeapi/getNodeStats.rst @@ -0,0 +1,18 @@ +getNodeStats() Netscript Function +================================= + +.. js:function:: getNodeStats(i) + + :param number i: Index/Identifier of Hacknet Node. :ref:`See here for details ` + + Returns an object containing a variety of stats about the specified Hacknet Node:: + + { + name: Node's name ("hacknet-node-5"), + level: Node's level, + ram: Node's RAM, + cores: Node's number of cores, + production: Node's money earned per second, + timeOnline: Number of seconds since Node has been purchased, + totalProduction: Total number of money Node has produced + } diff --git a/doc/source/netscript/hacknetnodeapi/getPurchaseNodeCost.rst b/doc/source/netscript/hacknetnodeapi/getPurchaseNodeCost.rst new file mode 100644 index 000000000..459c82957 --- /dev/null +++ b/doc/source/netscript/hacknetnodeapi/getPurchaseNodeCost.rst @@ -0,0 +1,6 @@ +getPurchaseNodeCost() Netscript Function +======================================== + +.. js:function:: getPurchaseNodeCost() + + Returns the cost of purchasing a new Hacknet Node diff --git a/doc/source/netscript/hacknetnodeapi/getRamUpgradeCost.rst b/doc/source/netscript/hacknetnodeapi/getRamUpgradeCost.rst new file mode 100644 index 000000000..2ba4974aa --- /dev/null +++ b/doc/source/netscript/hacknetnodeapi/getRamUpgradeCost.rst @@ -0,0 +1,12 @@ +getRamUpgradeCost() Netscript Function +====================================== + +.. js:function:: getRamUpgradeCost(i, n) + + :param number i: Index/Identifier of Hacknet Node. :ref:`See here for details ` + :param number n: Number of times to upgrade RAM. Must be positive. Rounded to nearest integer + + Returns the cost of upgrading the RAM of the specified Hacknet Node *n* times. + + If an invalid value for *n* is provided, then this function returns 0. If the + specified Hacknet Node is already at max RAM, then Infinity is returned. diff --git a/doc/source/netscript/hacknetnodeapi/numNodes.rst b/doc/source/netscript/hacknetnodeapi/numNodes.rst new file mode 100644 index 000000000..0e4c49188 --- /dev/null +++ b/doc/source/netscript/hacknetnodeapi/numNodes.rst @@ -0,0 +1,6 @@ +numNodes() Netscript Function +============================= + +.. js:function:: numNodes() + + Returns the number of Hacknet Nodes you own. diff --git a/doc/source/netscript/hacknetnodeapi/purchaseNode.rst b/doc/source/netscript/hacknetnodeapi/purchaseNode.rst new file mode 100644 index 000000000..7bac278dc --- /dev/null +++ b/doc/source/netscript/hacknetnodeapi/purchaseNode.rst @@ -0,0 +1,11 @@ +purchaseNode() Netscript Function +================================= + +.. js:function:: purchaseNode() + + Purchases a new Hacknet Node. Returns a number with the index of the Hacknet Node. + This index is equivalent to the number at the end of the Hacknet Node's name + (e.g The Hacknet Node named 'hacknet-node-4' will have an index of 4). + + If the player cannot afford to purchase a new Hacknet Node then the function + will return -1. diff --git a/doc/source/netscript/hacknetnodeapi/upgradeCore.rst b/doc/source/netscript/hacknetnodeapi/upgradeCore.rst new file mode 100644 index 000000000..372b4da45 --- /dev/null +++ b/doc/source/netscript/hacknetnodeapi/upgradeCore.rst @@ -0,0 +1,14 @@ +upgradeCore() Netscript Function +================================ + +.. js:function:: upgradeCore(i, n) + + :param number i: Index/Identifier of Hacknet Node. :ref:`See here for details ` + :param number n: Number of cores to purchase. Must be positive. Rounded to nearest integer + + Tries to purchase *n* cores for the specified Hacknet Node. + + Returns true if it successfully purchases *n* cores for the Hacknet Node or if + it purchases some positive amount and the Node reaches its max number of cores. + + Returns false otherwise. diff --git a/doc/source/netscript/hacknetnodeapi/upgradeLevel.rst b/doc/source/netscript/hacknetnodeapi/upgradeLevel.rst new file mode 100644 index 000000000..243d58ca6 --- /dev/null +++ b/doc/source/netscript/hacknetnodeapi/upgradeLevel.rst @@ -0,0 +1,14 @@ +upgradeLevel() Netscript Function +================================= + +.. js:function:: upgradeLevel(i, n) + + :param number i: Index/Identifier of Hacknet Node. :ref:`See here for details ` + :param number n: Number of levels to purchase. Must be positive. Rounded to nearest integer + + Tries to upgrade the level of the specified Hacknet Node by *n*. + + Returns true if the Hacknet Node's level is successfully upgraded by *n* or + if it is upgraded by some positive amount and the Node reaches its max level. + + Returns false otherwise. diff --git a/doc/source/netscript/hacknetnodeapi/upgradeRam.rst b/doc/source/netscript/hacknetnodeapi/upgradeRam.rst new file mode 100644 index 000000000..319981e06 --- /dev/null +++ b/doc/source/netscript/hacknetnodeapi/upgradeRam.rst @@ -0,0 +1,16 @@ +upgradeRam() Netscript Function +=============================== + +.. js:function:: upgradeRam(i, n) + + :param number i: Index/Identifier of Hacknet Node. :ref:`See here for details ` + :param number n: Number of times to upgrade RAM. Must be positive. Rounded to nearest integer + + Tries to upgrade the specified Hacknet Node's RAM *n* times. Note that each upgrade + doubles the Node's RAM. So this is equivalent to multiplying the Node's RAM by + 2 :sup:`n`. + + Returns true if the Hacknet Node's RAM is successfully upgraded *n* times or if + it is upgraded some positive number of times and the Node reaches it max RAM. + + Returns false otherwise. diff --git a/doc/source/netscript/netscriptadvancedfunctions.rst b/doc/source/netscript/netscriptadvancedfunctions.rst index d41cc060b..60400e1f7 100644 --- a/doc/source/netscript/netscriptadvancedfunctions.rst +++ b/doc/source/netscript/netscriptadvancedfunctions.rst @@ -4,39 +4,7 @@ Netscript Advanced Functions These Netscript functions become relevant later on in the game. They are put on a separate page because they contain spoilers for the game. -getBitNodeMultipliers -^^^^^^^^^^^^^^^^^^^^^ +.. toctree:: -.. js:function:: getBitNodeMultipliers() - - Returns an object containing the current BitNode multipliers. This function requires Source-File 5 in order - to run. The multipliers are returned in decimal forms (e.g. 1.5 instead of 150%). The multipliers represent - the difference between the current BitNode and the original BitNode (BitNode-1). For example, if the - *CrimeMoney* multiplier has a value of 0.1, then that means that committing crimes in the current BitNode - will only give 10% of the money you would have received in BitNode-1. - - The structure of the returned object is subject to change as BitNode multipliers get added to the game. - Refer to the `source code here `_ - to see the name of the BitNode multipliers. - - Example:: - - mults = getBitNodeMultipliers(); - print(mults.ServerMaxMoney); - print(mults.HackExpGain); - -getHackTime, getGrowTime, & getWeakenTime -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The :js:func:`getHackTime`, :js:func:`getGrowTime`, and :js:func:`getWeakenTime` -all take an additional third optional parameter for specifying a specific intelligence -level to see how that would affect the hack/grow/weaken times. This parameter -defaults to your current intelligence level. - -(Intelligence is unlocked after obtaining Source-File 5). - -The function signatures are then:: - - getHackTime(hostname/ip[, hackLvl=current level, intLvl=current level]) - getGrowTime(hostname/ip[, hackLvl=current level, intLvl=current level]) - getWeakenTime(hostname/ip[, hackLvl=current level, intLvl=current level]) + getBitNodeMultipliers() + getHackTime(), getGrowTime(), & getWeakenTime() diff --git a/doc/source/netscript/netscriptbladeburnerapi.rst b/doc/source/netscript/netscriptbladeburnerapi.rst index 23c3584cf..4ff1db46a 100644 --- a/doc/source/netscript/netscriptbladeburnerapi.rst +++ b/doc/source/netscript/netscriptbladeburnerapi.rst @@ -25,6 +25,44 @@ In :ref:`netscriptjs`:: ns.bladeburner.getContractNames(); ns.bladeburner.startAction("general", "Training"); +.. toctree:: + :caption: Functions: + + getContractNames() + getOperationNames() + getBlackOpNames() + getGeneralActionNames() + getSkillNames() + startAction() + stopBladeburnerAction() + getCurrentAction() + getActionTime() + getActionEstimatedSuccessChance() + getActionRepGain() + getActionCountRemaining() + getActionMaxLevel() + getActionCurrentLevel() + getActionAutolevel() + setActionAutolevel() + setActionLevel() + getRank() + getSkillPoints() + getSkillLevel() + getSkillUpgradeCost() + upgradeSkill() + getTeamSize() + setTeamSize() + getCityEstimatedPopulation() + getCityEstimatedCommunities() + getCityChaos() + getCity() + switchCity() + getStamina() + joinBladeburnerFaction() + joinBladeburnerDivision() + getBonusTime() + + .. _bladeburner_action_types: Bladeburner Action Types @@ -58,356 +96,6 @@ its type and name. The following are valid values when specifying the action's t * general action * gen -getContractNames ----------------- - -.. js:function:: getContractNames() - - Returns an array of strings containing the names of all Bladeburner contracts - -getOperationNames ------------------ - -.. js:function:: getOperationNames() - - Returns an array of strings containing the names of all Bladeburner operations - -getBlackOpNames ---------------- - -.. js:function:: getBlackOpNames() - - Returns an array of strings containing the names of all Bladeburner Black Ops - -getGeneralActionNames ---------------------- - -.. js:function:: getGeneralActionNames() - - Returns an array of strings containing the names of all general Bladeburner actions - -getSkillNames -------------- - -.. js:function:: getSkillNames() - - Returns an array of strings containing the names of all Bladeburner skills - -startAction ------------ - -.. js:function:: startAction(type, name) - - :param string type: Type of action. See :ref:`bladeburner_action_types` - :param string name: Name of action. Must be an exact match - - Attempts to start the specified Bladeburner action. Returns true if the action - was started successfully, and false otherwise. - -stopBladeburnerAction ---------------------- - -.. js:function:: stopBladeburnerAction() - - Stops the current Bladeburner action - -getCurrentAction ----------------- - -.. js:function:: getCurrentAction() - - Returns an object that represents the player's current Bladeburner action:: - - { - type: Type of Action - name: Name of Action - } - - If the player is not performing an action, the function will return an object - with the 'type' property set to "Idle". - -getActionTime -------------- - -.. js:function:: getActionTime(type, name) - - :param string type: Type of action. See :ref:`bladeburner_action_types` - :param string name: Name of action. Must be an exact match - - Returns the number of seconds it takes to complete the specified action - -getActionEstimatedSuccessChance -------------------------------- - -.. js:function:: getActionEstimatedSuccessChance(type, name) - - :param string type: Type of action. See :ref:`bladeburner_action_types` - :param string name: Name of action. Must be an exact match - - Returns the estimated success chance for the specified action. This chance - is returned as a decimal value, NOT a percentage (e.g. if you have an estimated - success chance of 80%, then this function will return 0.80, NOT 80). - -getActionRepGain ----------------- - -.. js:function:: getActionRepGain(type, name[, level=current level]) - - :param string type: Type of action. See :ref:`bladeburner_action_types` - :param string name: Name of action. Must be an exact match - :param number level: Optional action level at which to calculate the gain - - Returns the average Bladeburner reputation gain for successfully completing - the specified action. Note that this value is an 'average' and the real - reputation gain may vary slightly from this value. - -getActionCountRemaining ------------------------ - -.. js:function:: getActionCountRemaining(type, name) - - :param string type: Type of action. See :ref:`bladeburner_action_types` - :param string name: Name of action. Must be an exact match - - Returns the remaining count of the specified action. - - Note that this is meant to be used for Contracts and Operations. - This function will return 'Infinity' for actions such as Training and Field Analysis. - -getActionMaxLevel ------------------ - -.. js:function:: getActionMaxLevel(type, name) - - :param string type: Type of action. See :ref:`bladeburner_action_types` - :param string name: Name of action. Must be an exact match - - Returns the maximum level for this action. - - Returns -1 if an invalid action is specified. - -getActionCurrentLevel ---------------------- - -.. js:function:: getActionCurrentLevel(type, name) - - :param string type: Type of action. See :ref:`bladeburner_action_types` - :param string name: Name of action. Must be an exact match - - Returns the current level of this action. - - Returns -1 if an invalid action is specified. - -getActionAutolevel ------------------- - -.. js:function:: getActionAutolevel(type, name) - - :param string type: Type of action. See :ref:`bladeburner_action_types` - :param string name: Name of action. Must be an exact match - - Return a boolean indicating whether or not this action is currently set to autolevel. - - Returns false if an invalid action is specified. - -setActionAutolevel ------------------- - -.. js:function:: setActionAutolevel(type, name, autoLevel) - - :param string type: Type of action. See :ref:`bladeburner_action_types` - :param string name: Name of action. Must be an exact match - :param boolean autoLevel: Whether or not to autolevel this action - - Enable/disable autoleveling for the specified action. - -setActionLevel --------------- - -.. js:function:: setActionLevel(type, name, level) - - :param string type: Type of action. See :ref:`bladeburner_action_types` - :param string name: Name of action. Must be an exact match - :param level int: Level to set this action to - - Set the level for the specified action. - -getRank -------- - -.. js:function:: getRank() - - Returns the player's Bladeburner Rank - -getSkillPoints --------------- - -.. js:function:: getSkillPoints() - - Returns the number of Bladeburner skill points you have - -getSkillLevel -------------- - -.. js:function:: getSkillLevel(skillName="") - - :param string skillName: Name of skill. Case-sensitive and must be an exact match - - This function returns your level in the specified skill. - - The function returns -1 if an invalid skill name is passed in - -getSkillUpgradeCost -------------------- - -.. js:function:: getSkillUpgradeCost(skillName="") - - :param string skillName: Name of skill. Case-sensitive and must be an exact match - - This function returns the number of skill points needed to upgrade the - specified skill. - - The function returns -1 if an invalid skill name is passed in. - -upgradeSkill ------------- - -.. js:function:: upgradeSkill(skillName) - - :param string skillName: Name of Skill to be upgraded. Case-sensitive and must be an exact match - - Attempts to upgrade the specified Bladeburner skill. Returns true if the - skill is successfully upgraded, and false otherwise - -getTeamSize ------------ - -.. js:function:: getTeamSize(type, name) - - :param string type: Type of action. See :ref:`bladeburner_action_types` - :param string name: Name of action. Must be an exact match - - Returns the number of Bladeburner team members you have assigned to the - specified action. - - Setting a team is only applicable for Operations and BlackOps. This function - will return 0 for other action types. - -setTeamSize ------------ - -.. js:function:: setTeamSize(type, name, size) - - :param string type: Type of action. See :ref:`bladeburner_action_types` - :param string name: Name of action. Must be an exact match - :param int size: Number of team members to set. Will be converted using Math.round() - - Set the team size for the specified Bladeburner action. - - Returns the team size that was set, or -1 if the function failed. - -getCityEstimatedPopulation --------------------------- - -.. js:function:: getCityEstimatedPopulation(cityName) - - :param string cityName: Name of city. Case-sensitive - - Returns the estimated number of Synthoids in the specified city, or -1 - if an invalid city was specified. - -getCityEstimatedCommunities ---------------------------- - -.. js:function:: getCityEstimatedCommunities(cityName) - - :param string cityName: Name of city. Case-sensitive - - Returns the estimated number of Synthoid communities in the specified city, - or -1 if an invalid city was specified. - -getCityChaos ------------- - -.. js:function:: getCityChaos(cityName) - - :param string cityName: Name of city. Case-sensitive - - Returns the chaos in the specified city, or -1 if an invalid city was specified - -getCity -------- - -.. js:function:: getCity() - - Returns the city that the player is currently in (for Bladeburner). - -switchCity ----------- - -.. js:function:: switchCity(cityName) - - :param string cityName: Name of city - - Attempts to switch to the specified city (for Bladeburner only). - - Returns true if successful, and false otherwise - -getStamina ----------- - -.. js:function:: getStamina() - - Returns an array with two elements: - - [Current stamina, Max stamina] - - Example usage:: - - function getStaminaPercentage() { - let res = bladeburner.getStamina(); - return res[0] / res[1]; - } - -joinBladeburnerFaction ----------------------- - -.. js:function:: joinBladeburnerFaction() - - Attempts to join the Bladeburner faction. - - Returns true if you successfully join the Bladeburner faction, or if - you are already a member. - - Returns false otherwise. - -joinBladeburnerDivision ------------------------ - -.. js:function:: joinBladeburnerDivision() - - Attempts to join the Bladeburner division. - - Returns true if you successfully join the Bladeburner division, or if you - are already a member. - - Returns false otherwise - -getBonusTime ------------- - -.. js:function:: getBonusTime() - - Returns the amount of accumulated "bonus time" (seconds) for the Bladeburner mechanic. - - "Bonus time" is accumulated when the game is offline or if the game is - inactive in the browser. - - "Bonus time" makes the game progress faster, up to 5x the normal speed. - For example, if an action takes 30 seconds to complete but you've accumulated - over 30 seconds in bonus time, then the action will only take 6 seconds - in real life to complete. - Examples -------- diff --git a/doc/source/netscript/netscriptcodingcontractapi.rst b/doc/source/netscript/netscriptcodingcontractapi.rst index 44db5e6f2..4b2e7ef3d 100644 --- a/doc/source/netscript/netscriptcodingcontractapi.rst +++ b/doc/source/netscript/netscriptcodingcontractapi.rst @@ -17,72 +17,10 @@ In :ref:`netscriptjs`:: ns.codingcontract.getDescription("foo.cct", "home"); ns.codingcontract.attempt(1, "foo.cct", "foodnstuff"); -attempt -------- +.. toctree:: -.. js:function:: attempt(answer, fn[, hostname/ip=current ip]) - - :param answer: Solution for the contract - :param string fn: Filename of the contract - :param string hostname/ip: Hostname or IP of the server containing the contract. - Optional. Defaults to current server if not provided - - Attempts to solve the Coding Contract with the provided solution. - - :returns: Boolean indicating whether the solution was correct - -getContractType ---------------- - -.. js:function:: getContractType(fn[, hostname/ip=current ip]) - - :param string fn: Filename of the contract - :param string hostname/ip: Hostname or IP of the server containing the contract. - Optional. Defaults to current server if not provided - - Returns a name describing the type of problem posed by the Coding Contract. - (e.g. Find Largest Prime Factor, Total Ways to Sum, etc.) - - :returns: A string with the contract's problem type - -getDescription --------------- - -.. js:function:: getDescription(fn[, hostname/ip=current ip]) - - :param string fn: Filename of the contract - :param string hostname/ip: Hostname or IP of the server containing the contract. - Optional. Defaults to current server if not provided - - Get the full text description for the problem posed by the Coding Contract - - :returns: A string with the contract's text description - -getData -------- - -.. js:function:: getData(fn[, hostname/ip=current ip]) - - :param string fn: Filename of the contract - :param string hostname/ip: Hostname or IP of the server containing the contract. - Optional. Defaults to current server if not provided - - Get the data associated with the specific Coding Contract. Note that this is - not the same as the contract's description. This is just the data that - the contract wants you to act on in order to solve - - :returns: The specified contract's data - -getNumTriesRemaining --------------------- - -.. js:function:: getNumTriesRemaining(fn[, hostname/ip=current ip]) - - :param string fn: Filename of the contract - :param string hostname/ip: Hostname or IP of the server containing the contract. - Optional. Defaults to current server if not provided - - Get the number of tries remaining on the contract before it - self-destructs. - - :returns: Number indicating how many attempts are remaining + attempt() + getContractType() + getDescription() + getData() + getNumTriesRemaining() diff --git a/doc/source/netscript/netscriptfunctions.rst b/doc/source/netscript/netscriptfunctions.rst index 5eac68ac5..58067d09d 100644 --- a/doc/source/netscript/netscriptfunctions.rst +++ b/doc/source/netscript/netscriptfunctions.rst @@ -6,1277 +6,83 @@ Netscript Basic Functions This page contains the complete documentation for all functions that are available in Netscript. This includes information such as function signatures, what they do, and their return values. -At the end is also a section that describes how to define your own functions in Netscript. - -hack -^^^^ - -.. js:function:: hack(hostname/ip) - - :param string hostname/ip: IP or hostname of the target server to hack - :returns: The amount of money stolen if the hack is successful, and zero otherwise - :RAM cost: 0.1 GB - - Function that is used to try and hack servers to steal money and gain hacking experience. The runtime for this command depends - on your hacking level and the target server's security level. In order to hack a server you must first gain root access - to that server and also have the required hacking level. - - A script can hack a server from anywhere. It does not need to be running on the same server to hack that server. For example, - you can create a script that hacks the 'foodnstuff' server and run that script on any server in the game. - - A successful hack() on a server will raise that server's security level by 0.002. - - Example:: - - hack("foodnstuff"); - hack("10.1.2.3"); - -grow -^^^^ - -.. js:function:: grow(hostname/ip) - - :param string hostname/ip: IP or hostname of the target server to grow - :returns: The number by which the money on the server was multiplied for the growth - :RAM cost: 0.15 GB - - Use your hacking skills to increase the amount of money available on a server. The runtime for this command depends on your hacking - level and the target server's security level. When grow() completes, the money available on a target server will be increased by a - certain, fixed percentage. This percentage is determined by the target server's growth rate (which varies between servers) and security level. - Generally, higher-level servers have higher growth rates. The getServerGrowth() function can be used to obtain a server's growth rate. - - Like hack(), grow() can be called on any server, regardless of where the script is running. The grow() command requires - root access to the target server, but there is no required hacking level to run the command. It also raises the security level - of the target server by 0.004. - - Example:: - - grow("foodnstuff"); - -weaken -^^^^^^ - -.. js:function:: weaken(hostname/ip) - - :param string hostname/ip: IP or hostname of the target server to weaken - :returns: The amount by which the target server's security level was decreased. This is equivalent to 0.05 multiplied - by the number of script threads - :RAM cost: 0.15 GB - - Use your hacking skills to attack a server's security, lowering the server's security level. The runtime for this command - depends on your hacking level and the target server's security level. This function lowers the security level of the target - server by 0.05. - - Like hack() and grow(), weaken() can be called on any server, regardless of where the script is running. This command requires - root access to the target server, but there is no required hacking level to run the command. - - Example:: - - weaken("foodnstuff"); - -hackAnalyzeThreads -^^^^^^^^^^^^^^^^^^ - -.. js:function:: hackAnalyzeThreads(hostname/ip, hackAmount) - - :param string hostname/ip: IP or hostname of server to analyze - :param number hackAmount: Amount of money you want to hack from the server - :returns: The number of threads needed to hack() the server for *hackAmount* money - :RAM cost: 1 GB - - This function returns the number of script threads you need when running - the `hack()` command to steal the specified amount of money from the target server. - - If `hackAmount` is less than zero or greater than the amount of money available - on the server, then this function returns -1. - - For example, let's say the `foodnstuff` server has $10m and you run:: - - hackAnalyzeThreads("foodnstuff", 1e6); - - If this function returns 50, this means that if your next `hack()` call - is run on a script with 50 threads, it will steal $1m from the `foodnstuff` server. - - **Warning**: The value returned by this function isn't necessarily a whole number. - -hackAnalyzePercent -^^^^^^^^^^^^^^^^^^ - -.. js:function:: hackAnalyzePercent(hostname/ip) - - :param string hostname/ip: IP or hostname of target server - :returns: The percentage of money you will steal from the target server with a single hack - :RAM cost: 1 GB - - Returns the percentage of the specified server's money you will steal with a - single hack. This value is returned in **percentage form, not decimal (Netscript - functions typically return in decimal form, but not this one).** - - For example, assume the following returns 1:: - - hackAnalyzePercent("foodnstuff"); - - This means that if hack the `foodnstuff` server, then you will steal 1% of its - total money. If you `hack()` using N threads, then you will steal N% of its total - money. - -hackChance -^^^^^^^^^^ - -.. js:function:: hackChance(hostname/ip) - - :param string hostname/ip: IP or hostname of target server - :returns: The chance you have of successfully hacking the target server - :RAM cost: 1 GB - - Returns the chance you have of successfully hacking the specified server. This - returned value is in decimal form, not percentage. - -growthAnalyze -^^^^^^^^^^^^^ - -.. js:function:: growthAnalyze(hostname/ip, growthAmount) - - :param string hostname/ip: IP or hostname of server to analyze - :param number growthAmount: Multiplicative factor by which the server is grown. Decimal form. - :returns: The amount of grow() calls needed to grow the specified server by the specified amount - :RAM cost: 1 GB - - This function returns the number of "growths" needed in order to increase the amount - of money available on the specified server by the specified amount. - - The specified amount is multiplicative and is in decimal form, not percentage. - - For example, if you want to determine how many `grow()` calls you need - to double the amount of money on `foodnstuff`, you would use:: - - growthAnalyze("foodnstuff", 2); - - If this returns 100, then this means you need to call `grow()` 100 times - in order to double the money (or once with 100 threads). - - **Warning**: The value returned by this function isn't necessarily a whole number. - -sleep -^^^^^ - -.. js:function:: sleep(n) - - :param number n: Number of milliseconds to sleep - :RAM cost: 0 GB - - Suspends the script for n milliseconds. - -print -^^^^^ - -.. js:function:: print(x) - - :param x: Value to be printed - :RAM cost: 0 GB - - Prints a value or a variable to the script's logs. - -tprint -^^^^^^ - -.. js:function:: tprint(x) - - :param x: Value to be printed - :RAM cost: 0 GB - - Prints a value or a variable to the Terminal - -clearLog -^^^^^^^^ - -.. js:function:: clearLog() - - :RAM cost: 0 GB - - Clears the script's logs - -disableLog -^^^^^^^^^^ - -.. js:function:: disableLog(fn) - - :param string fn: Name of function for which to disable logging - :RAM cost: 0 GB - - Disables logging for the given function. Logging can be disabled for - all functions by passing 'ALL' as the argument. - - Note that this does not completely remove all logging functionality. - This only stops a function from logging - when the function is successful. If the function fails, it will still log the reason for failure. - - Notable functions that cannot have their logs disabled: run, exec, exit - -enableLog -^^^^^^^^^ - -.. js:function:: enableLog(fn) - - :param string fn: Name of function for which to enable logging - :RAM cost: 0 GB - - Re-enables logging for the given function. If 'ALL' is passed into this function - as an argument, then it will revert the effects of disableLog('ALL') - -isLogEnabled -^^^^^^^^^^^^ - -.. js:function:: isLogEnabled(fn) - - :param string fn: Name of function to check - :RAM cost: 0 GB - - Returns a boolean indicating whether or not logging is enabled for that - function (or 'ALL') - -getScriptLogs -^^^^^^^^^^^^^ - -.. js:function:: getScriptLogs([fn], [hostname/ip=current ip], [args...]) - - :param string fn: Optional. Filename of script to get logs from. - :param string ip: Optional. IP or hostname of the server that the script is on - :param args...: Arguments to identify which scripts to get logs for - :RAM cost: 0 GB - - Returns a script's logs. The logs are returned as an array, where each - line is an element in the array. The most recently logged line is at the - end of the array. - - Note that there is a maximum number of lines that a script stores in its logs. - This is configurable in the game's options. - - If the function is called with no arguments, it will return the current script's logs. - - Otherwise, the `fn`, `hostname/ip,` and `args...` arguments can be used to get the logs - from another script. Remember that scripts are uniquely identified by both - their names and arguments. - - Examples:: - - // Get logs from foo.script on the current server that was run with no args - getScriptLogs("foo.script"); - - // Get logs from foo.script on the foodnstuff server that was run with no args - getScriptLogs("foo.script", "foodnstuff"); - - // Get logs from foo.script on the foodnstuff server that was run with the arguments [1, "test"] - getScriptLogs("foo.script", "foodnstuff", 1, "test"); - -scan -^^^^ - -.. js:function:: scan(hostname/ip=current ip[, hostnames=true]) - - :param string hostname/ip: IP or hostname of the server to scan - :param boolean: Optional boolean specifying whether the function should output hostnames (if true) or IP addresses (if false) - :RAM cost: 0.2 GB - - Returns an array containing the hostnames or IPs of all servers that are one node way from the specified target server. The - hostnames/IPs in the returned array are strings. - -nuke -^^^^ - -.. js:function:: nuke(hostname/ip) - - :param string hostname/ip: IP or hostname of the target server - :RAM cost: 0 GB - - Runs the NUKE.exe program on the target server. NUKE.exe must exist on your home computer. - - Example:: - - nuke("foodnstuff"); - -brutessh -^^^^^^^^ - -.. js:function:: brutessh(hostname/ip) - - :param string hostname/ip: IP or hostname of the target server - :RAM cost: 0 GB - - Runs the BruteSSH.exe program on the target server. BruteSSH.exe must exist on your home computer. - - Example:: - - brutessh("foodnstuff"); - -ftpcrack -^^^^^^^^ - -.. js:function:: ftpcrack(hostname/ip) - - :param string hostname/ip: IP or hostname of the target server - :RAM cost: 0 GB - - Runs the FTPCrack.exe program on the target server. FTPCrack.exe must exist on your home computer. - - Example:: - - ftpcrack("foodnstuff"); - -relaysmtp -^^^^^^^^^ - -.. js:function:: relaysmtp(hostname/ip) - - :param string hostname/ip: IP or hostname of the target server - :RAM cost: 0 GB - - Runs the relaySMTP.exe program on the target server. relaySMTP.exe must exist on your home computer. - - Example:: - - relaysmtp("foodnstuff"); - -httpworm -^^^^^^^^ - -.. js:function:: httpworm(hostname/ip) - - :param string hostname/ip: IP or hostname of the target server - :RAM cost: 0 GB - - Runs the HTTPWorm.exe program on the target server. HTTPWorm.exe must exist on your home computer. - - Example:: - - httpworm("foodnstuff"); - -sqlinject -^^^^^^^^^ - -.. js:function:: sqlinject(hostname/ip) - - :param string hostname/ip: IP or hostname of the target server - :RAM cost: 0 GB - - Runs the SQLInject.exe program on the target server. SQLInject.exe must exist on your home computer. - - Example:: - - sqlinject("foodnstuff"); - -run -^^^ - -.. js:function:: run(script, [numThreads=1], [args...]) - - :param string script: Filename of script to run - :param number numThreads: Optional thread count for new script. Set to 1 by default. Will be rounded to nearest integer - :param args...: - Additional arguments to pass into the new script that is being run. Note that if any arguments are being - passed into the new script, then the second argument *numThreads* must be filled in with a value. - :RAM cost: 1 GB - - Run a script as a separate process. This function can only be used to run scripts located on the current server (the server - running the script that calls this function). - - Returns true if the script is successfully started, and false otherwise. - - Running this function with a *numThreads* argument of 0 will return false without running the script. - However, running this function with a negative *numThreads* argument will cause a runtime error. - - The simplest way to use the *run* command is to call it with just the script name. The following example will run - 'foo.script' single-threaded with no arguments:: - - run("foo.script"); - - The following example will run 'foo.script' but with 5 threads instead of single-threaded:: - - run("foo.script", 5); - - This next example will run 'foo.script' single-threaded, and will pass the string 'foodnstuff' into the script - as an argument:: - - run("foo.script", 1, 'foodnstuff'); - -exec -^^^^ - -.. js:function:: exec(script, hostname/ip, [numThreads=1], [args...]) - - :param string script: Filename of script to execute - :param string hostname/ip: IP or hostname of the 'target server' on which to execute the script - :param number numThreads: Optional thread count for new script. Set to 1 by default. Will be rounded to nearest integer - :param args...: - Additional arguments to pass into the new script that is being run. Note that if any arguments are being - passed into the new script, then the third argument *numThreads* must be filled in with a value. - :RAM cost: 1.3 GB - - Run a script as a separate process on a specified server. This is similar to the *run* function except - that it can be used to run a script on any server, instead of just the current server. - - Returns true if the script is successfully started, and false otherwise. - - Running this function with a *numThreads* argument of 0 will return false without running the script. - However, running this function with a negative *numThreads* argument will cause a runtime error. - - The simplest way to use the *exec* command is to call it with just the script name and the target server. - The following example will try to run *generic-hack.script* on the *foodnstuff* server:: - - exec("generic-hack.script", "foodnstuff"); - - The following example will try to run the script *generic-hack.script* on the *joesguns* server with 10 threads:: - - exec("generic-hack.script", "joesguns", 10); - - This last example will try to run the script *foo.script* on the *foodnstuff* server with 5 threads. It will also pass - the number 1 and the string "test" in as arguments to the script:: - - exec("foo.script", "foodnstuff", 5, 1, "test"); - -spawn -^^^^^ - -.. js:function:: spawn(script, numThreads, [args...]) - - :param string script: Filename of script to execute - :param number numThreads: Number of threads to spawn new script with. Will be rounded to nearest integer - :param args...: - Additional arguments to pass into the new script that is being run. - :RAM cost: 2 GB - - Terminates the current script, and then after a delay of about 20 seconds it will execute the newly-specified script. - The purpose of this function is to execute a new script without being constrained by the RAM usage of the current one. - This function can only be used to run scripts on the local server. - - Because this function immediately terminates the script, it does not have a return value. - - The following example will execute the script 'foo.script' with 10 threads and the arguments 'foodnstuff' and 90:: - - spawn('foo.script', 10, 'foodnstuff', 90); - -kill -^^^^ - -.. js:function:: kill(script, hostname/ip, [args...]) - - :param string script: Filename of the script to kill - :param string hostname/ip: IP or hostname of the server on which to kill the script - :param args...: Arguments to identify which script to kill - :RAM cost: 0.5 GB - - Kills the script on the target server specified by the script's name and arguments. Remember that scripts - are uniquely identified by both their name and arguments. For example, if *foo.script* is run with the argument 1, then this - is not the same as *foo.script* run with the argument 2, even though they have the same code. - - If this function successfully kills the specified script, then it will return true. Otherwise, it will return false. - - Examples: - - The following example will try to kill a script named *foo.script* on the *foodnstuff* server that was ran with no arguments:: - - kill("foo.script", "foodnstuff"); - - The following will try to kill a script named *foo.script* on the current server that was ran with no arguments:: - - kill("foo.script", getHostname()); - - The following will try to kill a script named *foo.script* on the current server that was ran with the arguments 1 and "foodnstuff":: - - kill("foo.script", getHostname(), 1, "foodnstuff"); - -killall -^^^^^^^ - -.. js:function:: killall(hostname/ip) - - :param string hostname/ip: IP or hostname of the server on which to kill all scripts - :RAM cost: 0.5 GB - - Kills all running scripts on the specified server. This function returns true if any scripts were killed, and - false otherwise. In other words, it will return true if there are any scripts running on the target server. - - -exit -^^^^ - -.. js:function:: exit() - - :RAM cost: 0 GB - - Terminates the current script immediately - -scp -^^^ - -.. js:function:: scp(files, [source], destination) - - :param string/array files: Filename or an array of filenames of script/literature files to copy - :param string source: - Hostname or IP of the source server, which is the server from which the file will be copied. - This argument is optional and if it's omitted the source will be the current server. - :param string destination: Hostname or IP of the destination server, which is the server to which the file will be copied. - :RAM cost: 0.6 GB - - Copies a script or literature (.lit) file(s) to another server. The *files* argument can be either a string specifying a - single file to copy, or an array of strings specifying multiple files to copy. - - Returns true if the script/literature file is successfully copied over and false otherwise. If the *files* argument is an array - then this function will return true if at least one of the files in the array is successfully copied. - - Examples:: - - //Copies hack-template.script from the current server to foodnstuff - scp("hack-template.script", "foodnstuff"); - - //Copies foo.lit from the helios server to the home computer - scp("foo.lit", "helios", "home"); - - //Tries to copy three files from rothman-uni to home computer - files = ["foo1.lit", "foo2.script", "foo3.script"]; - scp(files, "rothman-uni", "home"); - -ls -^^ - -.. js:function:: ls(hostname/ip, [grep]) - - :param string hostname/ip: Hostname or IP of the target server - :param string grep: a substring to search for in the filename - :RAM cost: 0 GB - - Returns an array with the filenames of all files on the specified server (as strings). The returned array - is sorted in alphabetic order - -ps -^^ - -.. js:function:: ps(hostname/ip=current ip) - - :param string ip: Hostname or IP address of the target server. - If not specified, it will be the current server's IP by default - :RAM cost: 0.2 GB - - Returns an array with general information about all scripts running on the specified - target server. The information for each server is given in an object with - the following structure:: - - { - filename: Script name, - threads: Number of threads script is running with, - args: Script's arguments - } - - Example usage (using :doc:`netscriptjs`):: - - export async function main(ns) { - const ps = ns.ps("home"); - for (let i = 0; i < ps.length; ++i) { - ns.tprint(ps[i].filename + ' ' + ps[i].threads); - ns.tprint(ps[i].args); - } - } - -hasRootAccess -^^^^^^^^^^^^^ - -.. js:function:: hasRootAccess(hostname/ip) - - :param string hostname/ip: Hostname or IP of the target server - :RAM cost: 0.05 GB - - Returns a boolean indicating whether or not the player has root access to the specified target server. - - Example:: - - if (hasRootAccess("foodnstuff") == false) { - nuke("foodnstuff"); - } - -getHostname -^^^^^^^^^^^ - -.. js:function:: getHostname() - - :RAM cost: 0.05 GB - - Returns a string with the hostname of the server that the script is running on - -getHackingLevel -^^^^^^^^^^^^^^^ - -.. js:function:: getHackingLevel() - - :RAM cost: 0.05 GB - - Returns the player's current hacking level - -getHackingMultipliers -^^^^^^^^^^^^^^^^^^^^^ - -.. js:function:: getHackingMultipliers() - - :RAM cost: 4 GB - - Returns an object containing the Player's hacking related multipliers. These multipliers are - returned in decimal forms, not percentages (e.g. 1.5 instead of 150%). The object has the following structure:: - - { - chance: Player's hacking chance multiplier, - speed: Player's hacking speed multiplier, - money: Player's hacking money stolen multiplier, - growth: Player's hacking growth multiplier - } - - Example of how this can be used:: - - mults = getHackingMultipliers(); - print(mults.chance); - print(mults.growth); - -getHacknetMultipliers -^^^^^^^^^^^^^^^^^^^^^ - -.. js:function:: getHacknetMultipliers() - - :RAM cost: 4 GB - - Returns an object containing the Player's hacknet related multipliers. These multipliers are - returned in decimal forms, not percentages (e.g. 1.5 instead of 150%). The object has the following structure:: - - { - production: Player's hacknet production multiplier, - purchaseCost: Player's hacknet purchase cost multiplier, - ramCost: Player's hacknet ram cost multiplier, - coreCost: Player's hacknet core cost multiplier, - levelCost: Player's hacknet level cost multiplier - } - - Example of how this can be used:: - - mults = getHacknetMultipliers(); - print(mults.production); - print(mults.purchaseCost); - - - -getServerMoneyAvailable -^^^^^^^^^^^^^^^^^^^^^^^ - -.. js:function:: getServerMoneyAvailable(hostname/ip) - - :param string hostname/ip: Hostname or IP of target server - :RAM cost: 0.1 GB - - Returns the amount of money available on a server. **Running this function on the home computer will return - the player's money.** - - Example:: - - getServerMoneyAvailable("foodnstuff"); - getServerMoneyAvailable("home"); //Returns player's money - -getServerMaxMoney -^^^^^^^^^^^^^^^^^ - -.. js:function:: getServerMaxMoney(hostname/ip) - - :param string hostname/ip: Hostname or IP of target server - :RAM cost: 0.1 GB - - Returns the maximum amount of money that can be available on a server - -getServerGrowth -^^^^^^^^^^^^^^^ - -.. js:function:: getServerGrowth(hostname/ip) - - :param string hostname/ip: Hostname or IP of target server - :RAM cost: 0.1 GB - - Returns the server's instrinsic "growth parameter". This growth parameter is a number - between 1 and 100 that represents how quickly the server's money grows. This parameter affects the - percentage by which the server's money is increased when using the *grow()* function. A higher - growth parameter will result in a higher percentage increase from *grow()*. - -getServerSecurityLevel -^^^^^^^^^^^^^^^^^^^^^^ - -.. js:function:: getServerSecurityLevel(hostname/ip) - - :param string hostname/ip: Hostname or IP of target server - :RAM cost: 0.1 GB - - Returns the security level of the target server. A server's security level is denoted by a number, typically - between 1 and 100 (but it can go above 100). - -getServerBaseSecurityLevel -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. js:function:: getServerBaseSecurityLevel(hostname/ip) - - :param string hostname/ip: Hostname or IP of target server - :RAM cost: 0.1 GB - - Returns the base security level of the target server. This is the security level that the server starts out with. - This is different than *getServerSecurityLevel()* because *getServerSecurityLevel()* returns the current - security level of a server, which can constantly change due to *hack()*, *grow()*, and *weaken()*, calls on that - server. The base security level will stay the same until you reset by installing an Augmentation(s). - -getServerMinSecurityLevel -^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. js:function:: getServerMinSecurityLevel(hostname/ip) - - :param string hostname/ip: Hostname or IP of target server - :RAM cost: 0.1 GB - - Returns the minimum security level of the target server - -getServerRequiredHackingLevel -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. js:function:: getServerRequiredHackingLevel(hostname/ip) - - :param string hostname/ip: Hostname or IP of target server - :RAM cost: 0.1 GB - - Returns the required hacking level of the target server - -getServerNumPortsRequired -^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. js:function:: getServerNumPortsRequired(hostname/ip) - - :param string hostname/ip: Hostname or IP of target server - :RAM cost: 0.1 GB - - Returns the number of open ports required to successfully run NUKE.exe on the specified server. - -getServerRam -^^^^^^^^^^^^ - -.. js:function:: getServerRam(hostname/ip) - - :param string hostname/ip: Hostname or IP of target server - :RAM cost: 0.1 GB - - Returns an array with two elements that gives information about a server's memory (RAM). The first - element in the array is the amount of RAM that the server has total (in GB). The second element in - the array is the amount of RAM that is currently being used on the server (in GB). - - Example:: - - res = getServerRam("helios"); - totalRam = res[0]; - ramUsed = res[1]; - -serverExists -^^^^^^^^^^^^ - -.. js:function:: serverExists(hostname/ip) - - :param string hostname/ip: Hostname or IP of target server - :RAM cost: 0.1 GB - - Returns a boolean denoting whether or not the specified server exists - -fileExists -^^^^^^^^^^ - -.. js:function:: fileExists(filename, [hostname/ip]) - - :param string filename: Filename of file to check - :param string hostname/ip: - Hostname or IP of target server. This is optional. If it is not specified then the - function will use the current server as the target server - :RAM cost: 0.1 GB - - Returns a boolean indicating whether the specified file exists on the target server. The filename - for scripts is case-sensitive, but for other types of files it is not. For example, *fileExists("brutessh.exe")* - will work fine, even though the actual program is named "BruteSSH.exe". - - If the *hostname/ip* argument is omitted, then the function will search through the current server (the server - running the script that calls this function) for the file. - - Examples:: - - fileExists("foo.script", "foodnstuff"); - fileExists("ftpcrack.exe"); - - The first example above will return true if the script named *foo.script* exists on the *foodnstuff* server, and false otherwise. - The second example above will return true if the current server contains the *FTPCrack.exe* program, and false otherwise. - -isRunning -^^^^^^^^^ - -.. js:function:: isRunning(filename, hostname/ip, [args...]) - - :param string filename: Filename of script to check. This is case-sensitive. - :param string hostname/ip: Hostname or IP of target server - :param args...: Arguments to specify/identify which scripts to search for - :RAM cost: 0.1 GB - - Returns a boolean indicating whether the specified script is running on the target server. Remember that a script is - uniquely identified by both its name and its arguments. - - **Examples:** - - In this first example below, the function call will return true if there is a script named *foo.script* with no arguments - running on the *foodnstuff* server, and false otherwise:: - - isRunning("foo.script", "foodnstuff"); - - In this second example below, the function call will return true if there is a script named *foo.script* with no arguments - running on the current server, and false otherwise:: - - isRunning("foo.script", getHostname()); - - In this next example below, the function call will return true if there is a script named *foo.script* running with the arguments - 1, 5, and "test" (in that order) on the *joesguns* server, and false otherwise:: - - isRunning("foo.script", "joesguns", 1, 5, "test"); - -getNextHacknetNodeCost -^^^^^^^^^^^^^^^^^^^^^^ - -.. js:function:: getNextHacknetNodeCost() - - :RAM cost: 0 GB - - Deprecated (no longer usable). See :doc:`netscripthacknetnodeapi` - -purchaseHacknetNode -^^^^^^^^^^^^^^^^^^^ - -.. js:function:: purchaseHacknetNode() - - :RAM cost: 0 GB - - Deprecated (no longer usable). See :doc:`netscripthacknetnodeapi` - -getPurchasedServerCost -^^^^^^^^^^^^^^^^^^^^^^ - -.. js:function:: getPurchasedServerCost(ram) - - :RAM cost: 0.25 GB - - :param number ram: Amount of RAM of a potential purchased server. Must be a power of 2 (2, 4, 8, 16, etc.). Maximum value of 1048576 (2^20) - - Returns the cost to purchase a server with the specified amount of *ram*. - - Examples:: - - for (i = 1; i <= 20; i++) { - tprint(i + " -- " + getPurchasedServerCost(Math.pow(2, i))); - } - -purchaseServer -^^^^^^^^^^^^^^ - -.. js:function:: purchaseServer(hostname, ram) - - :param string hostname: Hostname of the purchased server - :param number ram: Amount of RAM of the purchased server. Must be a power of 2 (2, 4, 8, 16, etc.). Maximum value of 1048576 (2^20) - :RAM cost: 2.25 GB - - Purchased a server with the specified hostname and amount of RAM. - - The *hostname* argument can be any data type, but it will be converted to a string and have whitespace removed. Anything that resolves to an empty string will - cause the function to fail. If there is already a server with the specified hostname, then the function will automatically append - a number at the end of the *hostname* argument value until it finds a unique hostname. For example, if the script calls - *purchaseServer("foo", 4)* but a server named "foo" already exists, the it will automatically change the hostname to "foo-0". If there is already - a server with the hostname "foo-0", then it will change the hostname to "foo-1", and so on. - - Note that there is a maximum limit to the amount of servers you can purchase. - - Returns the hostname of the newly purchased server as a string. If the function fails to purchase a server, then it will return an - empty string. The function will fail if the arguments passed in are invalid, if the player does not have enough money to purchase - the specified server, or if the player has exceeded the maximum amount of servers. - - Example:: - - ram = 64; - hn = "pserv-"; - for (i = 0; i < 5; ++i) { - purchaseServer(hn + i, ram); - } - -deleteServer -^^^^^^^^^^^^ - -.. js:function:: deleteServer(hostname) - - :param string hostname: Hostname of the server to delete - :RAM cost: 2.25 GB - - Deletes one of your purchased servers, which is specified by its hostname. - - The *hostname* argument can be any data type, but it will be converted to a string. Whitespace is automatically removed from - the string. This function will not delete a server that still has scripts running on it. - - Returns true if successful, and false otherwise. - -getPurchasedServers -^^^^^^^^^^^^^^^^^^^ - -.. js:function:: getPurchasedServers([hostname=true]) - - :param boolean hostname: - Specifies whether hostnames or IP addresses should be returned. If it's true then hostnames will be returned, and if false - then IPs will be returned. If this argument is omitted then it is true by default - :RAM cost: 2.25 GB - - Returns an array with either the hostnames or IPs of all of the servers you have purchased. - -getPurchasedServerLimit -^^^^^^^^^^^^^^^^^^^^^^^ - -.. js:function:: getPurchasedServerLimit() - - :RAM cost: 0.05 GB - - Returns the maximum number of servers you can purchase - -getPurchasedServerMaxRam -^^^^^^^^^^^^^^^^^^^^^^^^ - -.. js:function:: getPurchasedServerMaxRam() - - :RAM cost: 0.05 GB - - Returns the maximum RAM that a purchased server can have - -write -^^^^^ - -.. js:function:: write(port/fn, data="", mode="a") - - :param string/number port/fn: Port or text file/script that will be written to - :param string data: Data to write - :param string mode: Defines the write mode. Only valid when writing to text files or scripts. - :RAM cost: 1 GB - - This function can be used to either write data to a port, a text file (.txt), or a script (.script, .js, .ns) - - If the first argument is a number between 1 and 20, then it specifies a port and this function will write *data* to that port. Read - about how :ref:`netscript_ports` work here. The third argument, *mode*, is not used - when writing to a port. - - If the first argument is a string, then it specifies the name of a text file or script and this function will write *data* to that text file/script. If the - specified text file/script does not exist, then it will be created. The third argument *mode*, defines how the data will be written. If *mode* - is set to "w", then the data is written in "write" mode which means that it will overwrite all existing data on the text file/script. If *mode* is set to - any other value then the data will be written in "append" mode which means that the data will be added at the end of the file. - -tryWrite -^^^^^^^^ - -.. js:function:: tryWrite(port, data="") - - :param number port: Port to be written to - :param string data: Data to try to write - :returns: True if the data is successfully written to the port, and false otherwise - :RAM cost: 1 GB - - Attempts to write data to the specified Netscript Port. If the port is full, the data will - not be written. Otherwise, the data will be written normally - -read -^^^^ - -.. js:function:: read(port/fn) - - :param string/number port/fn: Port or text file to read from - :RAM cost: 1 GB - - This function is used to read data from a port, a text file (.txt), or a script (.script, .js, .ns) - - If the argument *port/fn* is a number between 1 and 20, then it specifies a port and it will read data from that port. Read - about how :ref:`netscript_ports` work here. A port is a serialized queue. This function - will remove the first element from that queue and return it. If the queue is empty, then the string "NULL PORT DATA" will be returned. - - If the argument *port/fn* is a string, then it specifies the name of a text file or script and this function will return the data in the specified text file/script. If - the text file does not exist, an empty string will be returned. - -peek -^^^^ - -.. js:function:: peek(port) - - :param number port: Port to peek. Must be an integer between 1 and 20 - :RAM cost: 1 GB - - This function is used to peek at the data from a port. It returns the first element in the specified port - without removing that element. If the port is empty, the string "NULL PORT DATA" will be returned. - - Read about how :ref:`netscript_ports` work here - -clear -^^^^^ - -.. js:function:: clear(port/fn) - - :param string/number port/fn: Port or text file to clear - :RAM cost: 1 GB - - This function is used to clear data in a `Netscript Ports `_ or a text file. - - If the *port/fn* argument is a number between 1 and 20, then it specifies a port and will clear it (deleting all data from the underlying queue). - - If the *port/fn* argument is a string, then it specifies the name of a text file (.txt) and will delete all data from that text file. - -getPortHandle -^^^^^^^^^^^^^ - -.. js:function:: getPortHandle(port) - - :param number port: Port number - :RAM cost: 10 GB - - Get a handle to a Netscript Port. See more details here: :ref:`netscript_ports` - - **WARNING:** Port Handles only work in :ref:`netscriptjs`. They will not work in :ref:`netscript1`. - -rm -^^ - -.. js:function:: rm(fn[, hostname/ip=current server]) - - :param string fn: Filename of file to remove. Must include the extension - :param string hostname/ip: Hostname or IP Address of the server on which to delete the file. Optional. Defaults to current server - :returns: True if it successfully deletes the file, and false otherwise - :RAM cost: 1 GB - - Removes the specified file from the current server. This function works for every file type except message (.msg) files. - -scriptRunning -^^^^^^^^^^^^^ - -.. js:function:: scriptRunning(scriptname, hostname/ip) - - :param string scriptname: Filename of script to check. This is case-sensitive. - :param string hostname/ip: Hostname or IP of target server - :RAM cost: 1 GB - - Returns a boolean indicating whether any instance of the specified script is running on the target server, regardless of - its arguments. - - This is different than the *isRunning()* function because it does not try to identify a specific instance of a running script - by its arguments. - - **Examples:** - - The example below will return true if there is any script named *foo.script* running on the *foodnstuff* server, and false otherwise:: - - scriptRunning("foo.script", "foodnstuff"); - - The example below will return true if there is any script named "foo.script" running on the current server, and false otherwise:: - - scriptRunning("foo.script", getHostname()); - -scriptKill -^^^^^^^^^^ - -.. js:function:: scriptKill(scriptname, hostname/ip) - - :param string scriptname: Filename of script to kill. This is case-sensitive. - :param string hostname/ip: Hostname or IP of target server - :RAM cost: 1 GB - - Kills all scripts with the specified filename on the target server specified by *hostname/ip*, regardless of arguments. Returns - true if one or more scripts were successfully killed, and false if none were. - -getScriptName -^^^^^^^^^^^^^ - -.. js:function:: getScriptName() - - :RAM cost: 0 GB - - Returns the current script name - -getScriptRam -^^^^^^^^^^^^ - -.. js:function:: getScriptRam(scriptname[, hostname/ip]) - - :param string scriptname: Filename of script. This is case-sensitive. - :param string hostname/ip: Hostname or IP of target server the script is located on. This is optional, If it is not specified then the function will set the current server as the target server. - :RAM cost: 0.1 GB - - Returns the amount of RAM required to run the specified script on the target server. Returns - 0 if the script does not exist. - -getHackTime -^^^^^^^^^^^ - -.. js:function:: getHackTime(hostname/ip[, hackLvl=current level]) - - :param string hostname/ip: Hostname or IP of target server - :param number hackLvl: Optional hacking level for the calculation. Defaults to player's current hacking level - :RAM cost: 0.05 GB - - Returns the amount of time in seconds it takes to execute the *hack()* Netscript function on the target server. - - The function takes in an optional *hackLvl* parameter that can be specified - to see what the hack time would be at different hacking levels. - -getGrowTime -^^^^^^^^^^^ - -.. js:function:: getGrowTime(hostname/ip[, hackLvl=current level]) - - :param string hostname/ip: Hostname or IP of target server - :param number hackLvl: Optional hacking level for the calculation. Defaults to player's current hacking level - :RAM cost: 0.05 GB - - Returns the amount of time in seconds it takes to execute the *grow()* Netscript function on the target server. - - The function takes in an optional *hackLvl* parameter that can be specified - to see what the grow time would be at different hacking levels. - -getWeakenTime -^^^^^^^^^^^^^ - -.. js:function:: getWeakenTime(hostname/ip[, hackLvl=current level]) - - :param string hostname/ip: Hostname or IP of target server - :param number hackLvl: Optional hacking level for the calculation. Defaults to player's current hacking level - :RAM cost: 0.05 GB - - Returns the amount of time in seconds it takes to execute the *weaken()* Netscript function on the target server. - - The function takes in an optional *hackLvl* parameter that can be specified - to see what the weaken time would be at different hacking levels. - -getScriptIncome -^^^^^^^^^^^^^^^ - -.. js:function:: getScriptIncome([scriptname], [hostname/ip], [args...]) - - :param string scriptname: Filename of script - :param string hostname/ip: Server on which script is running - :param args...: Arguments that the script is running with - :RAM cost: 0.1 GB - - Returns the amount of income the specified script generates while online (when the game is open, does not apply for offline income). - Remember that a script is uniquely identified by both its name and its arguments. So for example if you ran a script with the arguments - "foodnstuff" and "5" then in order to use this function to get that script's income you must specify those same arguments in the same order - in this function call. - - This function can also be called with no arguments. If called with no arguments, then this function will return an array of two values. The - first value is the total income ($ / second) of all of your active scripts (scripts that are currently running on any server). The second value - is the total income ($ / second) that you've earned from scripts since you last installed Augmentations. - -getScriptExpGain -^^^^^^^^^^^^^^^^ - -.. js:function:: getScriptExpGain([scriptname], [hostname/ip], [args...]) - - :param string scriptname: Filename of script - :param string hostname/ip: Server on which script is running - :param args...: Arguments that the script is running with - :RAM cost: 0.1 GB - - Returns the amount of hacking experience the specified script generates while online (when the game is open, does not apply for offline experience gains). - Remember that a script is uniquely identified by both its name and its arguments. - - This function can also return the total experience gain rate of all of your active scripts by running the function with no arguments. - -getTimeSinceLastAug -^^^^^^^^^^^^^^^^^^^ - -.. js:function:: getTimeSinceLastAug() - - :RAM cost: 0.05 GB - - Returns the amount of time in milliseconds that have passed since you last installed Augmentations - -sprintf -^^^^^^^ - -.. js:function:: sprintf() - - :RAM cost: 0 GB - - See `this link `_ for details. - -vsprintf -^^^^^^^^ - -.. js:function:: vsprintf() - - :RAM cost: 0 GB - - See `this link `_ for details. - -nFormat -^^^^^^^ - -.. js:function:: nFormat(n, format) - - :param number n: Number to format - :param string format: Formatter - - Converts a number into a string with the specified formatter. This uses the - `numeraljs `_ library, so the formatters must be compatible - with that. - - This is the same function that the game itself uses to display numbers. - - Examples:: - - nFormat(1.23e9, "$0.000a"); // Returns "$1.230b" - nFormat(12345.678, "0,0"); // Returns "12,346" - nFormat(0.84, "0.0%"); // Returns "84.0% - -prompt -^^^^^^ - -.. js:function:: prompt(txt) - - :param string txt: Text to appear in the prompt dialog box - :RAM cost: 0 GB - - Prompts the player with a dialog box with two options: "Yes" and "No". This function will return true if the player click "Yes" and - false if the player clicks "No". The script's execution is halted until the player selects one of the options. - -wget -^^^^ - -.. js:function:: wget(url, target[, hostname/ip=current ip]) - - :param string url: URL to pull data from - :param string target: Filename to write data to. Must be script or text file - :param string ip: Optional hostname/ip of server for target file. - :RAM cost: 0 GB - - Retrieves data from a URL and downloads it to a file on the specified server. The data can only - be downloaded to a script (.script, .ns, .js) or a text file (.txt). If the file already exists, - it will be overwritten by this command. - - Note that it will not be possible to download data from many websites because they do not allow - cross-origin resource sharing (CORS). Example:: - - wget("https://raw.githubusercontent.com/danielyxie/bitburner/master/README.md", "game_readme.txt"); - - **IMPORTANT:** This is an asynchronous function that returns a Promise. The Promise's resolved - value will be a boolean indicating whether or not the data was successfully - retrieved from the URL. Because the function is async and returns a Promise, - it is recommended you use :code:`wget` in :ref:`netscriptjs`. - - In NetscriptJS, you must preface any call to - :code:`wget` with the :code:`await` keyword (like you would :code:`hack` or :code:`sleep`). - - :code:`wget` will still work in :ref:`netscript1`, but the functions execution will not - be synchronous (i.e. it may not execute when you expect/want it to). Furthermore, since Promises are not - supported in ES5, you will not be able to process the returned value of :code:`wget` in - Netscript 1.0. - -getFavorToDonate -^^^^^^^^^^^^^^^^ - - :RAM cost: 0.1 GB - - Returns the amount of Faction favor required to be able to donate to a faction. +.. toctree:: + :caption: Functions: + + hack() + grow() + weaken() + hackAnalyzeThreads() + hackAnalyzePercent() + hackChance() + growthAnalyze() + sleep() + print() + tprint() + clearLog() + disableLog() + enableLog() + isLogEnabled() + getScriptLogs() + scan() + nuke() + brutessh() + ftpcrack() + relaysmtp() + httpworm() + sqlinject() + run() + exec() + spawn() + kill() + killall() + exit() + scp() + ls() + ps() + hasRootAccess() + getHostname() + getHackingLevel() + getHackingMultipliers() + getHacknetMultipliers() + getServerMoneyAvailable() + getServerMaxMoney() + getServerGrowth() + getServerSecurityLevel() + getServerBaseSecurityLevel() + getServerMinSecurityLevel() + getServerRequiredHackingLevel() + getServerNumPortsRequired() + getServerRam() + serverExists() + fileExists() + isRunning() + getPurchasedServerCost() + purchaseServer() + deleteServer() + getPurchasedServers() + getPurchasedServerLimit() + getPurchasedServerMaxRam() + write() + tryWrite() + read() + peek() + clear() + getPortHandle() + rm() + scriptRunning() + scriptKill() + getScriptName() + getScriptRam() + getHackTime() + getGrowTime() + getWeakenTime() + getScriptIncome() + getScriptExpGain() + getTimeSinceLastAug() + sprintf() + vsprintf() + nFormat() + prompt() + wget() + getFavorToDonate() diff --git a/doc/source/netscript/netscriptgangapi.rst b/doc/source/netscript/netscriptgangapi.rst index 392f7192c..95c322845 100644 --- a/doc/source/netscript/netscriptgangapi.rst +++ b/doc/source/netscript/netscriptgangapi.rst @@ -23,255 +23,22 @@ In :ref:`netscriptjs`:: ns.gang.getMemberNames(); ns.gang.recruitMember("Fry"); -getMemberNames --------------- - -.. js:function:: getMemberNames() - - Get the names of all Gang members - - :returns: An array of the names of all Gang members as strings - -getGangInformation ------------------- - -.. js:function:: getGangInformation() - - Get general information about the gang - - :returns: An object with the gang information. - - The object has the following structure:: - - { - faction: Name of faction that the gang belongs to ("Slum Snakes", etc.) - isHacking: Boolean indicating whether or not its a hacking gang - moneyGainRate: Money earned per second - power: Gang's power for territory warfare - respect: Gang's respect - respectGainRate: Respect earned per second - territory: Amount of territory held. Returned in decimal form, not percentage - territoryClashChance: Clash chance. Returned in decimal form, not percentage - wantedLevel: Gang's wanted level - wantedLevelGainRate: Wanted level gained/lost per second (negative for losses) - } - -getOtherGangInformation ------------------------ - -.. js:function:: getOtherGangInformation() - - Get territory and power information about all gangs - - :returns: An object with information about all gangs - - The object has the following structure:: - - { - "Slum Snakes" : { - power: Slum Snakes' power - territory: Slum Snakes' territory, in decimal form - }, - "Tetrads" : { - power: ... - territory: ... - }, - "The Syndicate" : { - power: ... - territory: ... - }, - ... (for all six gangs) - } - -getMemberInformation --------------------- - -.. js:function:: getMemberInformation(name) - - :param string name: Name of member - - Get stat and equipment-related information about a Gang Member - - :returns: An object with the gang member information. - - The object has the following structure:: - - { - agility: Agility stat - agilityEquipMult: Agility multiplier from equipment. Decimal form - agilityAscensionMult: Agility multiplier from ascension. Decimal form - augmentations: Array of names of all owned Augmentations - charisma: Charisma stat - charismaEquipMult: Charisma multiplier from equipment. Decimal form - charismaAscensionMult: Charisma multiplier from ascension. Decimal form - defense: Defense stat - defenseEquipMult: Defense multiplier from equipment. Decimal form - defenseAscensionMult: Defense multiplier from ascension. Decimal form - dexterity: Dexterity stat - dexterityEquipMult: Dexterity multiplier from equipment. Decimal form - dexterityAscensionMult: Dexterity multiplier from ascension. Decimal form - equipment: Array of names of all owned Non-Augmentation Equipment - hacking: Hacking stat - hackingEquipMult: Hacking multiplier from equipment. Decimal form - hackingAscensionMult: Hacking multiplier from ascension. Decimal form - strength: Strength stat - strengthEquipMult: Strength multiplier from equipment. Decimal form - strengthAscensionMult: Strength multiplier from ascension. Decimal form - task: Name of currently assigned task - } - -canRecruitMember ----------------- - -.. js:function:: canRecruitMember() - - :returns: Boolean indicating whether a member can currently be recruited - -recruitMember -------------- - -.. js:function:: recruitMember(name) - - :param string name: Name of member to recruit - - Attempt to recruit a new gang member. - - Possible reasons for failure: - * Cannot currently recruit a new member - * There already exists a member with the specified name - - :returns: True if the member was successfully recruited. False otherwise - -getTaskNames ------------- - -.. js:function:: getTaskNames() - - Get the name of all valid tasks that Gang members can be assigned to - - :returns: Array of strings of all task names - -setMemberTask -------------- - -.. js:function:: setMemberTask(memberName, taskName) - - :param string memberName: Name of Gang member to assign - :param string taskName: Task to assign - - Attempts to assign the specified Gang Member to the specified task. - If an invalid task is specified, the Gang member will be set to idle ("Unassigned") - - :returns: True if the Gang Member was successfully assigned to the task. False otherwise - -getEquipmentNames ------------------ - -.. js:function:: getEquipmentNames() - - Get the name of all possible equipment/upgrades you can purchase for your - Gang Members. This includes Augmentations. - - :returns: Array of strings of the names of all Equpiment/Augmentations - -getEquipmentCost ----------------- - -.. js:function:: getEquipmentCost(equipName) - - :param string equipName: Name of equipment - - Get the amount of money it takes to purchase a piece of Equipment or an Augmentation. - If an invalid Equipment/Augmentation is specified, this function will return Infinity. - - :returns: Cost to purchase the specified Equipment/Augmentation (number). Infinity - for invalid arguments - -getEquipmentType ----------------- - -.. js:function:: getEquipmentType(equipName) - - :param string equipName: Name of equipment - - Get the specified equipment type, which can be one of the following: - - * Weapon - * Armor - * Vehicle - * Rootkit - * Augmentation - - :returns: A string stating the type of the equipment - -purchaseEquipment ------------------ - -.. js:function:: purchaseEquipment(memberName, equipName) - - :param string memberName: Name of Gang member to purchase the equipment for - :param string equipName: Name of Equipment/Augmentation to purchase - - Attempt to purchase the specified Equipment/Augmentation for the specified - Gang member. - - :returns: True if the equipment was successfully purchased. False otherwise - - -ascendMember ------------- - -.. js:function:: ascendMember(name) - - :param string name: Name of member to ascend - - Ascend the specified Gang Member. - - :returns: An object with info about the ascension results. - - The object has the following structure:: - - { - respect: Amount of respect lost from ascending - hack: Hacking multiplier gained from ascending. Decimal form - str: Strength multiplier gained from ascending. Decimal form - def: Defense multiplier gained from ascending. Decimal form - dex: Dexterity multiplier gained from ascending. Decimal form - agi: Agility multiplier gained from ascending. Decimal form - cha: Charisma multiplier gained from ascending. Decimal form - } - - -setTerritoryWarfare -------------------- - -.. js:function:: setTerritoryWarfare(engage) - - :param bool engage: Whether or not to engage in territory warfare - - Set whether or not the gang should engage in territory warfare - -getChanceToWinClash -------------------- - -.. js:function:: getChanceToWinClash(gangName) - - :param string gangName: Target gang - - Returns the chance you have to win a clash with the specified gang. The chance - is returned in decimal form, not percentage - - -getBonusTime ------------- - -.. js:function:: getBonusTime() - - Returns the amount of accumulated "bonus time" (seconds) for the Gang mechanic. - - "Bonus time" is accumulated when the game is offline or if the game is - inactive in the browser. - - "Bonus time" makes the game progress faster, up to 10x the normal speed. - - :returns: Bonus time for the Gang mechanic in seconds +.. toctree:: + :caption: API Functions: + + getMemberNames() + getGangInformation() + getOtherGangInformation() + getMemberInformation() + canRecruitMember() + recruitMember() + getTaskNames() + setMemberTask() + getEquipmentNames() + getEquipmentCost() + getEquipmentType() + purchaseEquipment() + ascendMember() + setTerritoryWarfare() + getChanceToWinClash() + getBonusTime() diff --git a/doc/source/netscript/netscripthacknetnodeapi.rst b/doc/source/netscript/netscripthacknetnodeapi.rst index d1433eb21..fde650836 100644 --- a/doc/source/netscript/netscripthacknetnodeapi.rst +++ b/doc/source/netscript/netscripthacknetnodeapi.rst @@ -1,4 +1,4 @@ -.. _netscripthacknetnodeapi: +.. _netscript_hacknetnodeapi: Netscript Hacknet Node API ========================== @@ -21,6 +21,22 @@ In :ref:`netscriptjs`:: ns.hacknet.purchaseNode(); ns.hacknet.getNodeStats(3).level; +.. toctree:: + :caption: API Functions: + + numNodes() + purchaseNode() + getPurchaseNodeCost() + getNodeStats() + upgradeLevel() + upgradeRam() + upgradeCore() + getLevelUpgradeCost() + getRamUpgradeCost() + getCoreUpgradeCost() + +.. _netscript_hacknetnodeapi_referencingahacknetnode: + Referencing a Hacknet Node -------------------------- Most of the functions in the Hacknet Node API perform an operation on a single @@ -35,128 +51,7 @@ RAM Cost -------- Accessing the `hacknet` namespace incurs a one time cost of 4 GB of RAM. In other words, using multiple Hacknet Node API functions in a script will not cost -more than 4 GB of RAM. - -numNodes --------- -.. js:function:: numNodes() - - Returns the number of Hacknet Nodes you own. - -purchaseNode ------------- -.. js:function:: purchaseNode() - - Purchases a new Hacknet Node. Returns a number with the index of the Hacknet Node. - This index is equivalent to the number at the end of the Hacknet Node's name - (e.g The Hacknet Node named 'hacknet-node-4' will have an index of 4). - - If the player cannot afford to purchase a new Hacknet Node then the function - will return -1. - -getPurchaseNodeCost -------------------- -.. js:function:: getPurchaseNodeCost() - - Returns the cost of purchasing a new Hacknet Node - -getNodeStats ------------- -.. js:function:: getNodeStats(i) - - :param number i: Index/Identifier of Hacknet Node - - Returns an object containing a variety of stats about the specified Hacknet Node:: - - { - name: Node's name ("hacknet-node-5"), - level: Node's level, - ram: Node's RAM, - cores: Node's number of cores, - production: Node's money earned per second, - timeOnline: Number of seconds since Node has been purchased, - totalProduction: Total number of money Node has produced - } - -upgradeLevel ------------- -.. js:function:: upgradeLevel(i, n) - - :param number i: Index/Identifier of Hacknet Node - :param number n: Number of levels to purchase. Must be positive. Rounded to nearest integer - - Tries to upgrade the level of the specified Hacknet Node by *n*. - - Returns true if the Hacknet Node's level is successfully upgraded by *n* or - if it is upgraded by some positive amount and the Node reaches its max level. - - Returns false otherwise. - -upgradeRam ----------- -.. js:function:: upgradeRam(i, n) - - :param number i: Index/Identifier of Hacknet Node - :param number n: Number of times to upgrade RAM. Must be positive. Rounded to nearest integer - - Tries to upgrade the specified Hacknet Node's RAM *n* times. Note that each upgrade - doubles the Node's RAM. So this is equivalent to multiplying the Node's RAM by - 2 :sup:`n`. - - Returns true if the Hacknet Node's RAM is successfully upgraded *n* times or if - it is upgraded some positive number of times and the Node reaches it max RAM. - - Returns false otherwise. - -upgradeCore ------------ -.. js:function:: upgradeCore(i, n) - - :param number i: Index/Identifier of Hacknet Node - :param number n: Number of cores to purchase. Must be positive. Rounded to nearest integer - - Tries to purchase *n* cores for the specified Hacknet Node. - - Returns true if it successfully purchases *n* cores for the Hacknet Node or if - it purchases some positive amount and the Node reaches its max number of cores. - - Returns false otherwise. - -getLevelUpgradeCost -------------------- -.. js:function:: getLevelUpgradeCost(i, n) - - :param number i: Index/Identifier of Hacknet Node - :param number n: Number of levels to upgrade. Must be positive. Rounded to nearest integer - - Returns the cost of upgrading the specified Hacknet Node by *n* levels. - - If an invalid value for *n* is provided, then this function returns 0. If the - specified Hacknet Node is already at max level, then Infinity is returned. - -getRamUpgradeCost ------------------ -.. js:function:: getRamUpgradeCost(i, n) - - :param number i: Index/Identifier of Hacknet Node - :param number n: Number of times to upgrade RAM. Must be positive. Rounded to nearest integer - - Returns the cost of upgrading the RAM of the specified Hacknet Node *n* times. - - If an invalid value for *n* is provided, then this function returns 0. If the - specified Hacknet Node is already at max RAM, then Infinity is returned. - -getCoreUpgradeCost ------------------- -.. js:function:: getCoreUpgradeCost(i, n) - - :param number i: Index/Identifier of Hacknet Node - :param number n: Number of times to upgrade cores. Must be positive. Rounded to nearest integer - - Returns the cost of upgrading the number of cores of the specified Hacknet Node by *n*. - - If an invalid value for *n* is provided, then this function returns 0. If the - specified Hacknet Node is already at the max number of cores, then Infinity is returned. +more than 4 GB of RAM. Utilities --------- @@ -164,28 +59,10 @@ The following functions are not officially part of the Hacknet Node API, but the can be useful when writing Hacknet Node-related scripts. Since they are not part of the API, they do not need to be accessed using the *hacknet* namespace. -.. js:function:: getHacknetMultipliers() - - Returns an object containing the Player's hacknet related multipliers. These multipliers are - returned in integer forms, not percentages (e.g. 1.5 instead of 150%). The object has the following structure:: - - { - production: Player's hacknet production multiplier, - purchaseCost: Player's hacknet purchase cost multiplier, - ramCost: Player's hacknet ram cost multiplier, - coreCost: Player's hacknet core cost multiplier, - levelCost: Player's hacknet level cost multiplier - } - - Example of how this can be used:: - - mults = getHacknetMultipliers(); - print(mults.production); - print(mults.purchaseCost); - +* :js:func:`getHacknetMultipliers` Example(s) -^^^^^^^^^^ +---------- The following is an example of one way a script can be used to automate the purchasing and upgrading of Hacknet Nodes. @@ -194,8 +71,9 @@ This script attempts to purchase Hacknet Nodes until the player has a total of 8 it gradually upgrades those Node's to a minimum of level 140, 64 GB RAM, and 8 cores:: function myMoney() { - return getServerMoneyAvailable("home"); - } + return getServerMoneyAvailable("home");() + } + }() disableLog("getServerMoneyAvailable"); disableLog("sleep"); diff --git a/doc/source/netscript/netscriptixapi.rst b/doc/source/netscript/netscriptixapi.rst index 98bbfcdd8..9a1d11b66 100644 --- a/doc/source/netscript/netscriptixapi.rst +++ b/doc/source/netscript/netscriptixapi.rst @@ -13,328 +13,21 @@ TIX API can be purchased by visiting the World Stock Exchange in-game. Access to the TIX API currently costs $5 billion. After you purchase it, you will retain this access even after you 'reset' by installing Augmentations -getStockSymbols ---------------- - -.. js:function:: getStockSymbols() - - :RAM cost: 2 GB - - Returns an array of the symbols of the tradable stocks - -getStockPrice -------------- - -.. js:function:: getStockPrice(sym) - - :param string sym: Stock symbol - :RAM cost: 2 GB - - Returns the price of a stock, given its symbol (NOT the company name). The symbol is a sequence - of two to four capital letters. - - Example:: - - getStockPrice("FISG"); - -getStockPosition ----------------- - -.. js:function:: getStockPosition(sym) - - :param string sym: Stock symbol - :RAM cost: 2 GB - - Returns an array of four elements that represents the player's position in a stock. - - The first element is the returned array is the number of shares the player owns of the stock in the - `Long position `_. The second - element in the array is the average price of the player's shares in the Long position. - - The third element in the array is the number of shares the player owns of the stock in the - `Short position `_. The fourth - element in the array is the average price of the player's Short position. - - All elements in the returned array are numeric. - - Example:: - - pos = getStockPosition("ECP"); - shares = pos[0]; - avgPx = pos[1]; - sharesShort = pos[2]; - avgPxShort = pos[3]; - -getStockMaxShares ------------------ - - -.. js:function:: getStockMaxShares(sym) - - :param string sym: Stock symbol - :RAM cost: 2 GB - - Returns the maximum number of shares that the stock has. This is the maximum - amount of the stock that can be purchased in both the Long and Short - positions combined - -buyStock --------- - -.. js:function:: buyStock(sym, shares) - - :param string sym: Symbol of stock to purchase - :param number shares: Number of shares to purchased. Must be positive. Will be rounded to nearest integer - :RAM cost: 2.5 GB - - Attempts to purchase shares of a stock using a `Market Order `_. - - If the player does not have enough money to purchase the specified number of shares, then no shares will be purchased. Remember - that every transaction on the stock exchange costs a certain commission fee. - - If this function successfully purchases the shares, it will return the stock price at which each share was purchased. Otherwise, - it will return 0. - -sellStock ---------- - -.. js:function:: sellStock(sym, shares) - - :param string sym: Symbol of stock to sell - :param number shares: Number of shares to sell. Must be positive. Will be rounded to nearest integer - :RAM cost: 2.5 GB - - Attempts to sell shares of a stock using a `Market Order `_. - - If the specified number of shares in the function exceeds the amount that the player actually owns, then this function will - sell all owned shares. Remember that every transaction on the stock exchange costs a certain commission fee. - - The net profit made from selling stocks with this function is reflected in the script's statistics. - This net profit is calculated as:: - - shares * (sell price - average price of purchased shares) - - If the sale is successful, this function will return the stock price at which each share was sold. Otherwise, it will return 0. - -shortStock ----------- - -.. js:function:: shortStock(sym, shares) - - :param string sym: Symbol of stock to short - :param number shares: Number of shares to short. Must be positive. Will be rounded to nearest integer - :RAM cost: 2.5 GB - - Attempts to purchase a `short `_ position of a stock - using a `Market Order `_. - - The ability to short a stock is **not** immediately available to the player and must be unlocked later on in the game. - - If the player does not have enough money to purchase the specified number of shares, then no shares will be purchased. - Remember that every transaction on the stock exchange costs a certain commission fee. - - If the purchase is successful, this function will return the stock price at which each share was purchased. Otherwise, it will return 0. - -sellShort ---------- - -.. js:function:: sellShort(sym, shares) - - :param string sym: Symbol of stock to sell - :param number shares: Number of shares to sell. Must be positive. Will be rounded to nearest integer - :RAM cost: 2.5 GB - - Attempts to sell a `short `_ position of a stock - using a `Market Order `_. - - The ability to short a stock is **not** immediately available to the player and must be unlocked later on in the game. - - If the specified number of shares exceeds the amount that the player actually owns, then this function will sell all owned - shares. Remember that every transaction on the stock exchange costs a certain commission fee. - - If the sale is successful, this function will return the stock price at which each share was sold. Otherwise it will return 0. - -placeOrder ----------- - -.. js:function:: placeOrder(sym, shares, price, type, pos) - - :param string sym: Symbol of stock to player order for - :param number shares: Number of shares for order. Must be positive. Will be rounded to nearest integer - :param number price: Execution price for the order - :param string type: Type of order. It must specify "limit" or "stop", and must also specify "buy" or "sell". This is NOT - case-sensitive. Here are four examples that will work: - - * limitbuy - * limitsell - * stopbuy - * stopsell - - :param string pos: - Specifies whether the order is a "Long" or "Short" position. The Values "L" or "S" can also be used. This is - NOT case-sensitive. - :RAM cost: 2.5 GB - - Places an order on the stock market. This function only works for `Limit and Stop Orders `_. - - The ability to place limit and stop orders is **not** immediately available to the player and must be unlocked later on in the game. - - Returns true if the order is successfully placed, and false otherwise. - -cancelOrder ------------ - -.. js:function:: cancelOrder(sym, shares, price, type, pos) - - :param string sym: Symbol of stock to player order for - :param number shares: Number of shares for order. Must be positive. Will be rounded to nearest integer - :param number price: Execution price for the order - :param string type: Type of order. It must specify "limit" or "stop", and must also specify "buy" or "sell". This is NOT - case-sensitive. Here are four examples that will work: - - * limitbuy - * limitsell - * stopbuy - * stopsell - - :param string pos: - Specifies whether the order is a "Long" or "Short" position. The Values "L" or "S" can also be used. This is - NOT case-sensitive. - :RAM cost: 2.5 GB - - Cancels an oustanding Limit or Stop order on the stock market. - - The ability to use limit and stop orders is **not** immediately available to the player and must be unlocked later on in the game. - -getOrders ---------- - -.. js:function:: getOrders() - - :RAM cost: 2.5 GB - - Returns your order book for the stock market. This is an object containing information - for all the Limit and Stop Orders you have in the stock market. - - The object has the following structure:: - - { - StockSymbol1: [ // Array of orders for this stock - { - shares: Order quantity - price: Order price - type: Order type - position: Either "L" or "S" for Long or Short position - }, - { - ... - }, - ... - ], - StockSymbol2: [ // Array of orders for this stock - ... - ], - ... - } - - The "Order type" property can have one of the following four values: - - * "Limit Buy Order" - * "Limit Sell Order" - * "Stop Buy Order" - * "Stop Sell Order" - - **Note that the order book will only contain information for stocks that you actually - have orders in**. For example, if you do not have orders in Nova Medical (NVMD), then the returned - object will not have a "NVMD" property. - - Example:: - - { - ECP: [ - { - shares: 5, - price: 100,000 - type: "Stop Buy Order", - position: "S", - }, - { - shares: 25, - price: 125,000 - type: "Limit Sell Order", - position: "L", - }, - ], - SYSC: [ - { - shares: 100, - price: 10,000 - type: "Limit Buy Order", - position: "L", - }, - ], - } - -getStockVolatility ------------------- - -.. js:function:: getStockVolatility(sym) - - :param string sym: Symbol of stock - :RAM cost: 2.5 GB - - Returns the volatility of the specified stock. - - Volatility represents the maximum percentage by which a stock's price can - change every tick. The volatility is returned as a decimal value, NOT - a percentage (e.g. if a stock has a volatility of 3%, then this function will - return 0.03, NOT 3). - - In order to use this function, you must first purchase access to the Four Sigma (4S) - Market Data TIX API. - -getStockForecast ----------------- - -.. js:function:: getStockForecast(sym) - - :param string sym: Symbol of stock - :RAM cost: 2.5 GB - - Returns the probability that the specified stock's price will increase - (as opposed to decrease) during the next tick. - - The probability is returned as a decimal value, NOT a percentage (e.g. if a - stock has a 60% chance of increasing, then this function will return 0.6, - NOT 60). - - In other words, if this function returned 0.30 for a stock, then this means - that the stock's price has a 30% chance of increasing and a 70% chance of - decreasing during the next tick. - - In order to use this function, you must first purchase access to the Four Sigma (4S) - Market Data TIX API. - -purchase4SMarketData --------------------- - -.. js:function:: purchase4SMarketData() - - :RAM cost: 2.5 GB - - Purchase 4S Market Data Access. - - Returns true if you successfully purchased it or if you already have access. - Returns false otherwise. - -purchase4SMarketDataTixApi --------------------------- - -.. js:function:: purchase4SMarketDataTixApi() - - :RAM cost: 2.5 GB - - Purchase 4S Market Data TIX API Access. - - Returns true if you successfully purchased it or if you already have access. - Returns false otherwise. +.. toctree:: + :caption: API Functions: + + getStockSymbols() + getStockPrice() + getStockPosition() + getStockMaxShares() + buyStock() + sellStock() + shortStock() + sellShort() + placeOrder() + cancelOrder() + getOrders() + getStockVolatility() + getStockForecast() + purchase4SMarketData() + purchase4SMarketDataTixApi() diff --git a/doc/source/netscript/netscriptsingularityfunctions.rst b/doc/source/netscript/netscriptsingularityfunctions.rst index 9ba8da067..413d44f60 100644 --- a/doc/source/netscript/netscriptsingularityfunctions.rst +++ b/doc/source/netscript/netscriptsingularityfunctions.rst @@ -18,602 +18,39 @@ level 3, then you will be able to access all of the Singularity Functions. Note that Singularity Functions require twice as much RAM outside of BitNode-4 -universityCourse ----------------- - -.. js:function:: universityCourse(universityName, courseName) - - :param string universityName: - Name of university. Not case-sensitive. You must be in the correct city for whatever university you specify. - - * Summit University - * Rothman University - * ZB Institute Of Technology - :param string courseName: - Name of course. Not case-sensitive. - - * Study Computer Science - * Data Strucures - * Networks - * Algorithms - * Management - * Leadership - - If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to use this function. - - This function will automatically set you to start taking a course at a university. If you are already in the middle of some - "working" action (such as working at a company, for a faction, or on a program), then running this function will automatically - cancel that action and give you your earnings. - - The cost and experience gains for all of these universities and classes are the same as if you were to manually visit and take these classes. - - This function will return true if you successfully start taking the course, and false otherwise. - -gymWorkout ----------- - -.. js:function:: gymWorkout(gymName, stat) - - :param string gymName: - Name of gym. Not case-sensitive. You must be in the correct city for whatever gym you specify. - - * Crush Fitness Gym - * Snap Fitness Gym - * Iron Gym - * Powerhouse Gym - * Millenium Fitness Gym - :param string stat: - The stat you want to train. Not case-sensitive. - - * strength OR str - * defense OR def - * dexterity OR dex - * agility OR agi - - If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to use this function. - - This function will automatically set you to start working out at a gym to train a particular stat. If you are - already in the middle of some "working" action (such as working at a company, for a faction, or on a program), - then running this function will automatically cancel that action and give you your earnings. - - The cost and experience gains for all of these gyms are the same as if you were to manually visit these gyms and train - - This function will return true if you successfully start working out at the gym, and false otherwise. - -travelToCity ------------- - -.. js:function:: travelToCity(cityName) - - :param string cityName: - City to travel to. CASE-SENSITIVE. - - * Aevum - * Chongqing - * Sector-12 - * New Tokyo - * Ishima - * Volhaven - - If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to use this function. - - This function allows the player to travel to any city. The cost for using this function is the same as the cost for traveling through the Travel Agency. - - This function will return true if you successfully travel to the specified city and false otherwise. - -purchaseTor ------------ - -.. js:function:: purchaseTor() - - If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to use this function. - - This function allows you to automatically purchase a TOR router. The cost for purchasing a TOR router using this - function is the same as if you were to manually purchase one. - - This function will return true if it successfully purchase a TOR router and false otherwise. - -purchaseProgram ---------------- - -.. js:function:: purchaseProgram(programName) - - :param string programName: Name of program to purchase. Must include '.exe' extension. Not case-sensitive. - - If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to use this function. - - This function allows you to automatically purchase programs. You MUST have a TOR router in order to use this function. - The cost of purchasing programs using this function is the same as if you were purchasing them through the Dark Web using the - Terminal *buy* command. - - Example:: - - purchaseProgram("brutessh.exe"); - - This function will return true if the specified program is purchased, and false otherwise. - -getStats --------- - -.. js:function:: getStats() - - If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to run this function. - - Returns an object with the Player's stats. The object has the following properties:: - - { - hacking - strength - defense - dexterity - agility - charisma - intelligence - } - - Example:: - - res = getStats(); - print('My charisma level is: ' + res.charisma); - -getCharacterInformation ------------------------ - - If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to run this function. - - Returns an object with various information about your character. The object has the following properties:: - - { - bitnode: Current BitNode number - city: Name of city you are currently in - factions: Array of factions you are currently a member of - hp: Current health points - jobs: Array of all companies at which you have jobs - jobTitle: Array of job positions for all companies you are employed at. Same order as 'jobs' - maxHp: Maximum health points - tor: Boolean indicating whether or not you have a tor router - - // The following is an object with many of the player's multipliers from Augmentations/Source Files - mult: { - agility: Agility stat - agilityExp: Agility exp - companyRep: Company reputation - crimeMoney: Money earned from crimes - crimeSuccess: Crime success chance - defense: Defense stat - defenseExp: Defense exp - dexterity: Dexterity stat - dexterityExp: Dexterity exp - factionRep: Faction reputation - hacking: Hacking stat - hackingExp: Hacking exp - strength: Strength stat - strengthExp: Strength exp - workMoney: Money earned from jobs - }, - - // The following apply only to when the character is performing - // some type of working action, such as working for a company/faction - timeWorked: Timed worked in ms - workHackExpGain: Hacking experience earned so far from work - workStrExpGain: Str experience earned so far from work - workDefExpGain: Def experience earned so far from work - workDexExpGain: Dex experience earned so far from work - workAgiExpGain: Agi experience earned so far from work - workChaExpGain: Cha experience earned so far from work - workRepGain: Reputation earned so far from work, if applicable - workMoneyGain: Money earned so far from work, if applicable - } - -isBusy ------- - -.. js:function:: isBusy() - - If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to run this function. - - Returns a boolean indicating whether or not the player is currently performing an 'action'. These actions include - working for a company/faction, studying at a univeristy, working out at a gym, creating a program, or committing a crime. - -stopAction ----------- - -.. js:function:: stopAction() - - If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to run this function. - This function is used to end whatever 'action' the player is currently performing. The player - will receive whatever money/experience/etc. he has earned from that action. - - The actions that can be stopped with this function are: - - * Studying at a university - * Working for a company/faction - * Creating a program - * Committing a Crime - - This function will return true if the player's action was ended. It will return false if the player was not - performing an action when this function was called. - -upgradeHomeRam --------------- - -.. js:function:: upgradeHomeRam() - - If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function. - - This function will upgrade amount of RAM on the player's home computer. The cost is the same as if you were to do it manually. - - This function will return true if the player's home computer RAM is successfully upgraded, and false otherwise. - -getUpgradeHomeRamCost ---------------------- - -.. js:function:: getUpgradeHomeRamCost() - - If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function. - - Returns the cost of upgrading the player's home computer RAM. - -workForCompany --------------- - -.. js:function:: workForCompany() - - If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function. - - This function will automatically set you to start working at the company at which you are employed. - If you are already in the middle of some "working" action (such as working for a faction, training at - a gym, or creating a program), then running this function will automatically cancel that action and give you your earnings. - - This function will return true if the player starts working, and false otherwise. - - Note that when you are working for a company, you will not actually receive your earnings - (reputation, money, experience) until you FINISH the action. This can be an issue if, for example, - you only want to work until you get 100,000 company reputation. One small hack to get around this is to - continuously restart the action to receive your earnings:: - - while (getCompanyRep(COMPANY HERE) < VALUE) { - workForCompany(); - sleep(60000); - } - - This way, your company reputation will be updated every minute. - -applyToCompany --------------- - -.. js:function:: applyToCompany(companyName, field) - - :param string companyName: Name of company to apply to. CASE-SENSITIVE. - :param string field: - Field to which you want to apply. Not case-sensitive - - * software - * software consultant - * it - * security engineer - * network engineer - * business - * business consultant - * security - * agent - * employee - * part-time employee - * waiter - * part-time waiter - - If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function. - - This function will automatically try to apply to the specified company for a position in the specified - field. This function can also be used to apply for promotions by specifying the company and field you - are already employed at. - - This function will return true if you successfully get a job/promotion, and false otherwise. Note that - if you are trying to use this function to apply for a promotion and you don't get one, it will return false. - -getCompanyRep -------------- - -.. js:function:: getCompanyRep(companyName) - - :param string companyName: Name of the company. CASE-SENSITIVE - - If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function. - - This function will return the amount of reputation you have at the specified company. - If the company passed in as an argument is invalid, -1 will be returned. - -getCompanyFavor ---------------- - -.. js:function:: getCompanyFavor(companyName) - - :param string companyName: Name of the company. CASE-SENSITIVE - - If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function. - - This function will return the amount of favor you have at the specified company. - If the company passed in as an argument is invalid, -1 will be returned. - -getCompanyFavorGain -------------------- - -.. js:function:: getCompanyFavorGain(companyName) - - :param string companyName: Name of the company. CASE-SENSITIVE - - If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function. - - This function will return the amount of favor you will gain for the specified company - when you reset by installing Augmentations. - -checkFactionInvitations ------------------------ - -.. js:function:: checkFactionInvitations() - - If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function. - - Returns an array with the name of all Factions you currently have oustanding invitations from. - -joinFaction ------------ - -.. js:function:: joinFaction(name) - - :param string name: Name of faction to join. CASE-SENSITIVE - - If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function. - - This function will automatically accept an invitation from a faction and join it. - -workForFaction --------------- - -.. js:function:: workForFaction(factionName, workType) - - :param string factionName: Name of faction to work for. CASE-SENSITIVE - :param string workType: - Type of work to perform for the faction - - * hacking/hacking contracts/hackingcontracts - * field/fieldwork/field work - * security/securitywork/security work - - If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function. - - This function will automatically set you to start working for the specified faction. - Obviously, you must be a member of the faction or else this function will fail. If you are already in - the middle of some "working" action (such as working for a company, training at a gym, or creating a program), - then running this function will automatically cancel that action and give you your earnings. - - This function will return true if you successfully start working for the specified faction, and false otherwise. - - Note that when you are working for a faction, you will not actually receive your earnings (reputation, experience) - until you FINISH the action. This can be an issue if, for example, you only want to work until you get 100,000 faction - reputation. One small hack to get around this is to continuously restart the action to receive your earnings:: - - while (getFactionRep(FACTION NAME) < VALUE) { - workForFaction(FACNAME, WORKTYPE); - sleep(60000); - } - - This way, your faction reputation will be updated every minute. - -getFactionRep -------------- - -.. js:function:: getFactionRep(factionName) - - :param string factionName: Name of faction. CASE-SENSITIVE - - If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function. - - This function returns the amount of reputation you have for the specified faction. - -getFactionFavor ---------------- - -.. js:function:: getFactionFavor(factionName) - - :param string factionName: Name of faction. CASE-SENSITIVE - - If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function. - - This function returns the amount of favor you have for the specified faction. - -getFactionFavorGain -------------------- - -.. js:function:: getFactionFavorGain(factionName) - - :param string factionName: Name of faction. CASE-SENSITIVE - - If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function. - - This function returns the amount of favor you will gain for the specified faction when you reset by installing Augmentations. - -donateToFaction ---------------- - -.. js:function:: donateToFaction(factionName, donateAmt) - - :param string factionName: Name of faction to donate to. CASE-SENSITIVE - :param number donateAmt: Amount of money to donate - - If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function. - - Attempts to donate money to the specified faction in exchange for reputation. - Returns true if you successfully donate the money, and false otherwise. - -createProgram -------------- - -.. js:function:: createProgram(programName) - - :param string programName: Name of program to create. Not case-sensitive - - If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function. - - This function will automatically set you to start working on creating the specified program. If you are - already in the middle of some "working" action (such as working for a company, training at a gym, or taking a course), - then running this function will automatically cancel that action and give you your earnings. - - Example: - - createProgram("relaysmtp.exe"); - - Note that creating a program using this function has the same hacking level requirements as it normally would. These level requirements are: - - * BruteSSH.exe: 50 - * FTPCrack.exe: 100 - * relaySMTP.exe: 250 - * HTTPWorm.exe: 500 - * SQLInject.exe: 750 - * DeepscanV1.exe: 75 - * DeepscanV2.exe: 400 - * ServerProfiler.exe: 75 - * AutoLink.exe: 25 - - This function returns true if you successfully start working on the specified program, and false otherwise. - -commitCrime ------------ - -.. js:function:: commitCrime(crime) - - :param string crime: - Name of crime to attempt. Not case-sensitive. This argument is fairly lenient in terms of what inputs it accepts. - Here is a list of valid inputs for all of the crimes: - - * shoplift - * rob store - * mug - * larceny - * deal drugs - * bond forgery - * traffick arms - * homicide - * grand theft auto - * kidnap - * assassinate - * heist - - If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function. - - This function is used to automatically attempt to commit crimes. If you are already in the middle of some 'working' action - (such as working for a company or training at a gym), then running this function will automatically cancel that action and give you your earnings. - - This function returns the number of seconds it takes to attempt the specified crime (e.g It takes 60 seconds to attempt the 'Rob Store' crime, - so running *commitCrime('rob store')* will return 60). - - Warning: I do not recommend using the time returned from this function to try and schedule your crime attempts. - Instead, I would use the isBusy() Singularity function to check whether you have finished attempting a crime. - This is because although the game sets a certain crime to be X amount of seconds, there is no guarantee that your - browser will follow that time limit. - -getCrimeChance --------------- - -.. js:function:: getCrimeChance(crime) - - :param string crime: - Name of crime. Not case-sensitive. This argument is fairlyn lenient in terms of what inputs it accepts. - Check the documentation for the *commitCrime()* function for a list of example inputs. - - If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function. - - This function returns your chance of success at commiting the specified crime. The chance is returned as a decimal (i.e. 60% would be returned as 0.6). - -getOwnedAugmentations ---------------------- - -.. js:function:: getOwnedAugmentations(purchased=false) - - :param boolean purchase: - Specifies whether the returned array should include Augmentations you have purchased but not yet installed. - By default, this argument is false which means that the return value will NOT have the purchased Augmentations. - - If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function. - - This function returns an array containing the names (as strings) of all Augmentations you have. - -getOwnedSourceFiles -------------------- - -.. js:function:: getOwnedSourceFiles() - - If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function. - - Returns an array of source files - [{n: 1, lvl: 3}, {n: 4, lvl: 3}] - - -getAugmentationsFromFaction ---------------------------- - -.. js:function:: getAugmentationsFromFaction(facName) - - :param string facName: Name of faction. CASE-SENSITIVE - - If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function. - - Returns an array containing the names (as strings) of all Augmentations that are available from the specified faction. - -getAugmentationPrereq ---------------------- - -.. js:function:: getAugmentationPrereq(augName) - - :param string augName: Name of Augmentation. CASE-SENSITIVE - - If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function. - - This function returns an array with the names of the prerequisite Augmentation(s) for the specified Augmentation. - If there are no prerequisites, a blank array is returned. - - If an invalid Augmentation name is passed in for the *augName* argument, this function will return a blank array. - -getAugmentationCost -------------------- - -.. js:function:: getAugmentationCost(augName) - - :param string augName: Name of Augmentation. CASE-SENSITIVE - - If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function. - - This function returns an array with two elements that gives the cost for the specified Augmentation. - The first element in the returned array is the reputation requirement of the Augmentation, and the second element is the money cost. - - If an invalid Augmentation name is passed in for the *augName* argument, this function will return the array [-1, -1]. - -purchaseAugmentation --------------------- - -.. js:function:: purchaseAugmentation(factionName, augName) - - :param string factionName: Name of faction to purchase Augmentation from. CASE-SENSITIVE - :param string augName: Name of Augmentation to purchase. CASE-SENSITIVE - - - If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function. - - This function will try to purchase the specified Augmentation through the given Faction. - - This function will return true if the Augmentation is successfully purchased, and false otherwise. - -installAugmentations --------------------- - -.. js:function:: installAugmentations(cbScript) - - :param string cbScript: - Optional callback script. This is a script that will automatically be run after Augmentations are installed (after the reset). - This script will be run with no arguments and 1 thread. It must be located on your home computer. - - If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function. - - This function will automatically install your Augmentations, resetting the game as usual. - - It will return true if successful, and false otherwise. +.. toctree:: + :caption: Functions: + + universityCourse() + gymWorkout() + travelToCity() + purchaseTor() + purchaseProgram() + getStats() + getCharacterInformation() + isBusy() + stopAction() + upgradeHomeRam() + getUpgradeHomeRamCost() + workForCompany() + applyToCompany() + getCompanyRep() + getCompanyFavor() + getCompanyFavorGain() + checkFactionInvitations() + joinFaction() + workForFaction() + getFactionRep() + getFactionFavor() + getFactionFavorGain() + donateToFaction() + createProgram() + commitCrime() + getCrimeChance() + getOwnedAugmentations() + getOwnedSourceFiles() + getAugmentationsFromFaction() + getAugmentationPrereq() + getAugmentationCost() + purchaseAugmentation() + installAugmentations() diff --git a/doc/source/netscript/singularityfunctions/applyToCompany.rst b/doc/source/netscript/singularityfunctions/applyToCompany.rst new file mode 100644 index 000000000..b562bf7a7 --- /dev/null +++ b/doc/source/netscript/singularityfunctions/applyToCompany.rst @@ -0,0 +1,31 @@ +applyToCompany() Netscript Function +=================================== + +.. js:function:: applyToCompany(companyName, field) + + :param string companyName: Name of company to apply to. CASE-SENSITIVE. + :param string field: + Field to which you want to apply. Not case-sensitive + + * software + * software consultant + * it + * security engineer + * network engineer + * business + * business consultant + * security + * agent + * employee + * part-time employee + * waiter + * part-time waiter + + If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function. + + This function will automatically try to apply to the specified company for a position in the specified + field. This function can also be used to apply for promotions by specifying the company and field you + are already employed at. + + This function will return true if you successfully get a job/promotion, and false otherwise. Note that + if you are trying to use this function to apply for a promotion and you don't get one, it will return false. diff --git a/doc/source/netscript/singularityfunctions/checkFactionInvitations.rst b/doc/source/netscript/singularityfunctions/checkFactionInvitations.rst new file mode 100644 index 000000000..7dd54a2a9 --- /dev/null +++ b/doc/source/netscript/singularityfunctions/checkFactionInvitations.rst @@ -0,0 +1,8 @@ +checkFactionInvitations() Netscript Function +============================================ + +.. js:function:: checkFactionInvitations() + + If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function. + + Returns an array with the name of all Factions you currently have oustanding invitations from. diff --git a/doc/source/netscript/singularityfunctions/commitCrime.rst b/doc/source/netscript/singularityfunctions/commitCrime.rst new file mode 100644 index 000000000..226cfa990 --- /dev/null +++ b/doc/source/netscript/singularityfunctions/commitCrime.rst @@ -0,0 +1,34 @@ +commitCrime() Netscript Function +================================ + +.. js:function:: commitCrime(crime) + + :param string crime: + Name of crime to attempt. Not case-sensitive. This argument is fairly lenient in terms of what inputs it accepts. + Here is a list of valid inputs for all of the crimes: + + * shoplift + * rob store + * mug + * larceny + * deal drugs + * bond forgery + * traffick arms + * homicide + * grand theft auto + * kidnap + * assassinate + * heist + + If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function. + + This function is used to automatically attempt to commit crimes. If you are already in the middle of some 'working' action + (such as working for a company or training at a gym), then running this function will automatically cancel that action and give you your earnings. + + This function returns the number of seconds it takes to attempt the specified crime (e.g It takes 60 seconds to attempt the 'Rob Store' crime, + so running *commitCrime('rob store')* will return 60). + + Warning: I do not recommend using the time returned from this function to try and schedule your crime attempts. + Instead, I would use the isBusy() Singularity function to check whether you have finished attempting a crime. + This is because although the game sets a certain crime to be X amount of seconds, there is no guarantee that your + browser will follow that time limit. diff --git a/doc/source/netscript/singularityfunctions/createProgram.rst b/doc/source/netscript/singularityfunctions/createProgram.rst new file mode 100644 index 000000000..30d6568ee --- /dev/null +++ b/doc/source/netscript/singularityfunctions/createProgram.rst @@ -0,0 +1,30 @@ +createProgram() Netscript Function +================================== + +.. js:function:: createProgram(programName) + + :param string programName: Name of program to create. Not case-sensitive + + If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function. + + This function will automatically set you to start working on creating the specified program. If you are + already in the middle of some "working" action (such as working for a company, training at a gym, or taking a course), + then running this function will automatically cancel that action and give you your earnings. + + Example: + + createProgram("relaysmtp.exe"); + + Note that creating a program using this function has the same hacking level requirements as it normally would. These level requirements are: + + * BruteSSH.exe: 50 + * FTPCrack.exe: 100 + * relaySMTP.exe: 250 + * HTTPWorm.exe: 500 + * SQLInject.exe: 750 + * DeepscanV1.exe: 75 + * DeepscanV2.exe: 400 + * ServerProfiler.exe: 75 + * AutoLink.exe: 25 + + This function returns true if you successfully start working on the specified program, and false otherwise. diff --git a/doc/source/netscript/singularityfunctions/donateToFaction.rst b/doc/source/netscript/singularityfunctions/donateToFaction.rst new file mode 100644 index 000000000..f61cc70e6 --- /dev/null +++ b/doc/source/netscript/singularityfunctions/donateToFaction.rst @@ -0,0 +1,12 @@ +donateToFaction() Netscript Function +==================================== + +.. js:function:: donateToFaction(factionName, donateAmt) + + :param string factionName: Name of faction to donate to. CASE-SENSITIVE + :param number donateAmt: Amount of money to donate + + If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function. + + Attempts to donate money to the specified faction in exchange for reputation. + Returns true if you successfully donate the money, and false otherwise. diff --git a/doc/source/netscript/singularityfunctions/getAugmentationCost.rst b/doc/source/netscript/singularityfunctions/getAugmentationCost.rst new file mode 100644 index 000000000..1d7b623a8 --- /dev/null +++ b/doc/source/netscript/singularityfunctions/getAugmentationCost.rst @@ -0,0 +1,13 @@ +getAugmentationCost() Netscript Function +======================================== + +.. js:function:: getAugmentationCost(augName) + + :param string augName: Name of Augmentation. CASE-SENSITIVE + + If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function. + + This function returns an array with two elements that gives the cost for the specified Augmentation. + The first element in the returned array is the reputation requirement of the Augmentation, and the second element is the money cost. + + If an invalid Augmentation name is passed in for the *augName* argument, this function will return the array [-1, -1]. diff --git a/doc/source/netscript/singularityfunctions/getAugmentationPrereq.rst b/doc/source/netscript/singularityfunctions/getAugmentationPrereq.rst new file mode 100644 index 000000000..efe5c38f0 --- /dev/null +++ b/doc/source/netscript/singularityfunctions/getAugmentationPrereq.rst @@ -0,0 +1,13 @@ +getAugmentationPrereq() Netscript Function +========================================== + +.. js:function:: getAugmentationPrereq(augName) + + :param string augName: Name of Augmentation. CASE-SENSITIVE + + If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function. + + This function returns an array with the names of the prerequisite Augmentation(s) for the specified Augmentation. + If there are no prerequisites, a blank array is returned. + + If an invalid Augmentation name is passed in for the *augName* argument, this function will return a blank array. diff --git a/doc/source/netscript/singularityfunctions/getAugmentationsFromFaction.rst b/doc/source/netscript/singularityfunctions/getAugmentationsFromFaction.rst new file mode 100644 index 000000000..f1101b23c --- /dev/null +++ b/doc/source/netscript/singularityfunctions/getAugmentationsFromFaction.rst @@ -0,0 +1,10 @@ +getAugmentationsFromFaction() Netscript Function +================================================ + +.. js:function:: getAugmentationsFromFaction(facName) + + :param string facName: Name of faction. CASE-SENSITIVE + + If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function. + + Returns an array containing the names (as strings) of all Augmentations that are available from the specified faction. diff --git a/doc/source/netscript/singularityfunctions/getCharacterInformation.rst b/doc/source/netscript/singularityfunctions/getCharacterInformation.rst new file mode 100644 index 000000000..ba3ee9696 --- /dev/null +++ b/doc/source/netscript/singularityfunctions/getCharacterInformation.rst @@ -0,0 +1,50 @@ +getCharacterInformation() Netscript Function +============================================ + +.. js:function:: getCharacterInformation() + + If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to run this function. + + Returns an object with various information about your character. The object has the following properties:: + + { + bitnode: Current BitNode number + city: Name of city you are currently in + factions: Array of factions you are currently a member of + hp: Current health points + jobs: Array of all companies at which you have jobs + jobTitle: Array of job positions for all companies you are employed at. Same order as 'jobs' + maxHp: Maximum health points + tor: Boolean indicating whether or not you have a tor router + + // The following is an object with many of the player's multipliers from Augmentations/Source Files + mult: { + agility: Agility stat + agilityExp: Agility exp + companyRep: Company reputation + crimeMoney: Money earned from crimes + crimeSuccess: Crime success chance + defense: Defense stat + defenseExp: Defense exp + dexterity: Dexterity stat + dexterityExp: Dexterity exp + factionRep: Faction reputation + hacking: Hacking stat + hackingExp: Hacking exp + strength: Strength stat + strengthExp: Strength exp + workMoney: Money earned from jobs + }, + + // The following apply only to when the character is performing + // some type of working action, such as working for a company/faction + timeWorked: Timed worked in ms + workHackExpGain: Hacking experience earned so far from work + workStrExpGain: Str experience earned so far from work + workDefExpGain: Def experience earned so far from work + workDexExpGain: Dex experience earned so far from work + workAgiExpGain: Agi experience earned so far from work + workChaExpGain: Cha experience earned so far from work + workRepGain: Reputation earned so far from work, if applicable + workMoneyGain: Money earned so far from work, if applicable + } diff --git a/doc/source/netscript/singularityfunctions/getCompanyFavor.rst b/doc/source/netscript/singularityfunctions/getCompanyFavor.rst new file mode 100644 index 000000000..c303593d4 --- /dev/null +++ b/doc/source/netscript/singularityfunctions/getCompanyFavor.rst @@ -0,0 +1,11 @@ +getCompanyFavor() Netscript Function +==================================== + +.. js:function:: getCompanyFavor(companyName) + + :param string companyName: Name of the company. CASE-SENSITIVE + + If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function. + + This function will return the amount of favor you have at the specified company. + If the company passed in as an argument is invalid, -1 will be returned. diff --git a/doc/source/netscript/singularityfunctions/getCompanyFavorGain.rst b/doc/source/netscript/singularityfunctions/getCompanyFavorGain.rst new file mode 100644 index 000000000..9df9d2d32 --- /dev/null +++ b/doc/source/netscript/singularityfunctions/getCompanyFavorGain.rst @@ -0,0 +1,11 @@ +getCompanyFavorGain() Netscript Function +======================================== + +.. js:function:: getCompanyFavorGain(companyName) + + :param string companyName: Name of the company. CASE-SENSITIVE + + If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function. + + This function will return the amount of favor you will gain for the specified company + when you reset by installing Augmentations. diff --git a/doc/source/netscript/singularityfunctions/getCompanyRep.rst b/doc/source/netscript/singularityfunctions/getCompanyRep.rst new file mode 100644 index 000000000..6a2bc0db0 --- /dev/null +++ b/doc/source/netscript/singularityfunctions/getCompanyRep.rst @@ -0,0 +1,11 @@ +getCompanyRep() Netscript Function +================================== + +.. js:function:: getCompanyRep(companyName) + + :param string companyName: Name of the company. CASE-SENSITIVE + + If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function. + + This function will return the amount of reputation you have at the specified company. + If the company passed in as an argument is invalid, -1 will be returned. diff --git a/doc/source/netscript/singularityfunctions/getCrimeChance.rst b/doc/source/netscript/singularityfunctions/getCrimeChance.rst new file mode 100644 index 000000000..9c8587fc5 --- /dev/null +++ b/doc/source/netscript/singularityfunctions/getCrimeChance.rst @@ -0,0 +1,12 @@ +getCrimeChance() Netscript Function +=================================== + +.. js:function:: getCrimeChance(crime) + + :param string crime: + Name of crime. Not case-sensitive. This argument is fairlyn lenient in terms of what inputs it accepts. + Check the documentation for the *commitCrime()* function for a list of example inputs. + + If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function. + + This function returns your chance of success at commiting the specified crime. The chance is returned as a decimal (i.e. 60% would be returned as 0.6). diff --git a/doc/source/netscript/singularityfunctions/getFactionFavor.rst b/doc/source/netscript/singularityfunctions/getFactionFavor.rst new file mode 100644 index 000000000..d995ac999 --- /dev/null +++ b/doc/source/netscript/singularityfunctions/getFactionFavor.rst @@ -0,0 +1,10 @@ +getFactionFavor() Netscript Function +==================================== + +.. js:function:: getFactionFavor(factionName) + + :param string factionName: Name of faction. CASE-SENSITIVE + + If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function. + + This function returns the amount of favor you have for the specified faction. diff --git a/doc/source/netscript/singularityfunctions/getFactionFavorGain.rst b/doc/source/netscript/singularityfunctions/getFactionFavorGain.rst new file mode 100644 index 000000000..147f0fe52 --- /dev/null +++ b/doc/source/netscript/singularityfunctions/getFactionFavorGain.rst @@ -0,0 +1,10 @@ +getFactionFavorGain() Netscript Function +======================================== + +.. js:function:: getFactionFavorGain(factionName) + + :param string factionName: Name of faction. CASE-SENSITIVE + + If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function. + + This function returns the amount of favor you will gain for the specified faction when you reset by installing Augmentations. diff --git a/doc/source/netscript/singularityfunctions/getFactionRep.rst b/doc/source/netscript/singularityfunctions/getFactionRep.rst new file mode 100644 index 000000000..461b2ce1f --- /dev/null +++ b/doc/source/netscript/singularityfunctions/getFactionRep.rst @@ -0,0 +1,10 @@ +getFactionRep() Netscript Function +================================== + +.. js:function:: getFactionRep(factionName) + + :param string factionName: Name of faction. CASE-SENSITIVE + + If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function. + + This function returns the amount of reputation you have for the specified faction. diff --git a/doc/source/netscript/singularityfunctions/getOwnedAugmentations.rst b/doc/source/netscript/singularityfunctions/getOwnedAugmentations.rst new file mode 100644 index 000000000..52b4f94e9 --- /dev/null +++ b/doc/source/netscript/singularityfunctions/getOwnedAugmentations.rst @@ -0,0 +1,12 @@ +getOwnedAugmentations() Netscript Function +========================================== + +.. js:function:: getOwnedAugmentations(purchased=false) + + :param boolean purchase: + Specifies whether the returned array should include Augmentations you have purchased but not yet installed. + By default, this argument is false which means that the return value will NOT have the purchased Augmentations. + + If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function. + + This function returns an array containing the names (as strings) of all Augmentations you have. diff --git a/doc/source/netscript/singularityfunctions/getOwnedSourceFiles.rst b/doc/source/netscript/singularityfunctions/getOwnedSourceFiles.rst new file mode 100644 index 000000000..04d963092 --- /dev/null +++ b/doc/source/netscript/singularityfunctions/getOwnedSourceFiles.rst @@ -0,0 +1,9 @@ +getOwnedSourceFiles() Netscript Function +======================================== + +.. js:function:: getOwnedSourceFiles() + + If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function. + + Returns an array of source files + [{n: 1, lvl: 3}, {n: 4, lvl: 3}] diff --git a/doc/source/netscript/singularityfunctions/getStats.rst b/doc/source/netscript/singularityfunctions/getStats.rst new file mode 100644 index 000000000..74ad4ae17 --- /dev/null +++ b/doc/source/netscript/singularityfunctions/getStats.rst @@ -0,0 +1,23 @@ +getStats() Netscript Function +============================= + +.. js:function:: getStats() + + If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to run this function. + + Returns an object with the Player's stats. The object has the following properties:: + + { + hacking + strength + defense + dexterity + agility + charisma + intelligence + } + + Example:: + + res = getStats(); + print('My charisma level is: ' + res.charisma); diff --git a/doc/source/netscript/singularityfunctions/getUpgradeHomeRamCost.rst b/doc/source/netscript/singularityfunctions/getUpgradeHomeRamCost.rst new file mode 100644 index 000000000..90c6c61ae --- /dev/null +++ b/doc/source/netscript/singularityfunctions/getUpgradeHomeRamCost.rst @@ -0,0 +1,8 @@ +getUpgradeHomeRamCost() Netscript Function +========================================== + +.. js:function:: getUpgradeHomeRamCost() + + If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function. + + Returns the cost of upgrading the player's home computer RAM. diff --git a/doc/source/netscript/singularityfunctions/gymWorkout.rst b/doc/source/netscript/singularityfunctions/gymWorkout.rst new file mode 100644 index 000000000..32daad2c6 --- /dev/null +++ b/doc/source/netscript/singularityfunctions/gymWorkout.rst @@ -0,0 +1,30 @@ +gymWorkout() Netscript Function +=============================== + +.. js:function:: gymWorkout(gymName, stat) + + :param string gymName: + Name of gym. Not case-sensitive. You must be in the correct city for whatever gym you specify. + + * Crush Fitness Gym + * Snap Fitness Gym + * Iron Gym + * Powerhouse Gym + * Millenium Fitness Gym + :param string stat: + The stat you want to train. Not case-sensitive. + + * strength OR str + * defense OR def + * dexterity OR dex + * agility OR agi + + If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to use this function. + + This function will automatically set you to start working out at a gym to train a particular stat. If you are + already in the middle of some "working" action (such as working at a company, for a faction, or on a program), + then running this function will automatically cancel that action and give you your earnings. + + The cost and experience gains for all of these gyms are the same as if you were to manually visit these gyms and train + + This function will return true if you successfully start working out at the gym, and false otherwise. diff --git a/doc/source/netscript/singularityfunctions/installAugmentations.rst b/doc/source/netscript/singularityfunctions/installAugmentations.rst new file mode 100644 index 000000000..38a862674 --- /dev/null +++ b/doc/source/netscript/singularityfunctions/installAugmentations.rst @@ -0,0 +1,14 @@ +installAugmentations() Netscript Function +========================================= + +.. js:function:: installAugmentations(cbScript) + + :param string cbScript: + Optional callback script. This is a script that will automatically be run after Augmentations are installed (after the reset). + This script will be run with no arguments and 1 thread. It must be located on your home computer. + + If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function. + + This function will automatically install your Augmentations, resetting the game as usual. + + It will return true if successful, and false otherwise. diff --git a/doc/source/netscript/singularityfunctions/isBusy.rst b/doc/source/netscript/singularityfunctions/isBusy.rst new file mode 100644 index 000000000..1bccaa2fe --- /dev/null +++ b/doc/source/netscript/singularityfunctions/isBusy.rst @@ -0,0 +1,9 @@ +isBusy() Netscript Function +=========================== + +.. js:function:: isBusy() + + If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to run this function. + + Returns a boolean indicating whether or not the player is currently performing an 'action'. These actions include + working for a company/faction, studying at a univeristy, working out at a gym, creating a program, or committing a crime. diff --git a/doc/source/netscript/singularityfunctions/joinFaction.rst b/doc/source/netscript/singularityfunctions/joinFaction.rst new file mode 100644 index 000000000..a4f9da010 --- /dev/null +++ b/doc/source/netscript/singularityfunctions/joinFaction.rst @@ -0,0 +1,10 @@ +joinFaction() Netscript Function +================================ + +.. js:function:: joinFaction(name) + + :param string name: Name of faction to join. CASE-SENSITIVE + + If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function. + + This function will automatically accept an invitation from a faction and join it. diff --git a/doc/source/netscript/singularityfunctions/purchaseAugmentation.rst b/doc/source/netscript/singularityfunctions/purchaseAugmentation.rst new file mode 100644 index 000000000..28a5dd542 --- /dev/null +++ b/doc/source/netscript/singularityfunctions/purchaseAugmentation.rst @@ -0,0 +1,14 @@ +purchaseAugmentation() Netscript Function +========================================= + +.. js:function:: purchaseAugmentation(factionName, augName) + + :param string factionName: Name of faction to purchase Augmentation from. CASE-SENSITIVE + :param string augName: Name of Augmentation to purchase. CASE-SENSITIVE + + + If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function. + + This function will try to purchase the specified Augmentation through the given Faction. + + This function will return true if the Augmentation is successfully purchased, and false otherwise. diff --git a/doc/source/netscript/singularityfunctions/purchaseProgram.rst b/doc/source/netscript/singularityfunctions/purchaseProgram.rst new file mode 100644 index 000000000..c60ad4bd2 --- /dev/null +++ b/doc/source/netscript/singularityfunctions/purchaseProgram.rst @@ -0,0 +1,18 @@ +purchaseProgram() Netscript Function +==================================== + +.. js:function:: purchaseProgram(programName) + + :param string programName: Name of program to purchase. Must include '.exe' extension. Not case-sensitive. + + If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to use this function. + + This function allows you to automatically purchase programs. You MUST have a TOR router in order to use this function. + The cost of purchasing programs using this function is the same as if you were purchasing them through the Dark Web using the + Terminal *buy* command. + + Example:: + + purchaseProgram("brutessh.exe"); + + This function will return true if the specified program is purchased, and false otherwise. diff --git a/doc/source/netscript/singularityfunctions/purchaseTor.rst b/doc/source/netscript/singularityfunctions/purchaseTor.rst new file mode 100644 index 000000000..c9a488ef6 --- /dev/null +++ b/doc/source/netscript/singularityfunctions/purchaseTor.rst @@ -0,0 +1,11 @@ +purchaseTor() Netscript Function +================================ + +.. js:function:: purchaseTor() + + If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to use this function. + + This function allows you to automatically purchase a TOR router. The cost for purchasing a TOR router using this + function is the same as if you were to manually purchase one. + + This function will return true if it successfully purchase a TOR router and false otherwise. diff --git a/doc/source/netscript/singularityfunctions/stopAction.rst b/doc/source/netscript/singularityfunctions/stopAction.rst new file mode 100644 index 000000000..3406c7176 --- /dev/null +++ b/doc/source/netscript/singularityfunctions/stopAction.rst @@ -0,0 +1,18 @@ +stopAction() Netscript Function +=============================== + +.. js:function:: stopAction() + + If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to run this function. + This function is used to end whatever 'action' the player is currently performing. The player + will receive whatever money/experience/etc. he has earned from that action. + + The actions that can be stopped with this function are: + + * Studying at a university + * Working for a company/faction + * Creating a program + * Committing a Crime + + This function will return true if the player's action was ended. It will return false if the player was not + performing an action when this function was called. diff --git a/doc/source/netscript/singularityfunctions/travelToCity.rst b/doc/source/netscript/singularityfunctions/travelToCity.rst new file mode 100644 index 000000000..a8c798016 --- /dev/null +++ b/doc/source/netscript/singularityfunctions/travelToCity.rst @@ -0,0 +1,20 @@ +travelToCity() Netscript Function +================================= + +.. js:function:: travelToCity(cityName) + + :param string cityName: + City to travel to. CASE-SENSITIVE. + + * Aevum + * Chongqing + * Sector-12 + * New Tokyo + * Ishima + * Volhaven + + If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to use this function. + + This function allows the player to travel to any city. The cost for using this function is the same as the cost for traveling through the Travel Agency. + + This function will return true if you successfully travel to the specified city and false otherwise. diff --git a/doc/source/netscript/singularityfunctions/universityCourse.rst b/doc/source/netscript/singularityfunctions/universityCourse.rst new file mode 100644 index 000000000..7d273fe65 --- /dev/null +++ b/doc/source/netscript/singularityfunctions/universityCourse.rst @@ -0,0 +1,30 @@ +universityCourse() Netscript Function +===================================== + +.. js:function:: universityCourse(universityName, courseName) + + :param string universityName: + Name of university. Not case-sensitive. You must be in the correct city for whatever university you specify. + + * Summit University + * Rothman University + * ZB Institute Of Technology + :param string courseName: + Name of course. Not case-sensitive. + + * Study Computer Science + * Data Strucures + * Networks + * Algorithms + * Management + * Leadership + + If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to use this function. + + This function will automatically set you to start taking a course at a university. If you are already in the middle of some + "working" action (such as working at a company, for a faction, or on a program), then running this function will automatically + cancel that action and give you your earnings. + + The cost and experience gains for all of these universities and classes are the same as if you were to manually visit and take these classes. + + This function will return true if you successfully start taking the course, and false otherwise. diff --git a/doc/source/netscript/singularityfunctions/upgradeHomeRam.rst b/doc/source/netscript/singularityfunctions/upgradeHomeRam.rst new file mode 100644 index 000000000..c3a7f7da2 --- /dev/null +++ b/doc/source/netscript/singularityfunctions/upgradeHomeRam.rst @@ -0,0 +1,10 @@ +upgradeHomeRam() Netscript Function +=================================== + +.. js:function:: upgradeHomeRam() + + If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function. + + This function will upgrade amount of RAM on the player's home computer. The cost is the same as if you were to do it manually. + + This function will return true if the player's home computer RAM is successfully upgraded, and false otherwise. diff --git a/doc/source/netscript/singularityfunctions/workForCompany.rst b/doc/source/netscript/singularityfunctions/workForCompany.rst new file mode 100644 index 000000000..fde4d11d7 --- /dev/null +++ b/doc/source/netscript/singularityfunctions/workForCompany.rst @@ -0,0 +1,24 @@ +workForCompany() Netscript Function +=================================== + +.. js:function:: workForCompany() + + If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function. + + This function will automatically set you to start working at the company at which you are employed. + If you are already in the middle of some "working" action (such as working for a faction, training at + a gym, or creating a program), then running this function will automatically cancel that action and give you your earnings. + + This function will return true if the player starts working, and false otherwise. + + Note that when you are working for a company, you will not actually receive your earnings + (reputation, money, experience) until you FINISH the action. This can be an issue if, for example, + you only want to work until you get 100,000 company reputation. One small hack to get around this is to + continuously restart the action to receive your earnings:: + + while (getCompanyRep(COMPANY HERE) < VALUE) { + workForCompany(); + sleep(60000); + } + + This way, your company reputation will be updated every minute. diff --git a/doc/source/netscript/singularityfunctions/workForFaction.rst b/doc/source/netscript/singularityfunctions/workForFaction.rst new file mode 100644 index 000000000..e544a78da --- /dev/null +++ b/doc/source/netscript/singularityfunctions/workForFaction.rst @@ -0,0 +1,32 @@ +workForFaction() Netscript Function +=================================== + +.. js:function:: workForFaction(factionName, workType) + + :param string factionName: Name of faction to work for. CASE-SENSITIVE + :param string workType: + Type of work to perform for the faction + + * hacking/hacking contracts/hackingcontracts + * field/fieldwork/field work + * security/securitywork/security work + + If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function. + + This function will automatically set you to start working for the specified faction. + Obviously, you must be a member of the faction or else this function will fail. If you are already in + the middle of some "working" action (such as working for a company, training at a gym, or creating a program), + then running this function will automatically cancel that action and give you your earnings. + + This function will return true if you successfully start working for the specified faction, and false otherwise. + + Note that when you are working for a faction, you will not actually receive your earnings (reputation, experience) + until you FINISH the action. This can be an issue if, for example, you only want to work until you get 100,000 faction + reputation. One small hack to get around this is to continuously restart the action to receive your earnings:: + + while (getFactionRep(FACTION NAME) < VALUE) { + workForFaction(FACNAME, WORKTYPE); + sleep(60000); + } + + This way, your faction reputation will be updated every minute. diff --git a/doc/source/netscript/tixapi/buyStock.rst b/doc/source/netscript/tixapi/buyStock.rst new file mode 100644 index 000000000..06e70c891 --- /dev/null +++ b/doc/source/netscript/tixapi/buyStock.rst @@ -0,0 +1,16 @@ +buyStock() Netscript Function +============================= + +.. js:function:: buyStock(sym, shares) + + :param string sym: Symbol of stock to purchase + :param number shares: Number of shares to purchased. Must be positive. Will be rounded to nearest integer + :RAM cost: 2.5 GB + + Attempts to purchase shares of a stock using a `Market Order `_. + + If the player does not have enough money to purchase the specified number of shares, then no shares will be purchased. Remember + that every transaction on the stock exchange costs a certain commission fee. + + If this function successfully purchases the shares, it will return the stock price at which each share was purchased. Otherwise, + it will return 0. diff --git a/doc/source/netscript/tixapi/cancelOrder.rst b/doc/source/netscript/tixapi/cancelOrder.rst new file mode 100644 index 000000000..da9cb18c0 --- /dev/null +++ b/doc/source/netscript/tixapi/cancelOrder.rst @@ -0,0 +1,24 @@ +cancelOrder() Netscript Function +================================ + +.. js:function:: cancelOrder(sym, shares, price, type, pos) + + :param string sym: Symbol of stock to player order for + :param number shares: Number of shares for order. Must be positive. Will be rounded to nearest integer + :param number price: Execution price for the order + :param string type: Type of order. It must specify "limit" or "stop", and must also specify "buy" or "sell". This is NOT + case-sensitive. Here are four examples that will work: + + * limitbuy + * limitsell + * stopbuy + * stopsell + + :param string pos: + Specifies whether the order is a "Long" or "Short" position. The Values "L" or "S" can also be used. This is + NOT case-sensitive. + :RAM cost: 2.5 GB + + Cancels an oustanding Limit or Stop order on the stock market. + + The ability to use limit and stop orders is **not** immediately available to the player and must be unlocked later on in the game. diff --git a/doc/source/netscript/tixapi/getOrders.rst b/doc/source/netscript/tixapi/getOrders.rst new file mode 100644 index 000000000..2cd22dff5 --- /dev/null +++ b/doc/source/netscript/tixapi/getOrders.rst @@ -0,0 +1,68 @@ +getOrders() Netscript Function +============================== + +.. js:function:: getOrders() + + :RAM cost: 2.5 GB + + Returns your order book for the stock market. This is an object containing information + for all the Limit and Stop Orders you have in the stock market. + + The object has the following structure:: + + { + StockSymbol1: [ // Array of orders for this stock + { + shares: Order quantity + price: Order price + type: Order type + position: Either "L" or "S" for Long or Short position + }, + { + ... + }, + ... + ], + StockSymbol2: [ // Array of orders for this stock + ... + ], + ... + } + + The "Order type" property can have one of the following four values: + + * "Limit Buy Order" + * "Limit Sell Order" + * "Stop Buy Order" + * "Stop Sell Order" + + **Note that the order book will only contain information for stocks that you actually + have orders in**. For example, if you do not have orders in Nova Medical (NVMD), then the returned + object will not have a "NVMD" property. + + Example:: + + { + ECP: [ + { + shares: 5, + price: 100,000 + type: "Stop Buy Order", + position: "S", + }, + { + shares: 25, + price: 125,000 + type: "Limit Sell Order", + position: "L", + }, + ], + SYSC: [ + { + shares: 100, + price: 10,000 + type: "Limit Buy Order", + position: "L", + }, + ], + } diff --git a/doc/source/netscript/tixapi/getStockForecast.rst b/doc/source/netscript/tixapi/getStockForecast.rst new file mode 100644 index 000000000..7ce63f319 --- /dev/null +++ b/doc/source/netscript/tixapi/getStockForecast.rst @@ -0,0 +1,21 @@ +getStockForecast() Netscript Function +===================================== + +.. js:function:: getStockForecast(sym) + + :param string sym: Symbol of stock + :RAM cost: 2.5 GB + + Returns the probability that the specified stock's price will increase + (as opposed to decrease) during the next tick. + + The probability is returned as a decimal value, NOT a percentage (e.g. if a + stock has a 60% chance of increasing, then this function will return 0.6, + NOT 60). + + In other words, if this function returned 0.30 for a stock, then this means + that the stock's price has a 30% chance of increasing and a 70% chance of + decreasing during the next tick. + + In order to use this function, you must first purchase access to the Four Sigma (4S) + Market Data TIX API. diff --git a/doc/source/netscript/tixapi/getStockMaxShares.rst b/doc/source/netscript/tixapi/getStockMaxShares.rst new file mode 100644 index 000000000..4c1838183 --- /dev/null +++ b/doc/source/netscript/tixapi/getStockMaxShares.rst @@ -0,0 +1,11 @@ +getStockMaxShares() Netscript Function +====================================== + +.. js:function:: getStockMaxShares(sym) + + :param string sym: Stock symbol + :RAM cost: 2 GB + + Returns the maximum number of shares that the stock has. This is the maximum + amount of the stock that can be purchased in both the Long and Short + positions combined diff --git a/doc/source/netscript/tixapi/getStockPosition.rst b/doc/source/netscript/tixapi/getStockPosition.rst new file mode 100644 index 000000000..048a3bfb3 --- /dev/null +++ b/doc/source/netscript/tixapi/getStockPosition.rst @@ -0,0 +1,27 @@ +getStockPosition() Netscript Function +===================================== + +.. js:function:: getStockPosition(sym) + + :param string sym: Stock symbol + :RAM cost: 2 GB + + Returns an array of four elements that represents the player's position in a stock. + + The first element is the returned array is the number of shares the player owns of the stock in the + `Long position `_. The second + element in the array is the average price of the player's shares in the Long position. + + The third element in the array is the number of shares the player owns of the stock in the + `Short position `_. The fourth + element in the array is the average price of the player's Short position. + + All elements in the returned array are numeric. + + Example:: + + pos = getStockPosition("ECP"); + shares = pos[0]; + avgPx = pos[1]; + sharesShort = pos[2]; + avgPxShort = pos[3]; diff --git a/doc/source/netscript/tixapi/getStockPrice.rst b/doc/source/netscript/tixapi/getStockPrice.rst new file mode 100644 index 000000000..ae88e644f --- /dev/null +++ b/doc/source/netscript/tixapi/getStockPrice.rst @@ -0,0 +1,14 @@ +getStockPrice() Netscript Function +================================== + +.. js:function:: getStockPrice(sym) + + :param string sym: Stock symbol + :RAM cost: 2 GB + + Returns the price of a stock, given its symbol (NOT the company name). The symbol is a sequence + of two to four capital letters. + + Example:: + + getStockPrice("FISG"); diff --git a/doc/source/netscript/tixapi/getStockSymbols.rst b/doc/source/netscript/tixapi/getStockSymbols.rst new file mode 100644 index 000000000..17714156f --- /dev/null +++ b/doc/source/netscript/tixapi/getStockSymbols.rst @@ -0,0 +1,8 @@ +getStockSymbols() Netscript Function() +====================================== + +.. js:function:: getStockSymbols() + + :RAM cost: 2 GB + + Returns an array of the symbols of the tradable stocks diff --git a/doc/source/netscript/tixapi/getStockVolatility.rst b/doc/source/netscript/tixapi/getStockVolatility.rst new file mode 100644 index 000000000..0cc5fccb6 --- /dev/null +++ b/doc/source/netscript/tixapi/getStockVolatility.rst @@ -0,0 +1,17 @@ +getStockVolatility() Netscript Function +======================================= + +.. js:function:: getStockVolatility(sym) + + :param string sym: Symbol of stock + :RAM cost: 2.5 GB + + Returns the volatility of the specified stock. + + Volatility represents the maximum percentage by which a stock's price can + change every tick. The volatility is returned as a decimal value, NOT + a percentage (e.g. if a stock has a volatility of 3%, then this function will + return 0.03, NOT 3). + + In order to use this function, you must first purchase access to the Four Sigma (4S) + Market Data TIX API. diff --git a/doc/source/netscript/tixapi/placeOrder.rst b/doc/source/netscript/tixapi/placeOrder.rst new file mode 100644 index 000000000..8e8de3dda --- /dev/null +++ b/doc/source/netscript/tixapi/placeOrder.rst @@ -0,0 +1,26 @@ +placeOrder() Netscript Function +=============================== + +.. js:function:: placeOrder(sym, shares, price, type, pos) + + :param string sym: Symbol of stock to player order for + :param number shares: Number of shares for order. Must be positive. Will be rounded to nearest integer + :param number price: Execution price for the order + :param string type: Type of order. It must specify "limit" or "stop", and must also specify "buy" or "sell". This is NOT + case-sensitive. Here are four examples that will work: + + * limitbuy + * limitsell + * stopbuy + * stopsell + + :param string pos: + Specifies whether the order is a "Long" or "Short" position. The Values "L" or "S" can also be used. This is + NOT case-sensitive. + :RAM cost: 2.5 GB + + Places an order on the stock market. This function only works for `Limit and Stop Orders `_. + + The ability to place limit and stop orders is **not** immediately available to the player and must be unlocked later on in the game. + + Returns true if the order is successfully placed, and false otherwise. diff --git a/doc/source/netscript/tixapi/purchase4SMarketData.rst b/doc/source/netscript/tixapi/purchase4SMarketData.rst new file mode 100644 index 000000000..841cb4517 --- /dev/null +++ b/doc/source/netscript/tixapi/purchase4SMarketData.rst @@ -0,0 +1,11 @@ +purchase4SMarketData() Netscript Function +========================================= + +.. js:function:: purchase4SMarketData() + + :RAM cost: 2.5 GB + + Purchase 4S Market Data Access. + + Returns true if you successfully purchased it or if you already have access. + Returns false otherwise. diff --git a/doc/source/netscript/tixapi/purchase4SMarketDataTixApi.rst b/doc/source/netscript/tixapi/purchase4SMarketDataTixApi.rst new file mode 100644 index 000000000..119988f05 --- /dev/null +++ b/doc/source/netscript/tixapi/purchase4SMarketDataTixApi.rst @@ -0,0 +1,11 @@ +purchase4SMarketDataTixApi() Netscript Function +=============================================== + +.. js:function:: purchase4SMarketDataTixApi() + + :RAM cost: 2.5 GB + + Purchase 4S Market Data TIX API Access. + + Returns true if you successfully purchased it or if you already have access. + Returns false otherwise. diff --git a/doc/source/netscript/tixapi/sellShort.rst b/doc/source/netscript/tixapi/sellShort.rst new file mode 100644 index 000000000..2d8291fa5 --- /dev/null +++ b/doc/source/netscript/tixapi/sellShort.rst @@ -0,0 +1,18 @@ +sellShort() Netscript Function +============================== + +.. js:function:: sellShort(sym, shares) + + :param string sym: Symbol of stock to sell + :param number shares: Number of shares to sell. Must be positive. Will be rounded to nearest integer + :RAM cost: 2.5 GB + + Attempts to sell a `short `_ position of a stock + using a `Market Order `_. + + The ability to short a stock is **not** immediately available to the player and must be unlocked later on in the game. + + If the specified number of shares exceeds the amount that the player actually owns, then this function will sell all owned + shares. Remember that every transaction on the stock exchange costs a certain commission fee. + + If the sale is successful, this function will return the stock price at which each share was sold. Otherwise it will return 0. diff --git a/doc/source/netscript/tixapi/sellStock.rst b/doc/source/netscript/tixapi/sellStock.rst new file mode 100644 index 000000000..7c5e66723 --- /dev/null +++ b/doc/source/netscript/tixapi/sellStock.rst @@ -0,0 +1,20 @@ +sellStock() Netscript Function +============================== + +.. js:function:: sellStock(sym, shares) + + :param string sym: Symbol of stock to sell + :param number shares: Number of shares to sell. Must be positive. Will be rounded to nearest integer + :RAM cost: 2.5 GB + + Attempts to sell shares of a stock using a `Market Order `_. + + If the specified number of shares in the function exceeds the amount that the player actually owns, then this function will + sell all owned shares. Remember that every transaction on the stock exchange costs a certain commission fee. + + The net profit made from selling stocks with this function is reflected in the script's statistics. + This net profit is calculated as:: + + shares * (sell price - average price of purchased shares) + + If the sale is successful, this function will return the stock price at which each share was sold. Otherwise, it will return 0. diff --git a/doc/source/netscript/tixapi/shortStock.rst b/doc/source/netscript/tixapi/shortStock.rst new file mode 100644 index 000000000..cd319cf88 --- /dev/null +++ b/doc/source/netscript/tixapi/shortStock.rst @@ -0,0 +1,18 @@ +shortStock() Netscript Function +=============================== + +.. js:function:: shortStock(sym, shares) + + :param string sym: Symbol of stock to short + :param number shares: Number of shares to short. Must be positive. Will be rounded to nearest integer + :RAM cost: 2.5 GB + + Attempts to purchase a `short `_ position of a stock + using a `Market Order `_. + + The ability to short a stock is **not** immediately available to the player and must be unlocked later on in the game. + + If the player does not have enough money to purchase the specified number of shares, then no shares will be purchased. + Remember that every transaction on the stock exchange costs a certain commission fee. + + If the purchase is successful, this function will return the stock price at which each share was purchased. Otherwise, it will return 0. diff --git a/src/Constants.ts b/src/Constants.ts index eb36b0b1b..ee2dca54f 100644 --- a/src/Constants.ts +++ b/src/Constants.ts @@ -279,235 +279,6 @@ export let CONSTANTS: IMap = { // BitNode/Source-File related stuff TotalNumBitNodes: 24, - /* Tutorial related things */ - TutorialNetworkingText: "Servers are a central part of the game. You start with a single personal server (your home computer) " + - "and you can purchase additional servers as you progress through the game. Connecting to other servers " + - "and hacking them can be a major source of income and experience. Servers can also be used to run " + - "scripts which can automatically hack servers for you.

" + - "In order to navigate between machines, use the 'scan' or 'scan-analyze' Terminal command to see all servers " + - "that are reachable from your current server. Then, you can use the 'connect [hostname/ip]' " + - "command to connect to one of the available machines.

" + - "The 'hostname' and 'ifconfig' commands can be used to display the hostname/IP of the " + - "server you are currently connected to.", - - TutorialHackingText: "In the year 2077, currency has become digital and decentralized. People and corporations " + - "store their money on servers. By hacking these servers, you can steal their money and gain " + - "experience.

" + - "

Gaining root access


" + - "The key to hacking a server is to gain root access to that server. This can be done using " + - "the NUKE virus (NUKE.exe). You start the game with a copy of the NUKE virus on your home " + - "computer. The NUKE virus attacks the target server's open ports using buffer overflow " + - "exploits. When successful, you are granted root administrative access to the machine.

" + - "Typically, in order for the NUKE virus to succeed, the target server needs to have at least " + - "one of its ports opened. Some servers have no security and will not need any ports opened. Some " + - "will have very high security and will need many ports opened. In order to open ports on another " + - "server, you will need to run programs that attack the server to open specific ports. These programs " + - "can be coded once your hacking skill gets high enough, or they can be purchased if you can find " + - "a seller.

" + - "In order to determine how many ports need to be opened to successfully NUKE a server, connect to " + - "that server and run the 'analyze' command. This will also show you which ports have already been " + - "opened.

" + - "Once you have enough ports opened and have ran the NUKE virus to gain root access, the server " + - "can then be hacked by simply calling the 'hack' command through terminal, or by using a script.

" + - "

Hacking mechanics


" + - "When you execute the hack command, either manually through the terminal or automatically through " + - "a script, you attempt to hack the server. This action takes time. The more advanced a server's " + - "security is, the more time it will take. Your hacking skill level also affects the hacking time, " + - "with a higher hacking skill leading to shorter hacking times. Also, running the hack command " + - "manually through terminal is faster than hacking from a script.

" + - "Your attempt to hack a server will not always succeed. The chance you have to successfully hack a " + - "server is also determined by the server's security and your hacking skill level. Even if your " + - "hacking attempt is unsuccessful, you will still gain experience points.

" + - "When you successfully hack a server. You steal a certain percentage of that server's total money. This " + - "percentage is determined by the server's security and your hacking skill 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 (since you are only hacking a certain percentage). You can " + - "increase the amount of money on a server using a script and the grow() function in Netscript.

" + - "

Server Security


" + - "Each server has a security level, typically between 1 and 100. A higher number means the server has stronger security. " + - "It is possible for a server to have a security level of 100 or higher, in which case hacking that server " + - "will become impossible (0% chance to hack).

" + - "As mentioned above, a server's security level is an important factor " + - "to consider when hacking. You can check a server's security level using the 'analyze' command, although this " + - "only gives an estimate (with 5% uncertainty). You can also check a server's security in a script, using the " + - "getServerSecurityLevel(server) function in Netscript. See the Netscript documentation for more details. " + - "This function will give you an exact value for a server's security.

" + - "Whenever a server is hacked manually or through a script, its security level increases by a small amount. Calling " + - "the grow() command in a script will also increase security level of the target server. These actions will " + - "make it harder for you to hack the server, and decrease the amount of money you can steal. You can lower a " + - "server's security level in a script using the weaken(server) function in Netscript. See the Netscript " + - "documentation for more details.

" + - "A server has a minimum security level that is equal to one third of its starting security, rounded to the " + - "nearest integer. To be more precise:

" + - "server.minSecurityLevel = Math.max(1, Math.round(server.startingSecurityLevel / 3))

" + - "This means that a server's security will not fall below this value if you are trying to weaken it.", - - TutorialScriptsText: "Scripts can be used to automate the hacking process. Scripts must be written in the Netscript language. " + - "Documentation about the Netscript language can be found in the 'Netscript Programming Language' " + - "section of this 'Tutorial' page.

" + - "It is highly recommended that you have a basic background in programming to start writing scripts. " + - "You by no means need to be an expert. All you need is some familiarity with basic programming " + - "constructs like for/while loops, if statements, " + - "functions, variables, etc. The Netscript programming language most resembles the Javascript language. " + - "Therefore, a good beginner's programming tutorial to read might be " + - "this one. Note that while the Netscript language is similar to Javascript, it is not the exact same, so the " + - "syntax will vary a little bit.

" + - "Running a script requires RAM. The more complex a script is, the more RAM " + - "it requires to run. Scripts can be run on any server you have root access to.

" + - "Here are some Terminal commands that are useful when working with scripts:

" + - "check [script] [args...]
Prints the logs of the script specified by the name and arguments to Terminal. Arguments should be separated " + - "by a space. Note that scripts are uniquely " + - "identified by their arguments as well as their name. For example, if you ran a script 'foo.script' with the argument 'foodnstuff' then in order to 'check' it you must " + - "also add the 'foodnstuff' argument to the check command as so:
check foo.script foodnstuff

" + - "free
Shows the current server's RAM usage and availability

" + - "kill [script] [args...]
Stops a script that is running with the specified script name and arguments. " + - "Arguments should be separated by a space. Note that " + - "scripts are uniquely identified by their arguments as well as their name. For example, if you ran a script 'foo.script' with the " + - "argument 1 and 2, then just typing 'kill foo.script' will not work. You have to use 'kill foo.script 1 2'.

" + - "mem [script] [-t] [n]
Check how much RAM a script requires to run with n threads

" + - "nano [script]
Create/Edit a script. The name of the script must end with the '.script' extension

" + - "ps
Displays all scripts that are actively running on the current server

" + - "rm [script]
Delete a script

" + - "run [script] [-t] [n] [args...]
Run a script with n threads and the specified arguments. Each argument should be separated by a space. " + - "Both the arguments and thread specification are optional. If neither are specified, then the script will be run single-threaded with no arguments.
" + - "Examples:
run foo.script
The command above will run 'foo.script' single-threaded with no arguments." + - "
run foo.script -t 10
The command above will run 'foo.script' with 10 threads and no arguments." + - "
run foo.script foodnstuff sigma-cosmetics 10
The command above will run 'foo.script' single-threaded with three arguments: [foodnstuff, sigma-cosmetics, 10]" + - "
run foo.script -t 50 foodnstuff
The command above will run 'foo.script' with 50 threads and a single argument: [foodnstuff]

" + - "tail [script] [args...]
Displays the logs of the script specified by the name and arguments. Note that scripts are uniquely " + - "identified by their arguments as well as their name. For example, if you ran a script 'foo.script' with the argument 'foodnstuff' then in order to 'tail' it you must " + - "also add the 'foodnstuff' argument to the tail command as so:
tail foo.script foodnstuff

" + - "top
Displays all active scripts and their RAM usage

" + - "

Multithreading scripts


" + - "Scripts can be multithreaded. A multithreaded script runs the script's code once in each thread. The result is that " + - "every call to the hack(), grow(), and weaken() Netscript functions will have its effect multiplied by the number of threads. " + - "For example, if a normal single-threaded script is able to hack $10,000, then running the same script with 5 threads would " + - "yield $50,000.

" + - "When multithreading a script, the total RAM cost can be calculated by simply multiplying the base RAM cost of the script " + - "with the number of threads, where the base cost refers to the amount of RAM required to run the script single-threaded. " + - "In the terminal, you can run the " + - "'mem [scriptname] -t n' command to see how much RAM a script requires with n threads.

" + - "Every method for running a script has an option for making it multihreaded. To run a script with " + - "n threads from a Terminal:
" + - "run [scriptname] -t n

" + - "Using Netscript commands:
" + - "run('scriptname.script', n);
" + - "exec('scriptname.script, 'targetServer', n);

" + - "

Notes about how scripts work offline


" + - " The scripts that you write and execute are interpreted in Javascript. For this " + - "reason, it is not possible for these scripts to run while offline (when the game is closed). " + - "It is important to note that for this reason, conditionals such as if/else statements and certain " + - "commands such as purchaseHacknetNode() or nuke() will not work while the game is offline.

" + - "However, Scripts WILL continue to generate money and hacking exp for you while the game is offline. This " + - "offline production is based off of the scripts' production while the game is online.

" + - "grow() and weaken() are two Netscript commands that will also be applied when the game is offline, although at a slower rate " + - "compared to if the game was open. This is done by having each script keep track of the " + - "rate at which the grow() and weaken() commands are called when the game is online. These calculated rates are used to determine how many times " + - "these function calls would be made while the game is offline.

" + - "Also, note that because of the way the Netscript interpreter is implemented, " + - "whenever you reload or re-open the game all of the scripts that you are running will " + - "start running from the BEGINNING of the code. The game does not keep track of where exactly " + - "the execution of a script is when it saves/loads.


", - TutorialNetscriptText: "Netscript is a programming language implemented for this game. There are two versions of Netscript: " + - "Netscript 1.0 and Netscript 2.0 (NetscriptJS).

" + - "Click here for Bitburner's official Netscript documentation", - TutorialTravelingText:"There are six major cities in the world that you are able to travel to:

" + - " Aevum
" + - " Chongqing
" + - " Sector-12
" + - " New Tokyo
" + - " Ishima
" + - " Volhaven

" + - "To travel between cities, visit your current city's travel agency through the 'World' page. " + - "From the travel agency you can travel to any other city. Doing so costs money.

" + - "Each city has its own set of companies and unique locations. Also, certain content is only available to you " + - "if you are in certain cities, so get exploring!", - TutorialCompaniesText: "Hacking is not the only way to gain money and experience! Located around the world are many " + - "different companies which you can work for. By working for a company you can earn money, " + - "train your various labor skills, and unlock powerful passive perks.

" + - "To apply for a job, visit the company you want to work for through the 'World' menu. The company " + - "page will have options that let you apply to positions in the company. There might be several different " + - "positions you can apply for, ranging from software engineer to business analyst to security officer.

" + - "When you apply for a job, you will get the offer if your stats are high enough. Your first position at " + - "a company will be an entry-level position such as 'intern'. Once you get the job, an button will appear on " + - "the company page that allows you to work for the company. Click this button to start working.

" + - "Working occurs in 8 hour shifts. Once you start working, you will begin earning money, experience, " + - "and reputation. The rate at which you money and experience depends on the company and your position. " + - "The amount of reputation you gain for your company is based on your job performance, which is affected by " + - "your stats. Different positions value different stats. When you are working, you are unable to perform any " + - "other actions such as using your terminal or visiting other locations (However, note that any scripts you have " + - "running on servers will continue to run as you work!). It is possible to cancel your work shift before the " + - "8 hours is up. However, if you have a full-time job, then cancelling a shift early will result in you gaining " + - "only half of the reputation " + - "that you had earned up to that point. There are also part-time/consultant jobs available where you will not " + - " be penalized if you cancel a work shift early. However, these positions pay less than full-time positions.

" + - "As you continue to work at a company, you will gain more and more reputation at that company. When your stats " + - "and reputation are high enough, you can get a promotion. You can apply for a promotion on the company page, just like " + - "you applied for the job originally. Higher positions at a company provide better salaries and stat gains.

" + - "

Infiltrating Companies


" + - "Many companies have facilities that you can attempt to infiltrate. By infiltrating, you can steal classified company secrets " + - "and then sell these for money or for faction reputation. To try and infiltrate a company, visit a company through the " + - "'World' menu. There will be an option that says 'Infiltrate Company'.

" + - "When infiltrating a company, you must progress through clearance levels in the facility. Every clearance level " + - "has some form of security that you must get past. There are several forms of security, ranging from high-tech security systems to " + - "armed guards. For each form of security, there are a variety of options that you can choose to try and bypass the security. Examples " + - "include hacking the security, engaging in combat, assassination, or sneaking past the security. The chance to succeed for each option " + - "is determined in part by your stats. So, for example, trying to hack the security system relies on your hacking skill, whereas trying to " + - "sneak past the security relies on your agility level.

" + - "The facility has a 'security level' that affects your chance of success when trying to get past a clearance level. " + - "Every time you advance to the next clearance level, the facility's security level will increase by a fixed amount. Furthermore " + - "the options you choose and whether you succeed or fail will affect the security level as well. For example, " + - "if you try to kill a security guard and fail, the security level will increase by a lot. If you choose to sneak past " + - "security and succeed, the security level will not increase at all.

" + - "Every 5 clearance levels, you will steal classified company secrets that can be sold for money or faction reputation. However, " + - "in order to sell these secrets you must successfully escape the facility using the 'Escape' option. Furthermore, companies have " + - "a max clearance level. If you reach the max clearance level you will automatically escape the facility with all of your " + - "stolen secrets.

", - TutorialFactionsText: "Throughout the game you may receive invitations from factions. There are many different factions, and each faction " + - "has different criteria for determining its potential members. Joining a faction and furthering its cause is crucial " + - "to progressing in the game and unlocking endgame content.

" + - "It is possible to join multiple factions if you receive invitations from them. However, note that joining a faction " + - "may prevent you from joining other rival factions.

" + - "The 'Factions' link on the menu brings up a list of all factions that you have joined. " + - "You can select a Faction on this list to go to that Faction page. This page displays general " + - "information about the Faction and also lets you perform work for the faction. " + - "Working for a Faction is similar to working for a company except that you don't get paid a salary. " + - "You will only earn reputation in your Faction and train your stats. Also, cancelling work early " + - "when working for a Faction does NOT result in reduced experience/reputation earnings.

" + - "Earning reputation for a Faction unlocks powerful Augmentations. Purchasing and installing these Augmentations will " + - "upgrade your abilities. The Augmentations that are available to unlock vary from faction to faction.", - TutorialAugmentationsText: "Advances in science and medicine have lead to powerful new technologies that allow people to augment themselves " + - "beyond normal human capabilities. There are many different types of Augmentations, ranging from cybernetic to " + - "genetic to biological. Acquiring these Augmentations enhances the user's physical and mental faculties.

" + - "Because of how powerful these Augmentations are, the technology behind them is kept private and secret by the " + - "corporations and organizations that create them. Therefore, the only way for the player to obtain Augmentations is " + - "through Factions. After joining a Faction and earning enough reputation in it, you will be able to purchase " + - "its Augmentations. Different Factions offer different Augmentations. Augmentations must be purchased in order to be installed, " + - "and they are fairly expensive.

" + - "When you purchase an Augmentation, the price of purchasing another Augmentation increases by 90%. This multiplier stacks for " + - "each Augmentation you purchase. You will not gain the benefits of your purchased Augmentations until you install them. You can " + - "choose to install Augmentations through the 'Augmentations' menu tab. Once you install your purchased Augmentations, " + - "their costs are reset back to the original price.

" + - "Unfortunately, installing Augmentations has side effects. You will lose most of the progress you've made, including your " + - "skills, stats, and money. You will have to start over, but you will have all of the Augmentations you have installed to " + - "help you progress.

" + - "To summarize, here is a list of everything you will LOSE when you install an Augmentation:

" + - "Stats/Skills
" + - "Money
" + - "Scripts on all servers EXCEPT your home computer
" + - "Purchased servers
" + - "Hacknet Nodes
" + - "Company/faction reputation
" + - "Jobs and Faction memberships
" + - "Programs
" + - "Stocks
" + - "TOR router

" + - "Here is everything you will KEEP when you install an Augmentation:

" + - "Every Augmentation you have installed
" + - "Scripts on your home computer
" + - "RAM and CPU Core Upgrades on your home computer
" + - "World Stock Exchange account and TIX API Access
", - LatestUpdate: ` v0.44.1 @@ -516,6 +287,8 @@ export let CONSTANTS: IMap = { ** Sleeves are now assigned to Shock Recovery task by default ** Shock Recovery and Synchronize tasks are now twice as effective + * Changed documentation so that Netscript functions are own their own pages. Sorry if this is annoying, it was necessary for properly cross-referencing + * Officially deprecated the Wiki (the fandom site). Use the 'readthedocs' Documentation instead * Bug Fix: 'rm' Terminal and Netscript commands now work on non-program files that have '.exe' in the name (by Github user MasonD) * Bug Fix: The 'Find All Valid Math Expressions' Coding Contract should now properly ignore whitespace in answers * Bug Fix: The 'Merge Overlapping Intervals' Coding Contract should now properly accept 2D arrays when being attempted through Netscript diff --git a/src/InteractiveTutorial.js b/src/InteractiveTutorial.js index 8a36775ee..a1c604f08 100644 --- a/src/InteractiveTutorial.js +++ b/src/InteractiveTutorial.js @@ -496,8 +496,7 @@ function iTutorialEnd() { var txt = createElement("p", { innerHTML: "If you are new to the game, the following links may be useful for you!

" + - "Getting Started Guide" + - "Wiki" + + "Getting Started Guide" + "Documentation

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

cat hackers-starting-handbook.lit" diff --git a/src/PersonObjects/Sleeve/Sleeve.ts b/src/PersonObjects/Sleeve/Sleeve.ts index a02842560..8e644e2af 100644 --- a/src/PersonObjects/Sleeve/Sleeve.ts +++ b/src/PersonObjects/Sleeve/Sleeve.ts @@ -394,6 +394,7 @@ export class Sleeve extends Person { this.agility_exp = 0; this.charisma_exp = 0; this.applyAugmentation(aug); + this.augmentations.push({ name: aug.name, level: 1 }); this.updateStatLevels(); } diff --git a/src/PersonObjects/Sleeve/SleeveAugmentationsUI.ts b/src/PersonObjects/Sleeve/SleeveAugmentationsUI.ts index 3fc5b76a7..bfc4fe43b 100644 --- a/src/PersonObjects/Sleeve/SleeveAugmentationsUI.ts +++ b/src/PersonObjects/Sleeve/SleeveAugmentationsUI.ts @@ -8,6 +8,7 @@ import { IPlayer } from "../IPlayer"; import { Augmentation } from "../../Augmentation/Augmentation"; import { Augmentations } from "../../Augmentation/Augmentations"; +import { AugmentationNames } from "../../Augmentation/data/AugmentationNames"; import { Faction } from "../../Faction/Faction"; import { Factions } from "../../Faction/Factions"; @@ -19,18 +20,25 @@ import { dialogBoxCreate } from "../../../utils/DialogBox"; import { createElement } from "../../../utils/uiHelpers/createElement"; import { createPopup } from "../../../utils/uiHelpers/createPopup"; import { createPopupCloseButton } from "../../../utils/uiHelpers/createPopupCloseButton"; +import { removeElementById } from "../../../utils/uiHelpers/removeElementById"; export function createSleevePurchaseAugsPopup(sleeve: Sleeve, p: IPlayer) { + // Array of all owned Augmentations. Names only + const ownedAugNames: string[] = sleeve.augmentations.map((e) => {return e.name}); + // 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)) { @@ -42,6 +50,36 @@ export function createSleevePurchaseAugsPopup(sleeve: Sleeve, p: IPlayer) { // Create popup const popupId = "purchase-sleeve-augs-popup"; + // Close popup button + const closeBtn = createPopupCloseButton(popupId, { innerText: "Cancel" }); + + // General info about owned Augmentations + const ownedAugsInfo = createElement("p", { + display: "block", + innerHTML: "Owned Augmentations:", + }); + + const popupElems: HTMLElement[] = [closeBtn, ownedAugsInfo]; + + // Show owned augmentations + // First we'll make a div with a reduced width, so the tooltips don't go off + // the edge of the popup + const ownedAugsDiv = createElement("div", { width: "70%" }); + for (const ownedAug of ownedAugNames) { + const aug: Augmentation | null = Augmentations[ownedAug]; + if (aug == null) { + console.warn(`Invalid Augmentation: ${ownedAug}`); + continue; + } + + ownedAugsDiv.appendChild(createElement("div", { + class: "gang-owned-upgrade", // Reusing a class from the Gang UI + innerText: ownedAug, + tooltip: aug.info, + })) + } + popupElems.push(ownedAugsDiv); + // General info about buying Augmentations const info = createElement("p", { innerHTML: @@ -55,10 +93,7 @@ export function createSleevePurchaseAugsPopup(sleeve: Sleeve, p: IPlayer) { ].join(" "), }); - // Close popup - const closeBtn = createPopupCloseButton(popupId, { innerText: "Cancel" }); - - const popupElems: HTMLElement[] = [closeBtn, info]; + popupElems.push(info); for (const aug of availableAugs) { const div = createElement("div", { @@ -66,17 +101,21 @@ export function createSleevePurchaseAugsPopup(sleeve: Sleeve, p: IPlayer) { }); div.appendChild(createElement("p", { + fontSize: "12px", innerHTML: [ `

${aug.name}


`, `Cost: ${numeralWrapper.formatMoney(aug.baseCost)}

`, `${aug.info}` ].join(" "), + padding: "2px", clickListener: () => { if (p.canAfford(aug.baseCost)) { p.loseMoney(aug.baseCost); sleeve.installAugmentation(aug); dialogBoxCreate(`Installed ${aug.name} on Duplicate Sleeve!`, false) + removeElementById(popupId); + createSleevePurchaseAugsPopup(sleeve, p); } else { dialogBoxCreate(`You cannot afford ${aug.name}`, false); } diff --git a/src/PersonObjects/Sleeve/SleeveUI.ts b/src/PersonObjects/Sleeve/SleeveUI.ts index b8ee967a0..cf8ef9cf4 100644 --- a/src/PersonObjects/Sleeve/SleeveUI.ts +++ b/src/PersonObjects/Sleeve/SleeveUI.ts @@ -11,8 +11,6 @@ import { IPlayer } from "../IPlayer"; import { CONSTANTS } from "../../Constants"; import { Locations } from "../../Locations"; -import { Augmentations } from "../../Augmentation/Augmentations"; - import { Faction } from "../../Faction/Faction"; import { Factions } from "../../Faction/Factions"; import { FactionWorkType } from "../../Faction/FactionWorkTypeEnum"; @@ -276,7 +274,7 @@ function createSleeveUi(sleeve: Sleeve, allSleeves: Sleeve[]): ISleeveUIElems { elems.purchaseAugsButton = createElement("button", { class: "std-button", display: "block", - innerText: "Purchase Augmentations", + innerText: "Manage Augmentations", clickListener: () => { createSleevePurchaseAugsPopup(sleeve, playerRef!); } diff --git a/src/PersonObjects/Sleeve/data/SleeveFaq.ts b/src/PersonObjects/Sleeve/data/SleeveFaq.ts index dbd39b511..72d3a9f99 100644 --- a/src/PersonObjects/Sleeve/data/SleeveFaq.ts +++ b/src/PersonObjects/Sleeve/data/SleeveFaq.ts @@ -1,7 +1,7 @@ export const SleeveFaq: string = [ -"How do sleeves work?
", -"Sleeves are essentially clones. You can use them to perform any work type", +"How do Duplicate Sleeves work?
", +"Duplicate Sleeves are essentially clones. You can use them to perform any work type", "action, such as working for a company/faction or committing a crime.", "Having sleeves perform these tasks earns you money, experience, and reputation.

", "Sleeves are their own individuals, which means they each have their own", @@ -31,6 +31,19 @@ export const SleeveFaq: string = "To clarify further, if you have two sleeves they can work for two different", "companies, but they cannot both work for the same company.

", +"Why did my Sleeve stop working?
", +"Sleeves are subject to the same time restrictions as you. This means that", +"they automatically stop working at a company after 8 hours, and stop working", +"for a faction after 20 hours.

", + +"How do I buy Augmentations for my Sleeves?
", +"Your Sleeve needs to have a Shock of 0 in order for you to buy Augmentations", +"for it.

", + +"Why can't I buy the X Augmentation for my sleeve?
", +"Certain Augmentations, like Bladeburner-specific ones and NeuroFlux Governor,", +"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." ].join(" "); diff --git a/src/engine.js b/src/engine.js index 7ad1175f9..bbf24a9f9 100644 --- a/src/engine.js +++ b/src/engine.js @@ -209,17 +209,6 @@ const Engine = { //Main menu buttons saveMainMenuButton: null, deleteMainMenuButton: null, - - //Tutorial buttons - tutorialNetworkingButton: null, - tutorialHackingButton: null, - tutorialScriptsButton: null, - tutorialNetscriptButton: null, - tutorialTravelingButton: null, - tutorialCompaniesButton: null, - tutorialFactionsButton: null, - tutorialAugmentationsButton: null, - tutorialBackButton: null, }, //Display objects @@ -348,7 +337,6 @@ const Engine = { loadTutorialContent: function() { Engine.hideAllContent(); Engine.Display.tutorialContent.style.display = "block"; - Engine.displayTutorialContent(); routing.navigateTo(Page.Tutorial); MainMenuLinks.Tutorial.classList.add("active"); }, @@ -769,40 +757,6 @@ const Engine = { Engine.Display.factionsContent.appendChild(invitationsList); }, - displayTutorialContent: function() { - document.getElementById("tutorial-getting-started-link").style.display = "block"; - Engine.Clickables.tutorialNetworkingButton.style.display = "block"; - Engine.Clickables.tutorialHackingButton.style.display = "block"; - Engine.Clickables.tutorialScriptsButton.style.display = "block"; - Engine.Clickables.tutorialNetscriptButton.style.display = "block"; - Engine.Clickables.tutorialTravelingButton.style.display = "block"; - Engine.Clickables.tutorialCompaniesButton.style.display = "block"; - Engine.Clickables.tutorialFactionsButton.style.display = "block"; - Engine.Clickables.tutorialAugmentationsButton.style.display = "block"; - document.getElementById("tutorial-shortcuts-link").style.display = "block"; - - Engine.Clickables.tutorialBackButton.style.display = "none"; - document.getElementById("tutorial-text").style.display = "none"; - }, - - //Displays the text when a section of the Tutorial is opened - displayTutorialPage: function(text) { - document.getElementById("tutorial-getting-started-link").style.display = "none"; - Engine.Clickables.tutorialNetworkingButton.style.display = "none"; - Engine.Clickables.tutorialHackingButton.style.display = "none"; - Engine.Clickables.tutorialScriptsButton.style.display = "none"; - Engine.Clickables.tutorialNetscriptButton.style.display = "none"; - Engine.Clickables.tutorialTravelingButton.style.display = "none"; - Engine.Clickables.tutorialCompaniesButton.style.display = "none"; - Engine.Clickables.tutorialFactionsButton.style.display = "none"; - Engine.Clickables.tutorialAugmentationsButton.style.display = "none"; - document.getElementById("tutorial-shortcuts-link").style.display = "none"; - - Engine.Clickables.tutorialBackButton.style.display = "inline-block"; - document.getElementById("tutorial-text").style.display = "block"; - document.getElementById("tutorial-text").innerHTML = text; - }, - /* Main Event Loop */ idleTimer: function() { //Get time difference @@ -1446,52 +1400,6 @@ const Engine = { //Init Location buttons initLocationButtons(); - //Tutorial buttons - Engine.Clickables.tutorialNetworkingButton = document.getElementById("tutorial-networking-link"); - Engine.Clickables.tutorialNetworkingButton.addEventListener("click", function() { - Engine.displayTutorialPage(CONSTANTS.TutorialNetworkingText); - }); - - Engine.Clickables.tutorialHackingButton = document.getElementById("tutorial-hacking-link"); - Engine.Clickables.tutorialHackingButton.addEventListener("click", function() { - Engine.displayTutorialPage(CONSTANTS.TutorialHackingText); - }); - - Engine.Clickables.tutorialScriptsButton = document.getElementById("tutorial-scripts-link"); - Engine.Clickables.tutorialScriptsButton.addEventListener("click", function() { - Engine.displayTutorialPage(CONSTANTS.TutorialScriptsText); - }); - - Engine.Clickables.tutorialNetscriptButton = document.getElementById("tutorial-netscript-link"); - Engine.Clickables.tutorialNetscriptButton.addEventListener("click", function() { - Engine.displayTutorialPage(CONSTANTS.TutorialNetscriptText); - }); - - Engine.Clickables.tutorialTravelingButton = document.getElementById("tutorial-traveling-link"); - Engine.Clickables.tutorialTravelingButton.addEventListener("click", function() { - Engine.displayTutorialPage(CONSTANTS.TutorialTravelingText); - }); - - Engine.Clickables.tutorialCompaniesButton = document.getElementById("tutorial-jobs-link"); - Engine.Clickables.tutorialCompaniesButton.addEventListener("click", function() { - Engine.displayTutorialPage(CONSTANTS.TutorialCompaniesText); - }); - - Engine.Clickables.tutorialFactionsButton = document.getElementById("tutorial-factions-link"); - Engine.Clickables.tutorialFactionsButton.addEventListener("click", function() { - Engine.displayTutorialPage(CONSTANTS.TutorialFactionsText); - }); - - Engine.Clickables.tutorialAugmentationsButton = document.getElementById("tutorial-augmentations-link"); - Engine.Clickables.tutorialAugmentationsButton.addEventListener("click", function() { - Engine.displayTutorialPage(CONSTANTS.TutorialAugmentationsText); - }); - - Engine.Clickables.tutorialBackButton = document.getElementById("tutorial-back-button"); - Engine.Clickables.tutorialBackButton.addEventListener("click", function() { - Engine.displayTutorialContent(); - }); - // Initialize references to main menu links if (!initializeMainMenuLinks()) { const errorMsg = "Failed to initialize Main Menu Links. Please try refreshing the page. " + diff --git a/src/index.html b/src/index.html index 6745ad9a8..b88c3e468 100644 --- a/src/index.html +++ b/src/index.html @@ -478,21 +478,51 @@ if (htmlWebpackPlugin.options.googleAnalytics.trackingId) { %> @@ -972,7 +1002,7 @@ if (htmlWebpackPlugin.options.googleAnalytics.trackingId) { %>
Changelog - Wiki + Documentation Subreddit From d9c818777bb4badaa669161adef1c7e4f70dae46 Mon Sep 17 00:00:00 2001 From: danielyxie Date: Mon, 4 Mar 2019 22:29:27 -0800 Subject: [PATCH 6/7] Updating version to v0.44.1 and Updating docuemtnation changelog --- doc/source/changelog.rst | 13 +++++++++++++ src/Constants.ts | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/doc/source/changelog.rst b/doc/source/changelog.rst index 47ee7059c..e6c945faf 100644 --- a/doc/source/changelog.rst +++ b/doc/source/changelog.rst @@ -3,6 +3,19 @@ Changelog ========= +v0.44.1 - 3/4/2019 +------------------ +* Duplicate Sleeve changes: +** You can now purchase Augmentations for your Duplicate Sleeves +** Sleeves are now assigned to Shock Recovery task by default +** Shock Recovery and Synchronize tasks are now twice as effective + +* Changed documentation so that Netscript functions are own their own pages. Sorry if this is annoying, it was necessary for properly cross-referencing +* Officially deprecated the Wiki (the fandom site). Use the 'readthedocs' Documentation instead +* Bug Fix: 'rm' Terminal and Netscript commands now work on non-program files that have '.exe' in the name (by Github user MasonD) +* Bug Fix: The 'Find All Valid Math Expressions' Coding Contract should now properly ignore whitespace in answers +* Bug Fix: The 'Merge Overlapping Intervals' Coding Contract should now properly accept 2D arrays when being attempted through Netscript + v0.44.0 - 2/26/2019 ------------------- * Bladeburner Changes: diff --git a/src/Constants.ts b/src/Constants.ts index ee2dca54f..ed1927d30 100644 --- a/src/Constants.ts +++ b/src/Constants.ts @@ -1,7 +1,7 @@ import {IMap} from "./types"; export let CONSTANTS: IMap = { - Version: "0.44.0", + Version: "0.44.1", //Max level for any skill, assuming no multipliers. Determined by max numerical value in javascript for experience //and the skill level formula in Player.js. Note that all this means it that when experience hits MAX_INT, then From f2b4ae86926bb1a7977a36bd4a002ef16da74ebc Mon Sep 17 00:00:00 2001 From: danielyxie Date: Mon, 4 Mar 2019 22:49:31 -0800 Subject: [PATCH 7/7] Adding build for v0.44.1...forgot it because im a dumbass --- dist/engine.bundle.js | 2 +- dist/vendor.bundle.js | 106 +++++++++++++++++++++--------------------- index.html | 49 +++++++++++++------ 3 files changed, 89 insertions(+), 68 deletions(-) diff --git a/dist/engine.bundle.js b/dist/engine.bundle.js index 88d9069fe..eeac59b55 100644 --- a/dist/engine.bundle.js +++ b/dist/engine.bundle.js @@ -1,2 +1,2 @@ -!function(e){function t(t){for(var i,o,s=t[0],l=t[1],c=t[2],p=0,m=[];p0?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),q.hp=Math.round(this.max_hp*e)},G.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},G.prototype.hasProgram=function(e){var t=q.getHomeComputer();if(null==t)return!1;for(var n=0;n0)&&(this.intelligence_exp+=e)},G.prototype.queryStatFromString=function(e){const t=e.toLowerCase();return t.includes("hack")?q.hacking_skill:t.includes("str")?q.strength:t.includes("def")?q.defense:t.includes("dex")?q.dexterity:t.includes("agi")?q.agility:t.includes("cha")?q.charisma:t.includes("int")?q.intelligence:void 0},G.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=""},G.prototype.processWorkEarnings=function(e=1){const t=this.workHackExpGainRate*e,n=this.workStrExpGainRate*e,i=this.workDefExpGainRate*e,a=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(i),this.gainDexterityExp(a),this.gainAgilityExp(r),this.gainCharismaExp(o),this.gainMoney(s),this.recordMoneySource(s,"work"),this.workHackExpGained+=t,this.workStrExpGained+=n,this.workDefExpGained+=i,this.workDexExpGained+=a,this.workAgiExpGained+=r,this.workChaExpGained+=o,this.workRepGained+=this.workRepGainRate*e,this.workMoneyGained+=this.workMoneyGainRate*e,this.workMoneyGained-=this.workMoneyLossRate*e},G.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 q.finishWork(!0),!1}),v.Engine.loadWorkInProgressContent()},G.prototype.work=function(e){var t=!1;if(this.timeWorked+v.Engine._idleSpeed*e>=_.CONSTANTS.MillisecondsPer8Hours&&(t=!0,e=Math.round((_.CONSTANTS.MillisecondsPer8Hours-this.timeWorked)/v.Engine._idleSpeed)),this.timeWorked+=v.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],i="0";null!=n&&n instanceof u.Company?i=n.playerReputation:console.error(`Could not find Company: ${this.companyName}`);const a=this.jobs[this.companyName];document.getElementById("work-in-progress-text").innerHTML="You are currently working as a "+a+" at "+this.companyName+" (Current Company Reputation: "+L.numeralWrapper.format(i,"0,0")+")

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

You have earned:

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

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

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

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

"+L.numeralWrapper.format(this.workChaExpGained,"0,0.0000")+" ("+L.numeralWrapper.format(this.workChaExpGainRate*H,"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."},G.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:
$"+L.numeralWrapper.format(this.workMoneyGained,"0,0.00")+"
"+L.numeralWrapper.format(this.workRepGained,"0,0.0000")+" reputation for the company
"+L.numeralWrapper.format(this.workHackExpGained,"0,0.0000")+" hacking exp
"+L.numeralWrapper.format(this.workStrExpGained,"0,0.0000")+" strength exp
"+L.numeralWrapper.format(this.workDefExpGained,"0,0.0000")+" defense exp
"+L.numeralWrapper.format(this.workDexExpGained,"0,0.0000")+" dexterity exp
"+L.numeralWrapper.format(this.workAgiExpGained,"0,0.0000")+" agility exp
"+L.numeralWrapper.format(this.workChaExpGained,"0,0.0000")+" charisma exp
";if(n=e?"You worked a short shift of "+Object(U.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(B.dialogBoxCreate)(n),document.getElementById("mainmenu-container").style.visibility="visible",this.isWorking=!1,v.Engine.loadLocationContent(),t){var i="You worked a short shift of "+Object(U.convertTimeMsToTimeElapsedString)(this.timeWorked)+" and earned $"+L.numeralWrapper.format(this.workMoneyGained,"0,0.00")+", "+L.numeralWrapper.format(this.workRepGained,"0,0.0000")+" reputation, "+L.numeralWrapper.format(this.workHackExpGained,"0,0.0000")+" hacking exp, "+L.numeralWrapper.format(this.workStrExpGained,"0,0.0000")+" strength exp, "+L.numeralWrapper.format(this.workDefExpGained,"0,0.0000")+" defense exp, "+L.numeralWrapper.format(this.workDexExpGained,"0,0.0000")+" dexterity exp, "+L.numeralWrapper.format(this.workAgiExpGained,"0,0.0000")+" agility exp, and "+L.numeralWrapper.format(this.workChaExpGained,"0,0.0000")+" charisma exp.";return this.resetWorkStatus(),i}this.resetWorkStatus()},G.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 q.finishWorkPartTime(),!1}),v.Engine.loadWorkInProgressContent()},G.prototype.workPartTime=function(e){var t=!1;if(this.timeWorked+v.Engine._idleSpeed*e>=_.CONSTANTS.MillisecondsPer8Hours&&(t=!0,e=Math.round((_.CONSTANTS.MillisecondsPer8Hours-this.timeWorked)/v.Engine._idleSpeed)),this.timeWorked+=v.Engine._idleSpeed*e,this.workRepGainRate=this.getWorkRepGain(),this.processWorkEarnings(e),t||this.timeWorked>=_.CONSTANTS.MillisecondsPer8Hours)return this.finishWorkPartTime();var n=p.Companies[this.companyName],i="0";null!=n&&n instanceof u.Company?i=n.playerReputation:console.log("ERROR: Could not find Company: "+this.companyName);const a=this.jobs[this.companyName];document.getElementById("work-in-progress-text").innerHTML="You are currently working as a "+a+" at "+this.companyName+" (Current Company Reputation: "+L.numeralWrapper.format(i,"0,0")+")

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

You have earned:

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

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

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

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

"+L.numeralWrapper.format(this.workChaExpGained,"0,0.0000")+" ("+L.numeralWrapper.format(this.workChaExpGainRate*H,"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."},G.prototype.finishWorkPartTime=function(e=!1){p.Companies[this.companyName].playerReputation+=this.workRepGained,this.updateSkillLevels();var t="You earned a total of:
$"+L.numeralWrapper.format(this.workMoneyGained,"0,0.00")+"
"+L.numeralWrapper.format(this.workRepGained,"0,0.0000")+" reputation for the company
"+L.numeralWrapper.format(this.workHackExpGained,"0,0.0000")+" hacking exp
"+L.numeralWrapper.format(this.workStrExpGained,"0,0.0000")+" strength exp
"+L.numeralWrapper.format(this.workDefExpGained,"0,0.0000")+" defense exp
"+L.numeralWrapper.format(this.workDexExpGained,"0,0.0000")+" dexterity exp
"+L.numeralWrapper.format(this.workAgiExpGained,"0,0.0000")+" agility exp
"+L.numeralWrapper.format(this.workChaExpGained,"0,0.0000")+" charisma exp
";if(t="You worked for "+Object(U.convertTimeMsToTimeElapsedString)(this.timeWorked)+"

"+t,e||Object(B.dialogBoxCreate)(t),document.getElementById("mainmenu-container").style.visibility="visible",this.isWorking=!1,v.Engine.loadLocationContent(),e){var n="You worked for "+Object(U.convertTimeMsToTimeElapsedString)(this.timeWorked)+" and earned a total of $"+L.numeralWrapper.format(this.workMoneyGained,"0,0.00")+", "+L.numeralWrapper.format(this.workRepGained,"0,0.0000")+" reputation, "+L.numeralWrapper.format(this.workHackExpGained,"0,0.0000")+" hacking exp, "+L.numeralWrapper.format(this.workStrExpGained,"0,0.0000")+" strength exp, "+L.numeralWrapper.format(this.workDefExpGained,"0,0.0000")+" defense exp, "+L.numeralWrapper.format(this.workDexExpGained,"0,0.0000")+" dexterity exp, "+L.numeralWrapper.format(this.workAgiExpGained,"0,0.0000")+" agility exp, and "+L.numeralWrapper.format(this.workChaExpGained,"0,0.0000")+" charisma exp";return this.resetWorkStatus(),n}this.resetWorkStatus()},G.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 q.finishFactionWork(!0),!1}),v.Engine.loadWorkInProgressContent()},G.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)},G.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)},G.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)},G.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 i=!1;if(this.timeWorked+v.Engine._idleSpeed*e>=_.CONSTANTS.MillisecondsPer20Hours&&(i=!0,e=Math.round((_.CONSTANTS.MillisecondsPer20Hours-this.timeWorked)/v.Engine._idleSpeed)),this.timeWorked+=v.Engine._idleSpeed*e,this.processWorkEarnings(e),i||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: "+L.numeralWrapper.format(t.playerReputation,"0,0")+").
You have been doing this for "+Object(U.convertTimeMsToTimeElapsedString)(this.timeWorked)+"

You have earned:

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

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

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

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

"+L.numeralWrapper.format(this.workChaExpGained,"0,0.0000")+" ("+L.numeralWrapper.format(this.workChaExpGainRate*H,"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."},G.prototype.finishFactionWork=function(e,t=!1){var n=C.Factions[this.currentWorkFactionName];n.playerReputation+=this.workRepGained,this.updateSkillLevels();var i="You worked for your faction "+n.name+" for a total of "+Object(U.convertTimeMsToTimeElapsedString)(this.timeWorked)+"

You earned a total of:
$"+L.numeralWrapper.format(this.workMoneyGained,"0,0.00")+"
"+L.numeralWrapper.format(this.workRepGained,"0,0.0000")+" reputation for the faction
"+L.numeralWrapper.format(this.workHackExpGained,"0,0.0000")+" hacking exp
"+L.numeralWrapper.format(this.workStrExpGained,"0,0.0000")+" strength exp
"+L.numeralWrapper.format(this.workDefExpGained,"0,0.0000")+" defense exp
"+L.numeralWrapper.format(this.workDexExpGained,"0,0.0000")+" dexterity exp
"+L.numeralWrapper.format(this.workAgiExpGained,"0,0.0000")+" agility exp
"+L.numeralWrapper.format(this.workChaExpGained,"0,0.0000")+" charisma exp
";if(t||Object(B.dialogBoxCreate)(i),document.getElementById("mainmenu-container").style.visibility="visible",this.isWorking=!1,v.Engine.loadFactionContent(),Object(O.a)(n.name),t){var a="You worked for your faction "+n.name+" for a total of "+Object(U.convertTimeMsToTimeElapsedString)(this.timeWorked)+". You earned "+L.numeralWrapper.format(this.workRepGained,"0,0.0000")+" rep, "+L.numeralWrapper.format(this.workHackExpGained,"0,0.0000")+" hacking exp, "+L.numeralWrapper.format(this.workStrExpGained,"0,0.0000")+" str exp, "+L.numeralWrapper.format(this.workDefExpGained,"0,0.0000")+" def exp, "+L.numeralWrapper.format(this.workDexExpGained,"0,0.0000")+" dex exp, "+L.numeralWrapper.format(this.workAgiExpGained,"0,0.0000")+" agi exp, and "+L.numeralWrapper.format(this.workChaExpGained,"0,0.0000")+" cha exp.";return this.resetWorkStatus(),a}this.resetWorkStatus()},G.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],i=d.CompanyPositions[n];return null==i?(console.error(`Could not find CompanyPosition object for ${n}. Work salary will be 0`),0):i.baseSalary*t.salaryMultiplier*this.work_money_mult*s.BitNodeMultipliers.CompanyWorkMoney*e},G.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},G.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},G.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},G.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},G.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},G.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},G.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 i=n.calculateJobPerformance(this.hacking_skill,this.strength,this.defense,this.dexterity,this.agility,this.charisma);i+=this.intelligence/_.CONSTANTS.MaxSkillLevel;var a=1+e.favor/100;return isNaN(a)&&(a=1),i*this.company_rep_mult*a},G.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},G.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},G.prototype.startCreateProgramWork=function(e,t,n){this.resetWorkStatus(),this.isWorking=!0,this.workType=_.CONSTANTS.WorkTypeCreateProgram,this.createProgramReqLvl=n,this.timeNeededToCompleteWork=t;for(var i=0;i=100)break;this.timeWorkedCreateProgram=o/100*this.timeNeededToCompleteWork,this.getHomeComputer().programs.splice(i,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 q.finishCreateProgramWork(!0),!1}),v.Engine.loadWorkInProgressContent()},G.prototype.createProgramWork=function(e){var t=this.createProgramReqLvl,n=this.hacking_skill/t;n=1+(n-1)/5,this.timeWorked+=v.Engine._idleSpeed*e,this.timeWorkedCreateProgram+=v.Engine._idleSpeed*e*n;var i=this.createProgramName;this.timeWorkedCreateProgram>=this.timeNeededToCompleteWork&&this.finishCreateProgramWork(!1),document.getElementById("work-in-progress-text").innerHTML="You are currently working on coding "+i+".

You have been working for "+Object(U.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."},G.prototype.finishCreateProgramWork=function(e,t=!1){var n=this.createProgramName;if(!1===e)Object(B.dialogBoxCreate)("You've finished creating "+n+"!
The new program can be found on your home computer."),this.getHomeComputer().programs.push(n);else{var i=n+"-"+(Math.floor(this.timeWorkedCreateProgram/this.timeNeededToCompleteWork*1e4)/100).toString()+"%-INC";this.getHomeComputer().programs.push(i)}e||this.gainIntelligenceExp(this.createProgramReqLvl/_.CONSTANTS.IntelligenceProgramBaseExpGain),document.getElementById("mainmenu-container").style.visibility="visible",this.isWorking=!1,v.Engine.loadTerminalContent(),this.resetWorkStatus()},G.prototype.startClass=function(e,t,n){this.resetWorkStatus(),this.isWorking=!0,this.workType=_.CONSTANTS.WorkTypeStudyClass,this.className=n;var i=1e3/v.Engine._idleSpeed,a=0,r=0,o=0,l=0,c=0,u=0,p=0;switch(n){case _.CONSTANTS.ClassStudyComputerScience:r=.5*t/i;break;case _.CONSTANTS.ClassDataStructures:a=_.CONSTANTS.ClassDataStructuresBaseCost*e/i,r=1*t/i;break;case _.CONSTANTS.ClassNetworks:a=_.CONSTANTS.ClassNetworksBaseCost*e/i,r=2*t/i;break;case _.CONSTANTS.ClassAlgorithms:a=_.CONSTANTS.ClassAlgorithmsBaseCost*e/i,r=4*t/i;break;case _.CONSTANTS.ClassManagement:a=_.CONSTANTS.ClassManagementBaseCost*e/i,p=2*t/i;break;case _.CONSTANTS.ClassLeadership:a=_.CONSTANTS.ClassLeadershipBaseCost*e/i,p=4*t/i;break;case _.CONSTANTS.ClassGymStrength:a=_.CONSTANTS.ClassGymBaseCost*e/i,o=1*t/i;break;case _.CONSTANTS.ClassGymDefense:a=_.CONSTANTS.ClassGymBaseCost*e/i,l=1*t/i;break;case _.CONSTANTS.ClassGymDexterity:a=_.CONSTANTS.ClassGymBaseCost*e/i,c=1*t/i;break;case _.CONSTANTS.ClassGymAgility:a=_.CONSTANTS.ClassGymBaseCost*e/i,u=1*t/i;break;default:throw new Error("ERR: Invalid/unrecognized class name")}this.workMoneyLossRate=a,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 q.finishClass(),!1}),v.Engine.loadWorkInProgressContent()},G.prototype.takeClass=function(e){this.timeWorked+=v.Engine._idleSpeed*e;var t=this.className;this.processWorkEarnings(e),document.getElementById("work-in-progress-text").innerHTML="You have been "+t+" for "+Object(U.convertTimeMsToTimeElapsedString)(this.timeWorked)+"

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

You have gained:
"+L.numeralWrapper.format(this.workHackExpGained,"0,0.0000")+" ("+L.numeralWrapper.format(this.workHackExpGainRate*H,"0,0.0000")+" / sec) hacking exp
"+L.numeralWrapper.format(this.workStrExpGained,"0,0.0000")+" ("+L.numeralWrapper.format(this.workStrExpGainRate*H,"0,0.0000")+" / sec) strength exp
"+L.numeralWrapper.format(this.workDefExpGained,"0,0.0000")+" ("+L.numeralWrapper.format(this.workDefExpGainRate*H,"0,0.0000")+" / sec) defense exp
"+L.numeralWrapper.format(this.workDexExpGained,"0,0.0000")+" ("+L.numeralWrapper.format(this.workDexExpGainRate*H,"0,0.0000")+" / sec) dexterity exp
"+L.numeralWrapper.format(this.workAgiExpGained,"0,0.0000")+" ("+L.numeralWrapper.format(this.workAgiExpGainRate*H,"0,0.0000")+" / sec) agility exp
"+L.numeralWrapper.format(this.workChaExpGained,"0,0.0000")+" ("+L.numeralWrapper.format(this.workChaExpGainRate*H,"0,0.0000")+" / sec) charisma exp
You may cancel at any time"},G.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(U.convertTimeMsToTimeElapsedString)(this.timeWorked)+",
you spent a total of $"+L.numeralWrapper.format(-1*this.workMoneyGained,"0,0.00")+".

You earned a total of:
"+L.numeralWrapper.format(this.workHackExpGained,"0,0.0000")+" hacking exp
"+L.numeralWrapper.format(this.workStrExpGained,"0,0.0000")+" strength exp
"+L.numeralWrapper.format(this.workDefExpGained,"0,0.0000")+" defense exp
"+L.numeralWrapper.format(this.workDexExpGained,"0,0.0000")+" dexterity exp
"+L.numeralWrapper.format(this.workAgiExpGained,"0,0.0000")+" agility exp
"+L.numeralWrapper.format(this.workChaExpGained,"0,0.0000")+" charisma exp
";if(e||Object(B.dialogBoxCreate)(t),document.getElementById("mainmenu-container").style.visibility="visible",this.isWorking=!1,v.Engine.loadLocationContent(),e){var n="After "+this.className+" for "+Object(U.convertTimeMsToTimeElapsedString)(this.timeWorked)+", you spent a total of $"+L.numeralWrapper.format(-1*this.workMoneyGained,"0,0.00")+". You earned a total of: "+L.numeralWrapper.format(this.workHackExpGained,"0,0.0000")+" hacking exp, "+L.numeralWrapper.format(this.workStrExpGained,"0,0.0000")+" strength exp, "+L.numeralWrapper.format(this.workDefExpGained,"0,0.0000")+" defense exp, "+L.numeralWrapper.format(this.workDexExpGained,"0,0.0000")+" dexterity exp, "+L.numeralWrapper.format(this.workAgiExpGained,"0,0.0000")+" agility exp, and "+L.numeralWrapper.format(this.workChaExpGained,"0,0.0000")+" charisma exp";return this.resetWorkStatus(),n}this.resetWorkStatus()},G.prototype.startCrime=function(e,t,n,i,a,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=i*this.defense_exp_mult*s.BitNodeMultipliers.CrimeExpGain,this.workDexExpGained=a*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 q.finishCrime(!0),!1}),v.Engine.loadWorkInProgressContent()},G.prototype.commitCrime=function(e){if(this.timeWorked+=v.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 i="["+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(U.convertTimeMsToTimeElapsedString)(this.timeNeededToCompleteWork-this.timeWorked)+"
"+i.replace(/ /g," ")}},G.prototype.finishCrime=function(e){if(!e){if(Object(b.determineCrimeSuccess)(q,this.crimeType)){let e=null;for(const t in E.Crimes)if(E.Crimes[t].type==this.crimeType){e=E.Crimes[t];break}null==e&&(console.log(this.crimeType),Object(B.dialogBoxCreate)("ERR: Unrecognized crime type. This is probably a bug please contact the developer")),q.gainMoney(this.workMoneyGained),q.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 "+L.numeralWrapper.format(this.workMoneyGained,"$0.000a")+", "+L.numeralWrapper.format(this.workHackExpGained,"0,0.0000")+" hack exp, "+L.numeralWrapper.format(this.workStrExpGained,"0,0.0000")+" str exp, "+L.numeralWrapper.format(this.workDefExpGained,"0,0.0000")+" def exp, "+L.numeralWrapper.format(this.workDexExpGained,"0,0.0000")+" dex exp, "+L.numeralWrapper.format(this.workAgiExpGained,"0,0.0000")+" agi exp, "+L.numeralWrapper.format(this.workChaExpGained,"0,0.0000")+" cha exp."):Object(B.dialogBoxCreate)("Crime successful!

You gained:
$"+L.numeralWrapper.format(this.workMoneyGained,"0,0.00")+"
"+L.numeralWrapper.format(this.workHackExpGained,"0,0.0000")+" hacking experience
"+L.numeralWrapper.format(this.workStrExpGained,"0,0.0000")+" strength experience
"+L.numeralWrapper.format(this.workDefExpGained,"0,0.0000")+" defense experience
"+L.numeralWrapper.format(this.workDexExpGained,"0,0.0000")+" dexterity experience
"+L.numeralWrapper.format(this.workAgiExpGained,"0,0.0000")+" agility experience
"+L.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 "+L.numeralWrapper.format(this.workHackExpGained,"0,0.0000")+" hack exp, "+L.numeralWrapper.format(this.workStrExpGained,"0,0.0000")+" str exp, "+L.numeralWrapper.format(this.workDefExpGained,"0,0.0000")+" def exp, "+L.numeralWrapper.format(this.workDexExpGained,"0,0.0000")+" dex exp, "+L.numeralWrapper.format(this.workAgiExpGained,"0,0.0000")+" agi exp, "+L.numeralWrapper.format(this.workChaExpGained,"0,0.0000")+" cha exp."):Object(B.dialogBoxCreate)("Crime failed!

You gained:
"+L.numeralWrapper.format(this.workHackExpGained,"0,0.0000")+" hacking experience
"+L.numeralWrapper.format(this.workStrExpGained,"0,0.0000")+" strength experience
"+L.numeralWrapper.format(this.workDefExpGained,"0,0.0000")+" defense experience
"+L.numeralWrapper.format(this.workDexExpGained,"0,0.0000")+" dexterity experience
"+L.numeralWrapper.format(this.workAgiExpGained,"0,0.0000")+" agility experience
"+L.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(),v.Engine.loadLocationContent()},G.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},G.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}`)},G.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}`)},G.prototype.hospitalize=function(){!1===w.Settings.SuppressHospitalizationPopup&&Object(B.dialogBoxCreate)("You were in critical condition! You were taken to the hospital where luckily they were able to save your life. You were charged "+L.numeralWrapper.format(this.max_hp*_.CONSTANTS.HospitalCostPerHp,"$0.000a")),this.loseMoney(this.max_hp*_.CONSTANTS.HospitalCostPerHp),this.hp=this.max_hp},G.prototype.applyForJob=function(e,t=!1){let n=null;""!==this.companyName&&(n=p.Companies[this.companyName]);const i=this.jobs[this.companyName],a=p.Companies[this.location];if(!(a 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(a,r)){var o=Object(h.getJobRequirementText)(a,r);return!t&&void Object(B.dialogBoxCreate)("Unforunately, you do not qualify for this position
"+o)}for(;;){let e=Object(m.getNextCompanyPosition)(r);if(null==e)break;if(!a.hasPosition(e))break;if(!this.isQualified(a,e))break;r=e}if(null==n||n.name!=a.name||r.name!=i){if(this.companyName=a.name,this.jobs[a.name]=r.name,document.getElementById("world-menu-header").click(),document.getElementById("world-menu-header").click(),t)return!0;Object(B.dialogBoxCreate)("Congratulations! You were offered a new job at "+this.companyName+" as a "+r.name+"!"),v.Engine.loadLocationContent()}else{var s=Object(m.getNextCompanyPosition)(r);if(null==s){if(t)return!1;Object(B.dialogBoxCreate)("You are already at the highest position for your field! No promotion available")}else if(a.hasPosition(s)){if(t)return!1;o=Object(h.getJobRequirementText)(a,s);Object(B.dialogBoxCreate)("Unfortunately, you do not qualify for a promotion
"+o)}else{if(t)return!1;Object(B.dialogBoxCreate)("You are already at the highest position for your field! No promotion available")}}},G.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 i=this.jobs[this.companyName],a=d.CompanyPositions[i];return a.isSoftwareJob()&&t.isSoftwareJob()||a.isITJob()&&t.isITJob()||a.isBusinessJob()&&t.isBusinessJob()||a.isSecurityEngineerJob()&&t.isSecurityEngineerJob()||a.isNetworkEngineerJob()&&t.isNetworkEngineerJob()||a.isSecurityJob()&&t.isSecurityJob()||a.isAgentJob()&&t.isAgentJob()||a.isSoftwareConsultantJob()&&t.isSoftwareConsultantJob()||a.isBusinessConsultantJob()&&t.isBusinessConsultantJob()||a.isPartTimeJob()&&t.isPartTimeJob()?Object(m.getNextCompanyPosition)(a):t},G.prototype.applyForSoftwareJob=function(e=!1){return this.applyForJob(d.CompanyPositions[g.SoftwareCompanyPositions[0]],e)},G.prototype.applyForSoftwareConsultantJob=function(e=!1){return this.applyForJob(d.CompanyPositions[g.SoftwareConsultantCompanyPositions[0]],e)},G.prototype.applyForItJob=function(e=!1){return this.applyForJob(d.CompanyPositions[g.ITCompanyPositions[0]],e)},G.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(B.dialogBoxCreate)("Unforunately, you do not qualify for this position")},G.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(B.dialogBoxCreate)("Unforunately, you do not qualify for this position")},G.prototype.applyForBusinessJob=function(e=!1){return this.applyForJob(d.CompanyPositions[g.BusinessCompanyPositions[0]],e)},G.prototype.applyForBusinessConsultantJob=function(e=!1){return this.applyForJob(d.CompanyPositions[g.BusinessConsultantCompanyPositions[0]],e)},G.prototype.applyForSecurityJob=function(e=!1){return this.applyForJob(d.CompanyPositions[g.SecurityCompanyPositions[2]],e)},G.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(B.dialogBoxCreate)("Unforunately, you do not qualify for this position")},G.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(B.dialogBoxCreate)("Congratulations, you are now employed at "+this.companyName),v.Engine.loadLocationContent()}else{if(e)return!1;Object(B.dialogBoxCreate)("Unforunately, you do not qualify for this position")}},G.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(B.dialogBoxCreate)("Congratulations, you are now employed part-time at "+this.companyName),v.Engine.loadLocationContent()}else{if(e)return!1;Object(B.dialogBoxCreate)("Unforunately, you do not qualify for this position")}},G.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(B.dialogBoxCreate)("Congratulations, you are now employed as a waiter at "+this.companyName),v.Engine.loadLocationContent()}else{if(e)return!1;Object(B.dialogBoxCreate)("Unforunately, you do not qualify for this position")}},G.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(B.dialogBoxCreate)("Congratulations, you are now employed as a part-time waiter at "+this.companyName),v.Engine.loadLocationContent()}else{if(e)return!1;Object(B.dialogBoxCreate)("Unforunately, you do not qualify for this position")}},G.prototype.isQualified=function(e,t){var n=e.jobStatReqOffset,i=t.requiredHacking>0?t.requiredHacking+n:0,a=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>=i&&this.strength>=a&&this.defense>=r&&this.dexterity>=o&&this.agility>=s&&this.charisma>=l&&e.playerReputation>=t.requiredReputation},G.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||!a(S.Locations.AevumECorp)||e.push(c);var u=C.Factions.MegaCorp;u.isBanned||u.isMember||u.alreadyInvited||!a(S.Locations.Sector12MegaCorp)||e.push(u);var m=C.Factions["Bachman & Associates"];m.isBanned||m.isMember||m.alreadyInvited||!a(S.Locations.AevumBachmanAndAssociates)||e.push(m);var h=C.Factions["Blade Industries"];h.isBanned||h.isMember||h.alreadyInvited||!a(S.Locations.Sector12BladeIndustries)||e.push(h);var d=C.Factions.NWO;d.isBanned||d.isMember||d.alreadyInvited||!a(S.Locations.VolhavenNWO)||e.push(d);var g=C.Factions["Clarke Incorporated"];g.isBanned||g.isMember||g.alreadyInvited||!a(S.Locations.AevumClarkeIncorporated)||e.push(g);var y=C.Factions["OmniTek Incorporated"];y.isBanned||y.isMember||y.alreadyInvited||!a(S.Locations.VolhavenOmniTekIncorporated)||e.push(y);var f=C.Factions["Four Sigma"];f.isBanned||f.isMember||f.alreadyInvited||!a(S.Locations.Sector12FourSigma)||e.push(f);var b=C.Factions["KuaiGong International"];b.isBanned||b.isMember||b.alreadyInvited||!a(S.Locations.ChongqingKuaiGongInternational)||e.push(b);var E=C.Factions["Fulcrum Secret Technologies"],v=A.b[x.a[x.b.FulcrumSecretTechnologies]];null==v?console.log("ERROR: Could not find Fulcrum Secret Technologies Server"):E.isBanned||E.isMember||E.alreadyInvited||!v.manuallyHacked||!a(S.Locations.AevumFulcrumTechnologies,25e4)||e.push(E);var k=C.Factions.BitRunners,O=this.getHomeComputer(),T=A.b[x.a[x.b.BitRunnersServer]];null==T?console.log("ERROR: Could not find BitRunners Server"):!k.isBanned&&!k.isMember&&T.manuallyHacked&&!k.alreadyInvited&&this.hacking_skill>=500&&O.maxRam>=128&&e.push(k);var M=C.Factions["The Black Hand"],P=A.b[x.a[x.b.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&&O.maxRam>=64&&e.push(M);var w=C.Factions.NiteSec,R=A.b[x.a[x.b.NiteSecServer]];null==R?console.log("ERROR: Could not find NiteSec Server"):!w.isBanned&&!w.isMember&&R.manuallyHacked&&!w.alreadyInvited&&this.hacking_skill>=200&&O.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 j=C.Factions.Volhaven;j.isBanned||j.isMember||j.alreadyInvited||!this.money.gte(5e7)||this.city!=S.Locations.Volhaven||e.push(j);var W=C.Factions["Speakers for the Dead"];!W.isBanned&&!W.isMember&&!W.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(W);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&&(i.includes("Chief Technology Officer")||i.includes("Chief Financial Officer")||i.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.b[x.a[x.b.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},G.prototype.inGang=function(){return null!=this.gang&&void 0!=this.gang&&this.gang instanceof T.b},G.prototype.startGang=function(e,t){this.gang=new T.b(e,t)},G.prototype.hasCorporation=function(){return null!=this.corporation&&this.corporation instanceof y.a},G.prototype.inBladeburner=function(){return null!=this.bladeburner&&this.bladeburner instanceof l.a},G.prototype.setBitNodeNumber=function(e){this.bitNodeN=e},G.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))},G.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 i=this.factions.slice();if(0==(i=i.filter(e=>!o.includes(e))).length)return e.type=c.CodingContractRewardType.Money,this.gainCodingContractReward(e,t);const l=Math.floor(r/i.length);for(const e of i)C.Factions[e]instanceof k.Faction&&(C.Factions[e].playerReputation+=l);return`Gained ${l} reputation for each of the following factions: ${i.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 a=_.CONSTANTS.CodingContractBaseMoneyGain*t*s.BitNodeMultipliers.CodingContractMoney;return this.gainMoney(a),this.recordMoneySource(a,"codingcontract"),`Gained ${L.numeralWrapper.format(a,"$0.000a")}`}},G.prototype.toJSON=function(){return Object(F.Generic_toJSON)("PlayerObject",this)},G.fromJSON=function(e){return Object(F.Generic_fromJSON)(G,e.data)},F.Reviver.constructors.PlayerObject=G;let q=new G},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.CONSTANTS={Version:"0.44.0",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,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,TutorialNetworkingText:"Servers are a central part of the game. You start with a single personal server (your home computer) and you can purchase additional servers as you progress through the game. Connecting to other servers and hacking them can be a major source of income and experience. Servers can also be used to run scripts which can automatically hack servers for you.

In order to navigate between machines, use the 'scan' or 'scan-analyze' Terminal command to see all servers that are reachable from your current server. Then, you can use the 'connect [hostname/ip]' command to connect to one of the available machines.

The 'hostname' and 'ifconfig' commands can be used to display the hostname/IP of the server you are currently connected to.",TutorialHackingText:"In the year 2077, currency has become digital and decentralized. People and corporations store their money on servers. By hacking these servers, you can steal their money and gain experience.

Gaining root access


The key to hacking a server is to gain root access to that server. This can be done using the NUKE virus (NUKE.exe). You start the game with a copy of the NUKE virus on your home computer. The NUKE virus attacks the target server's open ports using buffer overflow exploits. When successful, you are granted root administrative access to the machine.

Typically, in order for the NUKE virus to succeed, the target server needs to have at least one of its ports opened. Some servers have no security and will not need any ports opened. Some will have very high security and will need many ports opened. In order to open ports on another server, you will need to run programs that attack the server to open specific ports. These programs can be coded once your hacking skill gets high enough, or they can be purchased if you can find a seller.

In order to determine how many ports need to be opened to successfully NUKE a server, connect to that server and run the 'analyze' command. This will also show you which ports have already been opened.

Once you have enough ports opened and have ran the NUKE virus to gain root access, the server can then be hacked by simply calling the 'hack' command through terminal, or by using a script.

Hacking mechanics


When you execute the hack command, either manually through the terminal or automatically through a script, you attempt to hack the server. This action takes time. The more advanced a server's security is, the more time it will take. Your hacking skill level also affects the hacking time, with a higher hacking skill leading to shorter hacking times. Also, running the hack command manually through terminal is faster than hacking from a script.

Your attempt to hack a server will not always succeed. The chance you have to successfully hack a server is also determined by the server's security and your hacking skill level. Even if your hacking attempt is unsuccessful, you will still gain experience points.

When you successfully hack a server. You steal a certain percentage of that server's total money. This percentage is determined by the server's security and your hacking skill 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 (since you are only hacking a certain percentage). You can increase the amount of money on a server using a script and the grow() function in Netscript.

Server Security


Each server has a security level, typically between 1 and 100. A higher number means the server has stronger security. It is possible for a server to have a security level of 100 or higher, in which case hacking that server will become impossible (0% chance to hack).

As mentioned above, a server's security level is an important factor to consider when hacking. You can check a server's security level using the 'analyze' command, although this only gives an estimate (with 5% uncertainty). You can also check a server's security in a script, using the getServerSecurityLevel(server) function in Netscript. See the Netscript documentation for more details. This function will give you an exact value for a server's security.

Whenever a server is hacked manually or through a script, its security level increases by a small amount. Calling the grow() command in a script will also increase security level of the target server. These actions will make it harder for you to hack the server, and decrease the amount of money you can steal. You can lower a server's security level in a script using the weaken(server) function in Netscript. See the Netscript documentation for more details.

A server has a minimum security level that is equal to one third of its starting security, rounded to the nearest integer. To be more precise:

server.minSecurityLevel = Math.max(1, Math.round(server.startingSecurityLevel / 3))

This means that a server's security will not fall below this value if you are trying to weaken it.",TutorialScriptsText:"Scripts can be used to automate the hacking process. Scripts must be written in the Netscript language. Documentation about the Netscript language can be found in the 'Netscript Programming Language' section of this 'Tutorial' page.

It is highly recommended that you have a basic background in programming to start writing scripts. You by no means need to be an expert. All you need is some familiarity with basic programming constructs like for/while loops, if statements, functions, variables, etc. The Netscript programming language most resembles the Javascript language. Therefore, a good beginner's programming tutorial to read might be this one. Note that while the Netscript language is similar to Javascript, it is not the exact same, so the syntax will vary a little bit.

Running a script requires RAM. The more complex a script is, the more RAM it requires to run. Scripts can be run on any server you have root access to.

Here are some Terminal commands that are useful when working with scripts:

check [script] [args...]
Prints the logs of the script specified by the name and arguments to Terminal. Arguments should be separated by a space. Note that scripts are uniquely identified by their arguments as well as their name. For example, if you ran a script 'foo.script' with the argument 'foodnstuff' then in order to 'check' it you must also add the 'foodnstuff' argument to the check command as so:
check foo.script foodnstuff

free
Shows the current server's RAM usage and availability

kill [script] [args...]
Stops a script that is running with the specified script name and arguments. Arguments should be separated by a space. Note that scripts are uniquely identified by their arguments as well as their name. For example, if you ran a script 'foo.script' with the argument 1 and 2, then just typing 'kill foo.script' will not work. You have to use 'kill foo.script 1 2'.

mem [script] [-t] [n]
Check how much RAM a script requires to run with n threads

nano [script]
Create/Edit a script. The name of the script must end with the '.script' extension

ps
Displays all scripts that are actively running on the current server

rm [script]
Delete a script

run [script] [-t] [n] [args...]
Run a script with n threads and the specified arguments. Each argument should be separated by a space. Both the arguments and thread specification are optional. If neither are specified, then the script will be run single-threaded with no arguments.
Examples:
run foo.script
The command above will run 'foo.script' single-threaded with no arguments.
run foo.script -t 10
The command above will run 'foo.script' with 10 threads and no arguments.
run foo.script foodnstuff sigma-cosmetics 10
The command above will run 'foo.script' single-threaded with three arguments: [foodnstuff, sigma-cosmetics, 10]
run foo.script -t 50 foodnstuff
The command above will run 'foo.script' with 50 threads and a single argument: [foodnstuff]

tail [script] [args...]
Displays the logs of the script specified by the name and arguments. Note that scripts are uniquely identified by their arguments as well as their name. For example, if you ran a script 'foo.script' with the argument 'foodnstuff' then in order to 'tail' it you must also add the 'foodnstuff' argument to the tail command as so:
tail foo.script foodnstuff

top
Displays all active scripts and their RAM usage

Multithreading scripts


Scripts can be multithreaded. A multithreaded script runs the script's code once in each thread. The result is that every call to the hack(), grow(), and weaken() Netscript functions will have its effect multiplied by the number of threads. For example, if a normal single-threaded script is able to hack $10,000, then running the same script with 5 threads would yield $50,000.

When multithreading a script, the total RAM cost can be calculated by simply multiplying the base RAM cost of the script with the number of threads, where the base cost refers to the amount of RAM required to run the script single-threaded. In the terminal, you can run the 'mem [scriptname] -t n' command to see how much RAM a script requires with n threads.

Every method for running a script has an option for making it multihreaded. To run a script with n threads from a Terminal:
run [scriptname] -t n

Using Netscript commands:
run('scriptname.script', n);
exec('scriptname.script, 'targetServer', n);

Notes about how scripts work offline


The scripts that you write and execute are interpreted in Javascript. For this reason, it is not possible for these scripts to run while offline (when the game is closed). It is important to note that for this reason, conditionals such as if/else statements and certain commands such as purchaseHacknetNode() or nuke() will not work while the game is offline.

However, Scripts WILL continue to generate money and hacking exp for you while the game is offline. This offline production is based off of the scripts' production while the game is online.

grow() and weaken() are two Netscript commands that will also be applied when the game is offline, although at a slower rate compared to if the game was open. This is done by having each script keep track of the rate at which the grow() and weaken() commands are called when the game is online. These calculated rates are used to determine how many times these function calls would be made while the game is offline.

Also, note that because of the way the Netscript interpreter is implemented, whenever you reload or re-open the game all of the scripts that you are running will start running from the BEGINNING of the code. The game does not keep track of where exactly the execution of a script is when it saves/loads.


",TutorialNetscriptText:"Netscript is a programming language implemented for this game. There are two versions of Netscript: Netscript 1.0 and Netscript 2.0 (NetscriptJS).

Click here for Bitburner's official Netscript documentation",TutorialTravelingText:"There are six major cities in the world that you are able to travel to:

Aevum
Chongqing
Sector-12
New Tokyo
Ishima
Volhaven

To travel between cities, visit your current city's travel agency through the 'World' page. From the travel agency you can travel to any other city. Doing so costs money.

Each city has its own set of companies and unique locations. Also, certain content is only available to you if you are in certain cities, so get exploring!",TutorialCompaniesText:"Hacking is not the only way to gain money and experience! Located around the world are many different companies which you can work for. By working for a company you can earn money, train your various labor skills, and unlock powerful passive perks.

To apply for a job, visit the company you want to work for through the 'World' menu. The company page will have options that let you apply to positions in the company. There might be several different positions you can apply for, ranging from software engineer to business analyst to security officer.

When you apply for a job, you will get the offer if your stats are high enough. Your first position at a company will be an entry-level position such as 'intern'. Once you get the job, an button will appear on the company page that allows you to work for the company. Click this button to start working.

Working occurs in 8 hour shifts. Once you start working, you will begin earning money, experience, and reputation. The rate at which you money and experience depends on the company and your position. The amount of reputation you gain for your company is based on your job performance, which is affected by your stats. Different positions value different stats. When you are working, you are unable to perform any other actions such as using your terminal or visiting other locations (However, note that any scripts you have running on servers will continue to run as you work!). It is possible to cancel your work shift before the 8 hours is up. However, if you have a full-time job, then cancelling a shift early will result in you gaining only half of the reputation that you had earned up to that point. There are also part-time/consultant jobs available where you will not be penalized if you cancel a work shift early. However, these positions pay less than full-time positions.

As you continue to work at a company, you will gain more and more reputation at that company. When your stats and reputation are high enough, you can get a promotion. You can apply for a promotion on the company page, just like you applied for the job originally. Higher positions at a company provide better salaries and stat gains.

Infiltrating Companies


Many companies have facilities that you can attempt to infiltrate. By infiltrating, you can steal classified company secrets and then sell these for money or for faction reputation. To try and infiltrate a company, visit a company through the 'World' menu. There will be an option that says 'Infiltrate Company'.

When infiltrating a company, you must progress through clearance levels in the facility. Every clearance level has some form of security that you must get past. There are several forms of security, ranging from high-tech security systems to armed guards. For each form of security, there are a variety of options that you can choose to try and bypass the security. Examples include hacking the security, engaging in combat, assassination, or sneaking past the security. The chance to succeed for each option is determined in part by your stats. So, for example, trying to hack the security system relies on your hacking skill, whereas trying to sneak past the security relies on your agility level.

The facility has a 'security level' that affects your chance of success when trying to get past a clearance level. Every time you advance to the next clearance level, the facility's security level will increase by a fixed amount. Furthermore the options you choose and whether you succeed or fail will affect the security level as well. For example, if you try to kill a security guard and fail, the security level will increase by a lot. If you choose to sneak past security and succeed, the security level will not increase at all.

Every 5 clearance levels, you will steal classified company secrets that can be sold for money or faction reputation. However, in order to sell these secrets you must successfully escape the facility using the 'Escape' option. Furthermore, companies have a max clearance level. If you reach the max clearance level you will automatically escape the facility with all of your stolen secrets.

",TutorialFactionsText:"Throughout the game you may receive invitations from factions. There are many different factions, and each faction has different criteria for determining its potential members. Joining a faction and furthering its cause is crucial to progressing in the game and unlocking endgame content.

It is possible to join multiple factions if you receive invitations from them. However, note that joining a faction may prevent you from joining other rival factions.

The 'Factions' link on the menu brings up a list of all factions that you have joined. You can select a Faction on this list to go to that Faction page. This page displays general information about the Faction and also lets you perform work for the faction. Working for a Faction is similar to working for a company except that you don't get paid a salary. You will only earn reputation in your Faction and train your stats. Also, cancelling work early when working for a Faction does NOT result in reduced experience/reputation earnings.

Earning reputation for a Faction unlocks powerful Augmentations. Purchasing and installing these Augmentations will upgrade your abilities. The Augmentations that are available to unlock vary from faction to faction.",TutorialAugmentationsText:"Advances in science and medicine have lead to powerful new technologies that allow people to augment themselves beyond normal human capabilities. There are many different types of Augmentations, ranging from cybernetic to genetic to biological. Acquiring these Augmentations enhances the user's physical and mental faculties.

Because of how powerful these Augmentations are, the technology behind them is kept private and secret by the corporations and organizations that create them. Therefore, the only way for the player to obtain Augmentations is through Factions. After joining a Faction and earning enough reputation in it, you will be able to purchase its Augmentations. Different Factions offer different Augmentations. Augmentations must be purchased in order to be installed, and they are fairly expensive.

When you purchase an Augmentation, the price of purchasing another Augmentation increases by 90%. This multiplier stacks for each Augmentation you purchase. You will not gain the benefits of your purchased Augmentations until you install them. You can choose to install Augmentations through the 'Augmentations' menu tab. Once you install your purchased Augmentations, their costs are reset back to the original price.

Unfortunately, installing Augmentations has side effects. You will lose most of the progress you've made, including your skills, stats, and money. You will have to start over, but you will have all of the Augmentations you have installed to help you progress.

To summarize, here is a list of everything you will LOSE when you install an Augmentation:

Stats/Skills
Money
Scripts on all servers EXCEPT your home computer
Purchased servers
Hacknet Nodes
Company/faction reputation
Jobs and Faction memberships
Programs
Stocks
TOR router

Here is everything you will KEEP when you install an Augmentation:

Every Augmentation you have installed
Scripts on your home computer
RAM and CPU Core Upgrades on your home computer
World Stock Exchange account and TIX API Access
",LatestUpdate:'\n v0.44.0\n * Bladeburner Changes:\n ** Reduced the amount of rank needed to earn a skill point\n ** Reduced the effects of the "Reaper" and "Evasive System" skills\n ** Increased the effect of the "Hyperdrive" and "Hands of Midas" skills\n ** Slightly increased the rate which the skill point cost rises for almost all skills\n ** The "Overlock" Skill now has a maximum level of 90 instead of 95\n ** Money earned from Contracts increased by 400%\n ** Changed the way population affects success rate. Extreme populations now have less dramatic effects\n ** Added two new General Actions: Diplomacy and Hyperbolic Regeneration Chamber\n ** Lowered the rep and money cost of the "Blade\'s Simulacrum" augmentation\n ** Significantly decreased the initial amount of Contracts/Operations (the "Contracts/Operations remaining" value)\n ** Decreased the rate at which the amount of Contracts/Operations increases over time\n ** Decreased the number of successes you need to increase the max level of a Contract/Operation\n ** Increased the average number of Synthoid communities each city has\n ** Reduced the amount by which a successful raid will decrease the population of a city\n ** The "riots" event will now increase the chaos of a city by a greater amount\n ** Significantly increased the effect that Agility and Dexterity have on action time\n\n * Added new BitNode multipliers:\n ** HomeComputerRamCost - Affects how much it costs to upgrade home computer\'s RAM\n ** DaedalusAugsRequirement - Affects how many Augmentations you need in order to get invited to Daedalus\n ** FourSigmaMarketDataCost - Affects how much it costs to unlock the stock market\'s 4S Market Data\n ** FourSigmaMarketDataApiCost - Affects how much it costs to unlock the stock market\'s 4S Market Data API\n\n * A few minor changes to BitNode multipliers across the board (mostly for the new multipliers)\n * \'The Covenant\' now requires 20 total Augmentations to get invited, rather than 30\n * You can now purchase permanent Duplicate Sleeves from \'The Covenant\'. This requires Source-File 10, and you must be in BN-10 or after\n * You can now track where all of your money comes from in the \'Stats\' page\n * Increased the money gained from Coding Contracts by 50%\n * getCharacterInformation() function now returns the player\'s HP and max HP\n * Bug Fix: You can no longer disconnect the enemy\'s connections in Hacking Missions\n * Bug Fix: Duplicate Sleeve faction reputation gain is now properly affected by faction favor\n * Bug Fix: After installing Augmentations, the Terminal display will now correctly show the current server as "home"\n * Bug Fix: Fixed an exploit where you could change the duration of timed functions (e.g. hack, weaken) in NetscriptJS\n * Bug Fix: You should now properly be able to use the ServerProfile.exe program\n * Bug Fix: Prevented exploit that allowed you to accept faction invites programmatically through NetscriptJS\n * Bug Fix: Faction invitations for megacorporations should now work properly\n '}},function(e,t,n){"use strict";function i(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(i("span",{class:"tooltiptext",innerHTML:t.tooltip}))):void 0!==t.tooltipleft?(e.className+=" tooltip",e.appendChild(i("span",{class:"tooltiptextleft",innerHTML:t.tooltipleft}))):void 0!==t.tooltipsmall?(e.className+=" tooltip",e.appendChild(i("span",{class:"tooltiptext smallfont",innerHTML:t.tooltipsmall}))):void 0!==t.tooltiplow&&(e.className+="tooltip",e.appendChild(i("span",{class:"tooltiptextlow",innerHTML:t.tooltiplow})))}(n,t),n}Object.defineProperty(t,"__esModule",{value:!0}),t.createElement=i},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const i=n(97);n(412),n(411),n(410),n(409),n(408),n(407),n(406),n(405),n(404),n(403),n(402),n(401),n(400),n(399);t.numeralWrapper=new class{constructor(){this.defaultLocale="en",this.defaultLocale="en"}updateLocale(e){return null!=i.locale(e)||(console.warn(`Invalid locale for numeral: ${e}`),i.locale(this.defaultLocale),!1)}format(e,t){return Math.abs(e)<1e-6&&(e=0),i(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";Object.defineProperty(t,"__esModule",{value:!0});const i=n(48);function a(e){return e.every(i.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),i=t%86400,a=Math.floor(i/3600),r=i%3600,o=Math.floor(r/60);let s="";return n>0&&(s+=`${n} days `),a>0&&(s+=`${a} hours `),o>0&&(s+=`${o} minutes `),s+=`${r%60} seconds`},t.longestCommonStart=function(e){if(!a(e))return"";if(0===e.length)return"";const t=e.concat().sort(),n=t[0],i=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 i=0;i{t.delay=null,n()},e),t.delayResolve=n})}function d(e,t,n=null){var i="";null!=n&&(i=" (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+i}function g(e,t,n,a,o=1){if(null!=(p=Object(r.c)(t,n,e)))return a.scriptRef.log(t+" is already running on "+e.hostname),Promise.resolve(!1);for(var s=0;sm?(a.scriptRef.log("Cannot run script "+t+"(t="+o+") on "+e.hostname+" because there is not enough available RAM!"),Promise.resolve(!1)):(null==a.disableLogs.ALL&&null==a.disableLogs.exec&&null==a.disableLogs.run&&null==a.disableLogs.spawn&&a.scriptRef.log("Running script: "+t+" on "+e.hostname+" with "+o+" threads and args: "+Object(l.arrayToString)(n)+". May take a few seconds to start up..."),(p=new r.a(c,n)).threads=o,e.runningScripts.push(p),Object(i.c)(p,e),Promise.resolve(!0))}return a.scriptRef.log("Could not find script "+t+" on "+e.hostname),Promise.resolve(!1)}function _(e){if(!Object(u.isString)(e))return!1;let t=e.split("|");if(4!=t.length)return!1;var n=t[1];return!!Object(c.isValidIPAddress)(n)}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const i=n(62);function a(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;":""}`,a=`${e}`;i.getElementById("terminal-input").insertAdjacentHTML("beforebegin",a),function(){const e=i.getElementById("terminal-container");e.scrollTop=e.scrollHeight}()}t.post=function(e){a(e)},t.postError=function(e){a(`ERROR: ${e}`,{color:"#ff2929"})},t.hackProgressBarPost=function(e){a(e,{id:"hack-progress-bar"})},t.hackProgressPost=function(e){a(e,{id:"hack-progress"})}},function(e,t,n){"use strict";n.r(t),function(e){n.d(t,"dialogBoxCreate",function(){return r}),n.d(t,"dialogBoxOpened",function(){return a});let i=[];e(document).click(function(t){a&&i.length>=1&&(e(t.target).closest(i[0]).length||(i[0].remove(),i.splice(0,1),0==i.length?a=!1:i[0].style.visibility="visible"))}),e(document).on("click",".dialog-box-close-button",function(e){a&&i.length>=1&&(i[0].remove(),i.splice(0,1),0==i.length?a=!1:i[0].style.visibility="visible")});var a=!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),i.length>=1&&(n.style.visibility="hidden"),i.push(n),setTimeout(function(){a=!0},400)}}.call(this,n(73))},function(e,t,n){"use strict";n.r(t),function(e){n.d(t,"Engine",function(){return oe});var i=n(4),a=n(94),r=n(78),o=n(13),s=n(66),l=n(6),c=n(70),u=n(34),p=n(159),m=n(119),h=n(107),d=(n(33),n(19)),g=n(69),_=n(1),y=n(142),f=n(15),b=n(51),E=n(52),v=n(110),k=n(5),C=n(77),O=n(37),T=n(100),S=n(44),M=n(65),P=n(47),A=n(35),w=n(0),x=n(104),R=(n(28),n(114)),N=n(68),I=n(84),L=n(32),D=n(11),B=n(18),j=n(86),W=n(85),F=n(36),U=n(24),H=n(59),G=n(98),K=n(121),q=n(141),$=n(87),Y=n(158),z=n(12),V=n(3),J=n(157),X=n(156),Q=n(26),Z=n(9),ee=n(101),te=(n(16),n(27)),ne=(n(21),n(2)),ie=n(40),ae=n(140),re=n(29);n(270),n(229),n(227),n(225),n(223),n(221),n(219),n(217),n(215),n(213),n(211),n(209),n(207),n(205),n(203),n(201),n(199),n(197),n(195),n(193),n(191),n(189),n(187);e(document).keydown(function(e){if(!0!==B.Settings.DisableHotkeys){try{if(Object(L.d)().isFocused())return}catch(e){}if(!(w.a.isWorking||N.b||M.c||m.a))if(84==e.keyCode&&e.altKey)e.preventDefault(),oe.loadTerminalContent();else if(e.keyCode===re.KEY.C&&e.altKey)e.preventDefault(),oe.loadCharacterContent();else if(e.keyCode===re.KEY.E&&e.altKey)e.preventDefault(),oe.loadScriptEditorContent();else if(e.keyCode===re.KEY.S&&e.altKey)e.preventDefault(),oe.loadActiveScriptsContent();else if(e.keyCode===re.KEY.H&&e.altKey)e.preventDefault(),oe.loadHacknetNodesContent();else if(e.keyCode===re.KEY.W&&e.altKey)e.preventDefault(),oe.loadWorldContent();else if(e.keyCode===re.KEY.J&&e.altKey)e.preventDefault(),oe.loadJobContent();else if(e.keyCode===re.KEY.R&&e.altKey)e.preventDefault(),oe.loadTravelContent();else if(e.keyCode===re.KEY.P&&e.altKey)e.preventDefault(),oe.loadCreateProgramContent();else if(e.keyCode===re.KEY.F&&e.altKey){if(z.routing.isOn(z.Page.Terminal)&&E.a.ENABLE_BASH_HOTKEYS)return;e.preventDefault(),oe.loadFactionsContent()}else e.keyCode===re.KEY.A&&e.altKey?(e.preventDefault(),oe.loadAugmentationsContent()):e.keyCode===re.KEY.U&&e.altKey&&(e.preventDefault(),oe.loadTutorialContent());e.keyCode===re.KEY.O&&e.altKey&&(e.preventDefault(),Object(ee.b)())}});const oe={version:"",Debug:!0,overview:new p.a,Clickables:{saveMainMenuButton:null,deleteMainMenuButton:null,tutorialNetworkingButton:null,tutorialHackingButton:null,tutorialScriptsButton:null,tutorialNetscriptButton:null,tutorialTravelingButton:null,tutorialCompaniesButton:null,tutorialFactionsButton:null,tutorialAugmentationsButton:null,tutorialBackButton: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(){oe.hideAllContent(),oe.Display.terminalContent.style.display="block",z.routing.navigateTo(z.Page.Terminal),Q.MainMenuLinks.Terminal.classList.add("active")},loadCharacterContent:function(){oe.hideAllContent(),oe.Display.characterContent.style.display="block",oe.updateCharacterInfo(),z.routing.navigateTo(z.Page.CharacterInfo),Q.MainMenuLinks.Stats.classList.add("active")},loadScriptEditorContent:function(e="",t=""){oe.hideAllContent(),oe.Display.scriptEditorContent.style.display="block";try{Object(L.d)().openScript(e,t)}catch(e){Object(ie.exceptionAlert)(e)}Object(L.h)(),z.routing.navigateTo(z.Page.ScriptEditor),Q.MainMenuLinks.ScriptEditor.classList.add("active")},loadActiveScriptsContent:function(){oe.hideAllContent(),oe.Display.activeScriptsContent.style.display="block",Object(r.c)(),z.routing.navigateTo(z.Page.ActiveScripts),Q.MainMenuLinks.ActiveScripts.classList.add("active")},loadHacknetNodesContent:function(){oe.hideAllContent(),oe.Display.hacknetNodesContent.style.display="block",Object(C.b)(),z.routing.navigateTo(z.Page.HacknetNodes),Q.MainMenuLinks.HacknetNodes.classList.add("active")},loadWorldContent:function(){oe.hideAllContent(),oe.Display.worldContent.style.display="block",oe.displayWorldInfo(),z.routing.navigateTo(z.Page.World),Q.MainMenuLinks.City.classList.add("active")},loadCreateProgramContent:function(){oe.hideAllContent(),oe.Display.createProgramContent.style.display="block",Object(R.a)(),z.routing.navigateTo(z.Page.CreateProgram),Q.MainMenuLinks.CreateProgram.classList.add("active")},loadFactionsContent:function(){oe.hideAllContent(),oe.Display.factionsContent.style.display="block",oe.displayFactionsInfo(),z.routing.navigateTo(z.Page.Factions),Q.MainMenuLinks.Factions.classList.add("active")},loadFactionContent:function(){oe.hideAllContent(),oe.Display.factionContent.style.display="block",z.routing.navigateTo(z.Page.Faction)},loadAugmentationsContent:function(){oe.hideAllContent(),oe.Display.augmentationsContent.style.display="block",Object(s.c)(oe.Display.augmentationsContent),z.routing.navigateTo(z.Page.Augmentations),Q.MainMenuLinks.Augmentations.classList.add("active")},loadTutorialContent:function(){oe.hideAllContent(),oe.Display.tutorialContent.style.display="block",oe.displayTutorialContent(),z.routing.navigateTo(z.Page.Tutorial),Q.MainMenuLinks.Tutorial.classList.add("active")},loadDevMenuContent:function(){oe.hideAllContent(),Object(y.b)(),z.routing.navigateTo(z.Page.DevMenu),Q.MainMenuLinks.DevMenu.classList.add("active")},loadLocationContent:function(){oe.hideAllContent(),oe.Display.locationContent.style.display="block";try{Object(v.a)()}catch(e){Object(ie.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")}oe.loadLocationContent()},loadJobContent:function(){""!=w.a.companyName?(w.a.location=w.a.companyName,oe.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(){oe.hideAllContent(),document.getElementById("mainmenu-container").style.visibility="hidden",oe.Display.workInProgressContent.style.display="block",z.routing.navigateTo(z.Page.WorkInProgress)},loadRedPillContent:function(){oe.hideAllContent(),document.getElementById("mainmenu-container").style.visibility="hidden",oe.Display.redPillContent.style.display="block",z.routing.navigateTo(z.Page.RedPill)},loadCinematicTextContent:function(){oe.hideAllContent(),document.getElementById("mainmenu-container").style.visibility="hidden",oe.Display.cinematicTextContent.style.display="block",z.routing.navigateTo(z.Page.CinematicText)},loadInfiltrationContent:function(){oe.hideAllContent(),oe.Display.infiltrationContent.style.display="block",z.routing.navigateTo(z.Page.Infiltration)},loadStockMarketContent:function(){oe.hideAllContent(),oe.Display.stockMarketContent.style.display="block",z.routing.navigateTo(z.Page.StockMarket),Object(U.g)()},loadGangContent:function(){oe.hideAllContent(),document.getElementById("gang-container")||w.a.inGang()?(w.a.gang.displayGangContent(w.a),z.routing.navigateTo(z.Page.Gang)):(oe.loadTerminalContent(),z.routing.navigateTo(z.Page.Terminal))},loadMissionContent:function(){oe.hideAllContent(),document.getElementById("mainmenu-container").style.visibility="hidden",document.getElementById("character-overview-wrapper").style.visibility="hidden",oe.Display.missionContent.style.display="block",z.routing.navigateTo(z.Page.Mission)},loadCorporationContent:function(){w.a.corporation instanceof g.a&&(oe.hideAllContent(),document.getElementById("character-overview-wrapper").style.visibility="hidden",w.a.corporation.createUI(),z.routing.navigateTo(z.Page.Corporation))},loadBladeburnerContent:function(){if(w.a.bladeburner instanceof u.a)try{oe.hideAllContent(),z.routing.navigateTo(z.Page.Bladeburner),w.a.bladeburner.createContent()}catch(e){Object(ie.exceptionAlert)(e)}},loadSleevesContent:function(){try{oe.hideAllContent(),z.routing.navigateTo(z.Page.Sleeves),Object(K.createSleevesPage)(w.a)}catch(e){Object(ie.exceptionAlert)(e)}},loadResleevingContent:function(){try{oe.hideAllContent(),z.routing.navigateTo(z.Page.Resleeves),Object(q.createResleevesPage)(w.a)}catch(e){Object(ie.exceptionAlert)(e)}},hideAllContent:function(){oe.Display.terminalContent.style.display="none",oe.Display.characterContent.style.display="none",oe.Display.scriptEditorContent.style.display="none",oe.Display.activeScriptsContent.style.display="none",oe.Display.hacknetNodesContent.style.display="none",oe.Display.worldContent.style.display="none",oe.Display.createProgramContent.style.display="none",oe.Display.factionsContent.style.display="none",oe.Display.factionContent.style.display="none",oe.Display.factionAugmentationsContent.style.display="none",oe.Display.augmentationsContent.style.display="none",oe.Display.tutorialContent.style.display="none",oe.Display.locationContent.style.display="none",oe.Display.workInProgressContent.style.display="none",oe.Display.redPillContent.style.display="none",oe.Display.cinematicTextContent.style.display="none",oe.Display.infiltrationContent.style.display="none",oe.Display.stockMarketContent.style.display="none",oe.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.a&&w.a.corporation.clearUI(),w.a.bladeburner instanceof u.a&&w.a.bladeburner.clearContent(),Object(q.clearResleevesPage)(),Object(K.clearSleevesPage)(),oe.aevumLocationsList.style.display="none",oe.chongqingLocationsList.style.display="none",oe.sector12LocationsList.style.display="none",oe.newTokyoLocationsList.style.display="none",oe.ishimaLocationsList.style.display="none",oe.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(y.a)()},displayCharacterOverviewInfo:function(){oe.overview.update();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)(oe.Display.characterInfo,w.a)},aevumLocationsList:null,chongqingLocationsList:null,sector12LocationsList:null,newTokyoLocationsList:null,ishimaLocationsList:null,volhavenLocationsList:null,displayWorldInfo:function(){oe.aevumLocationsList.style.display="none",oe.chongqingLocationsList.style.display="none",oe.sector12LocationsList.style.display="none",oe.newTokyoLocationsList.style.display="none",oe.ishimaLocationsList.style.display="none",oe.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:oe.aevumLocationsList.style.display="inline";break;case k.Locations.Chongqing:oe.chongqingLocationsList.style.display="inline";break;case k.Locations.Sector12:oe.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:oe.newTokyoLocationsList.style.display="inline";break;case k.Locations.Ishima:oe.ishimaLocationsList.style.display="inline";break;case k.Locations.Volhaven:oe.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,oe.loadStockMarketContent(),!1)})),t.appendChild(e),w.a.corporation instanceof g.a&&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:()=>(oe.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:()=>(oe.loadBladeburnerContent(),!1)})),t.appendChild(e))},displayFactionsInfo:function(){Object(te.removeChildrenFromElement)(oe.Display.factionsContent),oe.Display.factionsContent.appendChild(Object(ne.createElement)("h1",{innerText:"Factions"})),oe.Display.factionsContent.appendChild(Object(ne.createElement)("p",{innerText:"Lists all factions you have joined"}));var e=Object(ne.createElement)("ul");oe.Display.factionsContent.appendChild(Object(ne.createElement)("br"));for(var t=0;t(oe.loadFactionContent(),Object(b.a)(n),!1)})),e.appendChild(Object(ne.createElement)("br"))}();oe.Display.factionsContent.appendChild(e),oe.Display.factionsContent.appendChild(Object(ne.createElement)("br")),oe.Display.factionsContent.appendChild(Object(ne.createElement)("h1",{innerText:"Outstanding Faction Invitations"})),oe.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)(f.Factions[e]);for(var n=0;n0&&(oe._lastUpdate=e-n,w.a.lastUpdate=e-n,oe.updateGame(t)),window.requestAnimationFrame(oe.idleTimer)},updateGame:function(e=1){var t=e*oe._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&&(oe._totalActionTime=H.a.actionTime,oe._actionTimeLeft=H.a.actionTime,oe._actionInProgress=!0,oe._actionProgressBarCount=1,oe._actionProgressStr="[ ]",oe._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.a&&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")),oe.Counters.createProgramNotifications=10}if(oe.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 i=n[Math.floor(Math.random()*n.length)];Object(b.b)(i)}oe.Counters.checkFactionInvitations=100}if(oe.Counters.passiveFactionGrowth<=0){var s=Math.floor(600-oe.Counters.passiveFactionGrowth);Object(b.d)(s),oe.Counters.passiveFactionGrowth=600}if(oe.Counters.messages<=0&&(Object(S.c)(),o.Augmentations[l.AugmentationNames.TheRedPill].owned?oe.Counters.messages=4500:oe.Counters.messages=150),oe.Counters.sCr<=0&&(w.a.hasWseAccount&&Object(U.q)(),oe.Counters.sCr=1500),oe.Counters.mechanicProcess<=0){if(w.a.corporation instanceof g.a&&w.a.corporation.process(),w.a.bladeburner instanceof u.a)try{w.a.bladeburner.process()}catch(e){Object(ie.exceptionAlert)("Exception caught in Bladeburner.process(): "+e)}oe.Counters.mechanicProcess=5}oe.Counters.contractGeneration<=0&&(Math.random()<=.25&&Object(h.b)(),oe.Counters.contractGeneration=3e3)},_totalActionTime:0,_actionTimeLeft:0,_actionTimeStr:"Time left: ",_actionProgressStr:"[ ]",_actionProgressBarCount:1,_actionInProgress:!1,updateHackProgress:function(e=1){var t=e*oe._idleSpeed;oe._actionTimeLeft-=t/1e3,oe._actionTimeLeft=Math.max(oe._actionTimeLeft,0);for(var n=Math.round(100*(1-oe._actionTimeLeft/oe._totalActionTime));2*oe._actionProgressBarCount<=n;)oe._actionProgressStr=Object(i.replaceAt)(oe._actionProgressStr,oe._actionProgressBarCount,"|"),oe._actionProgressBarCount+=1;oe._actionTimeStr="Time left: "+Math.max(0,Math.round(oe._actionTimeLeft)).toString()+"s",document.getElementById("hack-progress").innerHTML=oe._actionTimeStr,document.getElementById("hack-progress-bar").innerHTML=oe._actionProgressStr.replace(/ /g," "),n>=100&&(oe._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,a,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(E):E.style.display="none",w.a.firstTimeTraveled?z.push(y):y.style.display="none",w.a.firstProgramAvailable?z.push(r):r.style.display="none",w.a.hasWseAccount?z.push(v):v.style.display="none",w.a.bladeburner instanceof u.a?z.push(k):k.style.display="none",w.a.corporation instanceof g.a?z.push(M):M.style.display="none",w.a.inGang()?z.push(A):A.style.display="none",oe.closeMainMenuHeader(z)}else{console.log("Initializing new game"),Object(c.initBitNodes)(),Object(c.initBitNodeMultipliers)(w.a),Object(j.c)(),Object(F.c)(),oe.setDisplayElements(),oe.start(),w.a.init(),Object(D.f)(),Object(d.initCompanies)(),Object(f.initFactions)(),Object(s.d)(),Object(S.d)(),Object(U.i)(),Object(T.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",E.style.display="none",v.style.display="none",y.style.display="none",r.style.display="none",k.style.display="none",M.style.display="none",A.style.display="none",N.style.display="none",oe.openMainMenuHeader([t,n,a,o,m,h,x,R]),Object(O.c)(),Object(ae.removeLoadingScreen)()}Object(J.a)(),Object(L.g)(),H.a.resetTerminalInput()},setDisplayElements:function(){if(oe.Display.terminalContent=document.getElementById("terminal-container"),z.routing.navigateTo(z.Page.Terminal),oe.Display.characterContent=document.getElementById("character-container"),oe.Display.characterContent.style.display="none",oe.Display.scriptEditorContent=document.getElementById("script-editor-container"),oe.Display.scriptEditorContent.style.display="none",oe.Display.activeScriptsContent=document.getElementById("active-scripts-container"),oe.Display.activeScriptsContent.style.display="none",oe.Display.hacknetNodesContent=document.getElementById("hacknet-nodes-container"),oe.Display.hacknetNodesContent.style.display="none",oe.Display.worldContent=document.getElementById("world-container"),oe.Display.worldContent.style.display="none",oe.Display.createProgramContent=document.getElementById("create-program-container"),oe.Display.createProgramContent.style.display="none",oe.Display.factionsContent=document.getElementById("factions-container"),oe.Display.factionsContent.style.display="none",oe.Display.factionContent=document.getElementById("faction-container"),oe.Display.factionContent.style.display="none",oe.Display.factionAugmentationsContent=document.getElementById("faction-augmentations-container"),oe.Display.factionAugmentationsContent.style.display="none",oe.Display.augmentationsContent=document.getElementById("augmentations-container"),oe.Display.augmentationsContent.style.display="none",oe.Display.tutorialContent=document.getElementById("tutorial-container"),oe.Display.tutorialContent.style.display="none",oe.Display.infiltrationContent=document.getElementById("infiltration-container"),oe.Display.infiltrationContent.style.display="none",oe.Display.stockMarketContent=document.getElementById("stock-market-container"),oe.Display.stockMarketContent.style.display="none",oe.Display.missionContent=document.getElementById("mission-container"),oe.Display.missionContent.style.display="none",oe.Display.characterInfo=document.getElementById("character-content"),oe.aevumLocationsList=document.getElementById("aevum-locations-list"),oe.chongqingLocationsList=document.getElementById("chongqing-locations-list"),oe.sector12LocationsList=document.getElementById("sector12-locations-list"),oe.newTokyoLocationsList=document.getElementById("newtokyo-locations-list"),oe.ishimaLocationsList=document.getElementById("ishima-locations-list"),oe.volhavenLocationsList=document.getElementById("volhaven-locations-list"),oe.Display.locationContent=document.getElementById("location-container"),oe.Display.locationContent.style.display="none",oe.Display.workInProgressContent=document.getElementById("work-in-progress-container"),oe.Display.workInProgressContent.style.display="none",oe.Display.redPillContent=document.getElementById("red-pill-container"),oe.Display.redPillContent.style.display="none",oe.Display.cinematicTextContent=document.getElementById("cinematic-text-container"),oe.Display.cinematicTextContent.style.display="none",Object(v.b)(),oe.Clickables.tutorialNetworkingButton=document.getElementById("tutorial-networking-link"),oe.Clickables.tutorialNetworkingButton.addEventListener("click",function(){oe.displayTutorialPage(_.CONSTANTS.TutorialNetworkingText)}),oe.Clickables.tutorialHackingButton=document.getElementById("tutorial-hacking-link"),oe.Clickables.tutorialHackingButton.addEventListener("click",function(){oe.displayTutorialPage(_.CONSTANTS.TutorialHackingText)}),oe.Clickables.tutorialScriptsButton=document.getElementById("tutorial-scripts-link"),oe.Clickables.tutorialScriptsButton.addEventListener("click",function(){oe.displayTutorialPage(_.CONSTANTS.TutorialScriptsText)}),oe.Clickables.tutorialNetscriptButton=document.getElementById("tutorial-netscript-link"),oe.Clickables.tutorialNetscriptButton.addEventListener("click",function(){oe.displayTutorialPage(_.CONSTANTS.TutorialNetscriptText)}),oe.Clickables.tutorialTravelingButton=document.getElementById("tutorial-traveling-link"),oe.Clickables.tutorialTravelingButton.addEventListener("click",function(){oe.displayTutorialPage(_.CONSTANTS.TutorialTravelingText)}),oe.Clickables.tutorialCompaniesButton=document.getElementById("tutorial-jobs-link"),oe.Clickables.tutorialCompaniesButton.addEventListener("click",function(){oe.displayTutorialPage(_.CONSTANTS.TutorialCompaniesText)}),oe.Clickables.tutorialFactionsButton=document.getElementById("tutorial-factions-link"),oe.Clickables.tutorialFactionsButton.addEventListener("click",function(){oe.displayTutorialPage(_.CONSTANTS.TutorialFactionsText)}),oe.Clickables.tutorialAugmentationsButton=document.getElementById("tutorial-augmentations-link"),oe.Clickables.tutorialAugmentationsButton.addEventListener("click",function(){oe.displayTutorialPage(_.CONSTANTS.TutorialAugmentationsText)}),oe.Clickables.tutorialBackButton=document.getElementById("tutorial-back-button"),oe.Clickables.tutorialBackButton.addEventListener("click",function(){oe.displayTutorialContent()}),!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(ie.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(ie.exceptionAlert)(new Error(e)),void console.error(e)}(Q.MainMenuLinks.Terminal.addEventListener("click",function(){return oe.loadTerminalContent(),!1}),Q.MainMenuLinks.ScriptEditor.addEventListener("click",function(){return oe.loadScriptEditorContent(),!1}),Q.MainMenuLinks.ActiveScripts.addEventListener("click",function(){return oe.loadActiveScriptsContent(),!1}),Q.MainMenuLinks.CreateProgram.addEventListener("click",function(){return oe.loadCreateProgramContent(),!1}),Q.MainMenuLinks.Stats.addEventListener("click",function(){return oe.loadCharacterContent(),!1}),Q.MainMenuLinks.Factions.addEventListener("click",function(){return oe.loadFactionsContent(),!1}),Q.MainMenuLinks.Augmentations.addEventListener("click",function(){return oe.loadAugmentationsContent(),!1}),Q.MainMenuLinks.HacknetNodes.addEventListener("click",function(){return oe.loadHacknetNodesContent(),!1}),Q.MainMenuLinks.Sleeves.addEventListener("click",function(){return oe.loadSleevesContent(),Q.MainMenuLinks.Sleeves.classList.add("active"),!1}),Q.MainMenuLinks.City.addEventListener("click",function(){return oe.loadWorldContent(),!1}),Q.MainMenuLinks.Travel.addEventListener("click",function(){return oe.loadTravelContent(),Q.MainMenuLinks.Travel.classList.add("active"),!1}),Q.MainMenuLinks.Job.addEventListener("click",function(){return oe.loadJobContent(),Q.MainMenuLinks.Job.classList.add("active"),!1}),Q.MainMenuLinks.StockMarket.addEventListener("click",function(){return oe.loadStockMarketContent(),Q.MainMenuLinks.StockMarket.classList.add("active"),!1}),Q.MainMenuLinks.Bladeburner.addEventListener("click",function(){return oe.loadBladeburnerContent(),!1}),Q.MainMenuLinks.Corporation.addEventListener("click",function(){return oe.loadCorporationContent(),Q.MainMenuLinks.Corporation.classList.add("active"),!1}),Q.MainMenuLinks.Gang.addEventListener("click",function(){return oe.loadGangContent(),!1}),Q.MainMenuLinks.Tutorial.addEventListener("click",function(){return oe.loadTutorialContent(),!1}),Q.MainMenuLinks.DevMenu.addEventListener("click",function(){return!1}),oe.ActiveScriptsList=document.getElementById("active-scripts-list"),oe.Clickables.saveMainMenuButton=document.getElementById("save-game-link"),oe.Clickables.saveMainMenuButton.addEventListener("click",function(){return I.b.saveGame(se),!1}),oe.Clickables.deleteMainMenuButton=document.getElementById("delete-game-link"),oe.Clickables.deleteMainMenuButton.addEventListener("click",function(){return I.b.deleteGame(se),!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(se),!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){f.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)}),oe.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(){oe.idleTimer(),Object(A.f)()}};var se,le;window.onload=function(){if(!window.indexedDB)return oe.load(null);(le=window.indexedDB.open("bitburnerSave",1)).onerror=function(e){return console.log("Error opening indexedDB: "),console.log(e),oe.load(null)},le.onsuccess=function(e){console.log("Opening bitburnerSave database successful!");var t=(se=e.target.result).transaction(["savestring"]).objectStore("savestring").get("save");t.onerror=function(e){return console.log("Error in Database request to get savestring: "+e),oe.load(null)},t.onsuccess=function(e){oe.load(t.result)}},le.onupgradeneeded=function(e){e.target.result.createObjectStore("savestring")}}}.call(this,n(73))},function(e,t,n){"use strict";n.d(t,"f",function(){return y}),n.d(t,"h",function(){return f}),n.d(t,"k",function(){return b}),n.d(t,"j",function(){return E}),n.d(t,"i",function(){return k}),n.d(t,"g",function(){return C}),n.d(t,"a",function(){return O}),n.d(t,"c",function(){return T}),n.d(t,"e",function(){return S}),n.d(t,"d",function(){return _}),n.d(t,"b",function(){return v});var i=n(20),a=n(45),r=n(1),o=n(32),s=n(0),l=n(28),c=n(36),u=n(75),p=n(16),m=n(71),h=n(166),d=n(14),g=n(106);function _(e={ip:Object(m.a)(),hostname:""}){this.ip=e.ip?e.ip:Object(m.a)();for(var t=e.hostname,n=0,a="";null!=T(t+a);)a="-"+n,++n;this.hostname=t+a,this.organizationName=null!=e.organizationName?e.organizationName:"",this.isConnectedTo=null!=e.isConnectedTo&&e.isConnectedTo,this.hasAdminRights=null!=e.adminRights&&e.adminRights,this.purchasedByPlayer=null!=e.purchasedByPlayer&&e.purchasedByPlayer,this.manuallyHacked=!1,this.maxRam=null!=e.maxRam?e.maxRam:0,this.ramUsed=0,this.cpuCores=1,this.scripts=[],this.runningScripts=[],this.programs=[],this.messages=[],this.textFiles=[],this.contracts=[],this.dir=0,this.requiredHackingSkill=null!=e.requiredHackingSkill?e.requiredHackingSkill:1,this.moneyAvailable=null!=e.moneyAvailable?e.moneyAvailable*i.BitNodeMultipliers.ServerStartingMoney:0,this.moneyMax=25*this.moneyAvailable*i.BitNodeMultipliers.ServerMaxMoney,this.hackDifficulty=null!=e.hackDifficulty?e.hackDifficulty*i.BitNodeMultipliers.ServerStartingSecurity:1,this.baseDifficulty=this.hackDifficulty,this.minDifficulty=Math.max(1,Math.round(this.hackDifficulty/3)),this.serverGrowth=null!=e.serverGrowth?e.serverGrowth:1,this.serversOnNetwork=[],this.numOpenPortsRequired=null!=e.numOpenPortsRequired?e.numOpenPortsRequired:5,this.sshPortOpen=!1,this.ftpPortOpen=!1,this.smtpPortOpen=!1,this.httpPortOpen=!1,this.sqlPortOpen=!1,this.openPortCount=0}function y(){const e=[];for(let t=0;t<15;t++)e.push([]);const t=["hackDifficulty","moneyAvailable","requiredHackingSkill","serverGrowth"],n=e=>{switch(typeof e){case"number":return e;case"object":return Object(p.getRandomInt)(e.min,e.max);default:throw Error(`Do not know how to convert the type '${typeof e}' to a number`)}};for(const i of h.serverMetadata){const a={hostname:i.hostname,ip:Object(m.a)(),numOpenPortsRequired:i.numOpenPortsRequired,organizationName:i.organizationName};void 0!==i.maxRamExponent&&(a.maxRam=Math.pow(2,n(i.maxRamExponent)));for(const e of t)void 0!==i[e]&&(a[e]=n(i[e]));const r=new _(a);for(const e of i.literature||[])r.messages.push(e);void 0!==i.specialName&&c.a.addIp(i.specialName,r.ip),O(r),void 0!==i.networkLayer&&e[n(i.networkLayer)-1].push(r)}const i=e=>e[Math.floor(Math.random()*e.length)],a=(e,t)=>{for(const n of e)r=n,o=t(),r.serversOnNetwork.push(o.ip),o.serversOnNetwork.push(r.ip)};var r,o;a(e[0],()=>s.a.getHomeComputer());for(let t=1;ti(e[t-1]))}function f(e,t){let n=1+(r.CONSTANTS.ServerBaseGrowthRate-1)/e.hackDifficulty;n>r.CONSTANTS.ServerMaxGrowthRate&&(n=r.CONSTANTS.ServerMaxGrowthRate);const i=e.serverGrowth/100;return Math.log(t)/(Math.log(n)*s.a.hacking_grow_mult*i)}function b(e,t){const n=Math.max(Math.floor(t/450),0);var a=1+(r.CONSTANTS.ServerBaseGrowthRate-1)/e.hackDifficulty;a>r.CONSTANTS.ServerMaxGrowthRate&&(a=r.CONSTANTS.ServerMaxGrowthRate);const o=n*(e.serverGrowth/100)*i.BitNodeMultipliers.ServerGrowthRate;var l=Math.pow(a,o*s.a.hacking_grow_mult);l<1&&(console.log("WARN: serverGrowth calculated to be less than 1"),l=1);const c=e.moneyAvailable;if(e.moneyAvailable*=l,e.moneyMax&&isNaN(e.moneyAvailable)&&(e.moneyAvailable=e.moneyMax),e.moneyMax&&e.moneyAvailable>e.moneyMax&&(e.moneyAvailable=e.moneyMax),c!==e.moneyAvailable){let t=f(e,e.moneyAvailable/c);t=Math.max(0,t),e.fortify(2*r.CONSTANTS.ServerFortifyAmount*Math.ceil(t))}return e.moneyAvailable/c}function E(e){const t=e.programs.includes(l.Programs.BitFlume.name);e.programs.length=0,e.runningScripts=[],e.serversOnNetwork=[],e.isConnectedTo=!0,e.ramUsed=0,e.programs.push(l.Programs.NukeProgram.name),t&&e.programs.push(l.Programs.BitFlume.name),e.scripts.forEach(function(e){e.updateRamUsage()}),e.messages.length=0,e.messages.push("hackers-starting-handbook.lit")}_.prototype.setMaxRam=function(e){this.maxRam=e},_.prototype.getServerOnNetwork=function(e){if(!(e>this.serversOnNetwork.length))return v[this.serversOnNetwork[e]];console.log("Tried to get server on network that was out of range")},_.prototype.getScript=function(e){for(var t=0;t1e6&&(this.hackDifficulty=1e6)},_.prototype.fortify=function(e){this.hackDifficulty+=e,this.capDifficulty()},_.prototype.weaken=function(e){this.hackDifficulty-=e*i.BitNodeMultipliers.ServerWeakenRate,this.capDifficulty()},_.prototype.writeToScriptFile=function(e,t){var n={success:!1,overwritten:!1};if(!Object(o.e)(e))return n;for(let i=0;it.fn!==e.fn):this.contracts=this.contracts.filter(t=>t.fn!==e)},_.prototype.getContract=function(e){for(const t of this.contracts)if(t.fn===e)return t;return null},_.prototype.toJSON=function(){return Object(d.Generic_toJSON)("Server",this)},_.fromJSON=function(e){return Object(d.Generic_fromJSON)(_,e.data)},d.Reviver.constructors.Server=_;let v={};function k(){for(var e in v)delete v[e];v={}}function C(e){v=JSON.parse(e,d.Reviver)}function O(e){var t=e.ip;if(Object(m.b)(t))throw console.log("IP of server that's being added: "+t),console.log("Hostname of the server thats being added: "+e.hostname),console.log("The server that already has this IP is: "+v[t].hostname),new Error("Error: Trying to add a server with an existing IP");v[t]=e}function T(e){for(var t in v)if(v.hasOwnProperty(t)&&v[t].hostname==e)return v[t];return null}function S(e){return Object(g.isValidIPAddress)(e)?void 0!==v[e]?v[e]:null:T(e)}function M(e,t,n){this.s=e,this.p=t,this.c=[],this.n=n,this.d=t.d+1,this.scrs=[],this.pgms=[],this.msgs=[]}M.prototype.createSubdir=function(e){new M(this.s,this,e)},M.prototype.getPath=function(e){for(var t=[],n=this;null!==n;)t.unshift(n.n,"/"),n=n.parent;return t.unshift("/"),t.join("")}},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";function i(e,t){var n;if(null==t)return console.log("Reviver WRONGLY called with key: "+e+", and value: "+t),0;if("object"==typeof t&&"string"==typeof t.ctor&&void 0!==t.data){if("AllServersMap"===t.ctor)return console.log("Converting AllServersMap for v0.43.1"),t.data;if("function"==typeof(n=i.constructors[t.ctor]||window[t.ctor])&&"function"==typeof n.fromJSON)return n.fromJSON(t)}return t}function a(e,t,n){var i,a;n||(n=Object.keys(t)),i={};for(let e=0;e{n=e,null!=t.Companies[n.name]&&console.warn(`Duplicate Company Position being defined: ${n.name}`),t.Companies[n.name]=new a.Company(n)});for(const n in t.Companies){const i=t.Companies[n];e[n]instanceof a.Company?(i.favor=e[n].favor,isNaN(i.favor)&&(i.favor=0)):i.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}),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 i=n(62);t.clearEventListeners=function(e){try{let t;const n=(t="string"==typeof e?i.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 i=n(21);t.yesNoBoxOpen=!1;const a=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 a?a.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 i.clearEventListeners("yes-no-box-yes")},t.yesNoBoxGetNoButton=function(){return i.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"),a?a.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 i.clearEventListeners("yes-no-text-input-box-yes")},t.yesNoTxtInpBoxGetNoButton=function(){return i.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 i=n(62),a=n(67);t.removeElementById=function(e){try{const t=i.getElementById(e);a.removeElement(t)}catch(e){}}},function(e,t,n){"use strict";n.d(t,"c",function(){return P}),n.d(t,"d",function(){return A}),n.d(t,"e",function(){return w}),n.d(t,"i",function(){return R}),n.d(t,"h",function(){return N}),n.d(t,"j",function(){return I}),n.d(t,"q",function(){return L}),n.d(t,"p",function(){return j}),n.d(t,"n",function(){return W}),n.d(t,"m",function(){return F}),n.d(t,"g",function(){return $}),n.d(t,"r",function(){return Z}),n.d(t,"k",function(){return x}),n.d(t,"o",function(){return H}),n.d(t,"l",function(){return O}),n.d(t,"f",function(){return T}),n.d(t,"a",function(){return k}),n.d(t,"b",function(){return C});var i=n(31),a=n(80),r=n(1),o=n(5),s=n(47),l=n(35),c=n(0),u=n(12),p=n(3),m=n(9),h=n(21),d=n(14),g=n(40),_=n(16),y=n(29),f=n(2),b=n(27),E=n(23),v=n(22),k={LimitBuy:"Limit Buy Order",LimitSell:"Limit Sell Order",StopBuy:"Stop Buy Order",StopSell:"Stop Sell Order"},C={Long:"L",Short:"S"};function O(e,t,n,a,r,o=null){var s=o instanceof l.b,c=new M(e,t,n,a,r);if(isNaN(t)||isNaN(n))return s?o.scriptRef.log("ERROR: Invalid numeric value provided for either 'shares' or 'price' argument"):Object(m.dialogBoxCreate)("ERROR: Invalid numeric value provided for either 'shares' or 'price' argument"),!1;if(null==P.Orders){var u={};for(var p in P)if(P.hasOwnProperty(p)){if(!((e=P[p])instanceof i.Stock))continue;u[e.symbol]=[]}P.Orders=u}return P.Orders[e.symbol].push(c),U(c.stock,c.type,c.pos),ee(c.stock),!0}function T(e,t=null){var n=t instanceof l.b;if(null==P.Orders)return!1;if(e.order&&e.order instanceof M){for(var a=e.order,r=P.Orders[a.stock.symbol],o=0;oe.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 i=e.playerShares*e.playerAvgPx;c.a.loseMoney(n+r.CONSTANTS.StockMarketCommission);var a=i+n;return e.playerShares=Math.round(e.playerShares+t),e.playerAvgPx=a/e.playerShares,Z(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 B(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),Z(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 i=n instanceof l.b;if(0===(t=Math.round(t))||t<0)return!1;if(null==e||isNaN(t))return i?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 a=e.price*t;if(c.a.money.lt(a+r.CONSTANTS.StockMarketCommission))return i?n.scriptRef.log("ERROR: shortStock() failed because you do not have enough money to purchase this short position. You need "+p.numeralWrapper.format(a+r.CONSTANTS.StockMarketCommission,"($0.000a)")+"."):Object(m.dialogBoxCreate)("You do not have enough money to purchase this short position. You need "+p.numeralWrapper.format(a+r.CONSTANTS.StockMarketCommission,"($0.000a)")+"."),!1;if(t+e.playerShares+e.playerShortShares>e.maxShares)return i?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(a+r.CONSTANTS.StockMarketCommission);var s=o+a;return e.playerShortShares=Math.round(e.playerShortShares+t),e.playerAvgShortPx=s/e.playerShortShares,Z(e),i?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 W(e,t,n=null){var i=n instanceof l.b;if(null==e||isNaN(t)||t<0)return i?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 a=t*e.playerAvgShortPx,o=(e.playerAvgShortPx-e.price)*t-r.CONSTANTS.StockMarketCommission;return isNaN(o)&&(o=0),c.a.gainMoney(a+o),c.a.recordMoneySource(o,"stock"),i&&(n.scriptRef.onlineMoneyMade+=o,c.a.scriptProdSinceLastAug+=o),e.playerShortShares=Math.round(e.playerShortShares-t),0===e.playerShortShares&&(e.playerAvgShortPx=0),Z(e),i?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(a+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(a+o,"($0.000a)")+"."),!0}function F(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 U(e,t,n){var a=P.Orders;if(null!=a){var r=a[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 i.Stock))continue;l[e.symbol]=[]}P.Orders=l}}function H(e){G=e}var G=!1,K=!1,q=r.CONSTANTS.StockMarketCommission;function $(){function e(e,t,n,i,a){e.innerText=i,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=a,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,N(),I(),c.a.loseMoney(r.CONSTANTS.WSEAccountCost),$(),!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),$(),!1});var o=Object(h.clearEventListeners)("stock-market-buy-4s-data");e(o,Object(a.getStockMarket4SDataCost)(),c.a.has4SData,"Buy 4S Market Data Access - "+p.numeralWrapper.format(Object(a.getStockMarket4SDataCost)(),"($0.000a)"),"4S Market Data - Purchased"),o.addEventListener("click",function(){return!c.a.money.lt(Object(a.getStockMarket4SDataCost)())&&(c.a.has4SData=!0,c.a.loseMoney(Object(a.getStockMarket4SDataCost)()),$(),!1)}),o.appendChild(Object(f.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(a.getStockMarket4STixApiCost)(),c.a.has4SDataTixApi,"Buy 4S Market Data TIX API Access - "+p.numeralWrapper.format(Object(a.getStockMarket4STixApiCost)(),"($0.000a)"),"4S Market Data TIX API - Purchased"),c.a.hasTixApiAccess?(l.addEventListener("click",function(){return!c.a.money.lt(Object(a.getStockMarket4STixApiCost)())&&(c.a.has4SDataTixApi=!0,c.a.loseMoney(Object(a.getStockMarket4STixApiCost)()),$(),!1)}),l.appendChild(Object(f.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(f.createElement)("span",{class:"tooltiptext",innerText:"Requires TIX API Access"}))),null!=(v=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"),E=document.getElementById("stock-market-watchlist-filter-update");if(!c.a.hasWseAccount){for(G=!1;v.firstChild;)v.removeChild(v.firstChild);return u.style.visibility="hidden",d.style.visibility="hidden",g.style.visibility="hidden",_.style.visibility="hidden",b.style.visibility="hidden",void(E.style.visibility="hidden")}if(u.style.visibility="visible",d.style.visibility="visible",g.style.visibility="visible",_.style.visibility="visible",b.style.visibility="visible",E.style.visibility="visible",!G&&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&&(K=!1,d.innerHTML="Switch to 'Portfolio' ModeDisplays only the stocks for which you have shares or orders",d.addEventListener("click",Y));var v=document.getElementById("stock-market-list");g&&g.addEventListener("click",()=>{for(var e=v.getElementsByClassName("accordion-header"),t=0;t{for(var e=v.getElementsByClassName("accordion-header"),t=0;t{let e=b.value.toString();P.watchlistFilter=e.replace(/\s/g,""),K?Y():z()}),b.addEventListener("keyup",e=>{e.preventDefault(),e.keyCode===y.KEY.ENTER&&E.click()})):console.warn("Stock Market Watchlist DOM elements could not be found"),V(),G=!0}if(c.a.hasWseAccount)for(var k in P)if(P.hasOwnProperty(k)){var C=P[k];C instanceof i.Stock&&(Q(C,null),ee(C))}}}function Y(){K=!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",z)),V()}function z(){K=!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",Y)),V()}function V(){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 a in P)if(P.hasOwnProperty(a)){if(!((o=P[a])instanceof i.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 a in P)if(P.hasOwnProperty(a)){var o;if(!((o=P[a])instanceof i.Stock))continue;if(r&&!r.includes(o.symbol))continue;let e=t[o.symbol];if(K&&0===o.playerShares&&0===o.playerShortShares&&0===e.length)continue;J(o)}X()}function J(e){if(e instanceof i.Stock){var t="stock-market-ticker-"+e.symbol,n=document.createElement("li"),a=document.createElement("button");a.classList.add("accordion-header"),a.setAttribute("id",t+"-hdr"),a.innerHTML=e.name+" - "+e.symbol+" - "+p.numeralWrapper.format(e.price,"($0.000a)");var r=document.createElement("div");r.classList.add("accordion-panel"),r.setAttribute("id",t+"-panel");var o=document.createElement("input"),l=document.createElement("select"),u=document.createElement("select"),h=document.createElement("span"),d=document.createElement("span"),g=document.createElement("span"),_=document.createElement("span"),y=document.createElement("p"),f=document.createElement("ul");o.classList.add("stock-market-input"),o.placeholder="Quantity (Shares)",o.setAttribute("id",t+"-qty-input"),o.setAttribute("onkeydown","return ( event.ctrlKey || event.altKey || (4734 && event.keyCode<40) || (event.keyCode==46) )"),l.classList.add("stock-market-input"),l.setAttribute("id",t+"-pos-selector");var b=document.createElement("option");if(b.text="Long",l.add(b),8===c.a.bitNodeN||s.f&&s.h>=2){var E=document.createElement("option");E.text="Short",l.add(E)}u.classList.add("stock-market-input"),u.setAttribute("id",t+"-order-selector");var T=document.createElement("option");if(T.text="Market Order",u.add(T),8===c.a.bitNodeN||s.f&&s.h>=3){var S=document.createElement("option");S.text="Limit Order",u.add(S);var M=document.createElement("option");M.text="Stop Order",u.add(M)}h.classList.add("stock-market-input"),h.classList.add("a-link-button"),h.innerHTML="Buy",h.addEventListener("click",()=>{var n=l.options[l.selectedIndex].text;n="Long"===n?C.Long:C.Short;var i=u.options[u.selectedIndex].text,a=Number(document.getElementById(t+"-qty-input").value);if(isNaN(a))return!1;switch(i){case"Market Order":n===C.Long?D(e,a):j(e,a,null);break;case"Limit Order":case"Stop Order":var r=Object(v.yesNoTxtInpBoxGetYesButton)(),o=Object(v.yesNoTxtInpBoxGetNoButton)();r.innerText="Place Buy "+i,o.innerText="Cancel Order",r.addEventListener("click",()=>{var t,r=Number(Object(v.yesNoTxtInpBoxGetInput)());t="Limit Order"===i?k.LimitBuy:k.StopBuy,O(e,a,r,t,n),Object(v.yesNoTxtInpBoxClose)()}),o.addEventListener("click",()=>{Object(v.yesNoTxtInpBoxClose)()}),Object(v.yesNoTxtInpBoxCreate)("Enter the price for your "+i);break;default:console.log("ERROR: Invalid order type")}return!1}),d.classList.add("stock-market-input"),d.classList.add("a-link-button"),d.innerHTML="Sell",d.addEventListener("click",()=>{var n=l.options[l.selectedIndex].text;n="Long"===n?C.Long:C.Short;var i=u.options[u.selectedIndex].text,a=Number(document.getElementById(t+"-qty-input").value);if(isNaN(a))return!1;switch(i){case"Market Order":n===C.Long?B(e,a):W(e,a,null);break;case"Limit Order":case"Stop Order":var r=Object(v.yesNoTxtInpBoxGetYesButton)(),o=Object(v.yesNoTxtInpBoxGetNoButton)();r.innerText="Place Sell "+i,o.innerText="Cancel Order",r.addEventListener("click",()=>{var t,r=Number(Object(v.yesNoTxtInpBoxGetInput)());t="Limit Order"===i?k.LimitSell:k.StopSell,Object(v.yesNoTxtInpBoxClose)(),O(e,a,r,t,n)}),o.addEventListener("click",()=>{Object(v.yesNoTxtInpBoxClose)()}),Object(v.yesNoTxtInpBoxCreate)("Enter the price for your "+i);break;default:console.log("ERROR: Invalid order type")}return!1}),g.classList.add("stock-market-input"),g.classList.add("a-link-button"),g.innerHTML="Buy MAX",g.addEventListener("click",()=>{var t=l.options[l.selectedIndex].text;t="Long"===t?C.Long:C.Short;var n=u.options[u.selectedIndex].text,i=c.a.money.toNumber();switch(n){case"Market Order":var a=Math.floor((i-q)/e.price);a=Math.min(a,Math.round(e.maxShares-e.playerShares-e.playerShortShares)),t===C.Long?D(e,a):j(e,a,null);break;case"Limit Order":case"Stop Order":var r=Object(v.yesNoTxtInpBoxGetYesButton)(),o=Object(v.yesNoTxtInpBoxGetNoButton)();r.innerText="Place Buy "+n,o.innerText="Cancel Order",r.addEventListener("click",()=>{var a,r=Number(Object(v.yesNoTxtInpBoxGetInput)());a="Limit Order"===n?k.LimitBuy:k.StopBuy;var o=Math.floor((i-q)/r);o=Math.min(o,Math.round(e.maxShares-e.playerShares-e.playerShortShares)),O(e,o,r,a,t),Object(v.yesNoTxtInpBoxClose)()}),o.addEventListener("click",()=>{Object(v.yesNoTxtInpBoxClose)()}),Object(v.yesNoTxtInpBoxCreate)("Enter the price for your "+n);break;default:console.log("ERROR: Invalid order type")}return!1}),_.classList.add("stock-market-input"),_.classList.add("a-link-button"),_.innerHTML="Sell ALL",_.addEventListener("click",()=>{var t=l.options[l.selectedIndex].text;switch(t="Long"===t?C.Long:C.Short,u.options[u.selectedIndex].text){case"Market Order":if(t===C.Long){var n=e.playerShares;B(e,n)}else{n=e.playerShortShares;W(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,f.setAttribute("id",t+"-order-list"),f.classList.add("stock-market-order-list"),r.appendChild(o),r.appendChild(l),r.appendChild(u),r.appendChild(h),r.appendChild(d),r.appendChild(g),r.appendChild(_),r.appendChild(y),r.appendChild(f),n.appendChild(a),n.appendChild(r),document.getElementById("stock-market-list").appendChild(n),Q(e,!0),Z(e),ee(e)}else console.log("Invalid stock in createStockSticker()")}function X(){var e=document.getElementById("stock-market-list").getElementsByClassName("accordion-header");if(null!=e)for(var t=0;t0||e.playerShortShares>0)&&Z(e);var a=document.getElementById(n+"-hdr");if(null==a){if(!K){let t=P.watchlistFilter;""!==t&&t.includes(e.symbol)&&console.log("ERROR: Couldn't find ticker element for stock: "+e.symbol)}return}let r=e.name+" ("+e.symbol+") - "+p.numeralWrapper.format(e.price,"($0.000a)");c.a.has4SData&&(r+=" - Volatility: "+p.numeralWrapper.format(e.mv,"0,0.00")+"% - Price Forecast: ",e.b?r+="+".repeat(Math.floor(e.otlkMag/10)+1):r+="-".repeat(Math.floor(e.otlkMag/10)+1)),a.innerText=r,null!=t&&(a.style.color=t?"#66ff33":"red")}function Z(e){if(!u.routing.isOn(u.Page.StockMarket))return;if(!(e instanceof i.Stock))return console.log("Invalid stock in updateStockPlayerPosition():"),void console.log(e);var t="stock-market-ticker-"+e.symbol;if(K){if(0===e.playerShares&&0===e.playerShortShares&&P.Orders&&P.Orders[e.symbol]&&0===P.Orders[e.symbol].length)return Object(E.removeElementById)(t+"-hdr"),void Object(E.removeElementById)(t+"-panel");if(null==document.getElementById(t+"-hdr"))return J(e),void X()}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 a=(e.price-e.playerAvgPx)*e.playerShares,r=a/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(a,"$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 ee(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 i=P.Orders;if(null!=i){var a=i[e.symbol];if(null!=a){if(K){if(0===e.playerShares&&0===e.playerShortShares&&P.Orders&&P.Orders[e.symbol]&&0===P.Orders[e.symbol].length)return Object(E.removeElementById)(t+"-hdr"),void Object(E.removeElementById)(t+"-panel");if(null==document.getElementById(t+"-hdr"))return J(e),void X()}for(;n.firstChild;)n.removeChild(n.firstChild);for(var r=0;r
Starting cost: "+a.numeralWrapper.format(t.IndustryStartingCosts.Energy,"$0.000a")+"
Recommended starting Industry: NO",Utilities:"Distributes water and provides wastewater services.

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

Starting cost: "+a.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: "+a.numeralWrapper.format(t.IndustryStartingCosts.Fishing,"$0.000a")+"
Recommended starting Industry: NO",Mining:"Extract and process metals from the earth.

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

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

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

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

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

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

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

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

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

Starting cost: "+a.numeralWrapper.format(t.IndustryStartingCosts.RealEstate,"$0.000a")+"
Recommended starting Industry: NO"},t.IndustryResearchTrees={Energy:i.getBaseResearchTreeCopy(),Utilities:i.getBaseResearchTreeCopy(),Agriculture:i.getBaseResearchTreeCopy(),Fishing:i.getBaseResearchTreeCopy(),Mining:i.getBaseResearchTreeCopy(),Food:i.getBaseResearchTreeCopy(),Tobacco:i.getBaseResearchTreeCopy(),Chemical:i.getBaseResearchTreeCopy(),Pharmaceutical:i.getBaseResearchTreeCopy(),Computer:i.getBaseResearchTreeCopy(),Robotics:i.getBaseResearchTreeCopy(),Software:i.getBaseResearchTreeCopy(),Healthcare:i.getBaseResearchTreeCopy(),RealEstate:i.getBaseResearchTreeCopy()},t.resetIndustryResearchTrees=function(){t.IndustryResearchTrees.Energy=i.getBaseResearchTreeCopy(),t.IndustryResearchTrees.Utilities=i.getBaseResearchTreeCopy(),t.IndustryResearchTrees.Agriculture=i.getBaseResearchTreeCopy(),t.IndustryResearchTrees.Fishing=i.getBaseResearchTreeCopy(),t.IndustryResearchTrees.Mining=i.getBaseResearchTreeCopy(),t.IndustryResearchTrees.Food=i.getBaseResearchTreeCopy(),t.IndustryResearchTrees.Tobacco=i.getBaseResearchTreeCopy(),t.IndustryResearchTrees.Chemical=i.getBaseResearchTreeCopy(),t.IndustryResearchTrees.Pharmaceutical=i.getBaseResearchTreeCopy(),t.IndustryResearchTrees.Computer=i.getBaseResearchTreeCopy(),t.IndustryResearchTrees.Robotics=i.getBaseResearchTreeCopy(),t.IndustryResearchTrees.Software=i.getBaseResearchTreeCopy(),t.IndustryResearchTrees.Healthcare=i.getBaseResearchTreeCopy(),t.IndustryResearchTrees.RealEstate=i.getBaseResearchTreeCopy()}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const i=n(21);t.MainMenuLinks={Terminal:null,ScriptEditor:null,ActiveScripts:null,CreateProgram:null,Stats:null,Factions:null,Augmentations:null,HacknetNodes:null,Sleeves:null,City:null,Travel:null,Job:null,StockMarket:null,Bladeburner:null,Corporation:null,Gang:null,Tutorial:null,Options:null,DevMenu:null},t.initializeMainMenuLinks=function(){try{function e(e){const t=i.clearEventListeners(e);if(null==t)throw new Error(`clearEventListeners() failed for element with id: ${e}`);return t}return t.MainMenuLinks.Terminal=e("terminal-menu-link"),t.MainMenuLinks.ScriptEditor=e("create-script-menu-link"),t.MainMenuLinks.ActiveScripts=e("active-scripts-menu-link"),t.MainMenuLinks.CreateProgram=e("create-program-menu-link"),t.MainMenuLinks.Stats=e("stats-menu-link"),t.MainMenuLinks.Factions=e("factions-menu-link"),t.MainMenuLinks.Augmentations=e("augmentations-menu-link"),t.MainMenuLinks.HacknetNodes=e("hacknet-nodes-menu-link"),t.MainMenuLinks.Sleeves=e("sleeves-menu-link"),t.MainMenuLinks.City=e("city-menu-link"),t.MainMenuLinks.Travel=e("travel-menu-link"),t.MainMenuLinks.Job=e("job-menu-link"),t.MainMenuLinks.StockMarket=e("stock-market-menu-link"),t.MainMenuLinks.Bladeburner=e("bladeburner-menu-link"),t.MainMenuLinks.Corporation=e("corporation-menu-link"),t.MainMenuLinks.Gang=e("gang-menu-link"),t.MainMenuLinks.Tutorial=e("tutorial-menu-link"),t.MainMenuLinks.Options=document.getElementById("options-menu-link"),t.MainMenuLinks.DevMenu=e("dev-menu-link"),!0}catch(e){return console.error(`Failed to initialize Main Menu Links: ${e}`),!1}}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const i=n(48),a=n(62);t.removeChildrenFromElement=function(e){if(null!==e)try{const t=i.isString(e)?a.getElementById(e):e;if(t instanceof Element)for(;null!==t.firstChild;)t.removeChild(t.firstChild)}catch(e){return void console.debug(e)}}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const i=n(242),a=n(241);t.Programs={};for(const e of a.programsMetadata)t.Programs[e.key]=new i.Program(e.name,e.create)},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.KEY={A:65,B:66,C:67,CTRL:17,D:68,DOWNARROW:40,E:69,ENTER:13,ESC:27,F:70,H:72,J:74,K:75,L:76,M:77,N:78,O:79,P:80,R:82,S:83,TAB:9,U:85,UPARROW:38,W:87,1:49,2:50}},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 i=n(14),a=n(16);class r{static fromJSON(e){return i.Generic_fromJSON(r,e.data)}constructor(e="",t="",n=1,i=!0,r=0,o=1e4,s=1e12){this.name=e,this.symbol=t,this.price=o,this.playerShares=0,this.playerAvgPx=0,this.playerShortShares=0,this.playerAvgShortPx=0,this.mv=n,this.b=i,this.otlkMag=r,this.cap=a.getRandomInt(1e3*o,25e3*o);let l=s/o;this.totalShares=1e5*Math.round(l/1e5);this.maxShares=1e5*Math.round(.2*this.totalShares/1e5),this.posTxtEl=null}toJSON(){return i.Generic_toJSON("Stock",this)}}t.Stock=r,i.Reviver.constructors.Stock=r},function(module,__webpack_exports__,__webpack_require__){"use strict";(function($){__webpack_require__.d(__webpack_exports__,"d",function(){return getCurrentEditor}),__webpack_require__.d(__webpack_exports__,"h",function(){return updateScriptEditorContent}),__webpack_require__.d(__webpack_exports__,"f",function(){return loadAllRunningScripts}),__webpack_require__.d(__webpack_exports__,"c",function(){return findRunningScript}),__webpack_require__.d(__webpack_exports__,"a",function(){return RunningScript}),__webpack_require__.d(__webpack_exports__,"b",function(){return Script}),__webpack_require__.d(__webpack_exports__,"g",function(){return scriptEditorInit}),__webpack_require__.d(__webpack_exports__,"e",function(){return isScriptFilename});var _Constants__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(1),_Constants__WEBPACK_IMPORTED_MODULE_0___default=__webpack_require__.n(_Constants__WEBPACK_IMPORTED_MODULE_0__),_engine__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(10),_Fconf__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(52),_InteractiveTutorial__WEBPACK_IMPORTED_MODULE_3__=__webpack_require__(37),_NetscriptEvaluator__WEBPACK_IMPORTED_MODULE_4__=__webpack_require__(7),_NetscriptFunctions__WEBPACK_IMPORTED_MODULE_5__=__webpack_require__(47),_NetscriptWorker__WEBPACK_IMPORTED_MODULE_6__=__webpack_require__(35),_Player__WEBPACK_IMPORTED_MODULE_7__=__webpack_require__(0),_ScriptEditor_Ace__WEBPACK_IMPORTED_MODULE_8__=__webpack_require__(96),_ScriptEditor_CodeMirror__WEBPACK_IMPORTED_MODULE_9__=__webpack_require__(95),_Server__WEBPACK_IMPORTED_MODULE_10__=__webpack_require__(11),_Settings_Settings__WEBPACK_IMPORTED_MODULE_11__=__webpack_require__(18),_Settings_Settings__WEBPACK_IMPORTED_MODULE_11___default=__webpack_require__.n(_Settings_Settings__WEBPACK_IMPORTED_MODULE_11__),_Settings_SettingEnums__WEBPACK_IMPORTED_MODULE_12__=__webpack_require__(43),_Settings_SettingEnums__WEBPACK_IMPORTED_MODULE_12___default=__webpack_require__.n(_Settings_SettingEnums__WEBPACK_IMPORTED_MODULE_12__),_ui_postToTerminal__WEBPACK_IMPORTED_MODULE_13__=__webpack_require__(8),_ui_postToTerminal__WEBPACK_IMPORTED_MODULE_13___default=__webpack_require__.n(_ui_postToTerminal__WEBPACK_IMPORTED_MODULE_13__),_TextFile__WEBPACK_IMPORTED_MODULE_14__=__webpack_require__(75),_TextFile__WEBPACK_IMPORTED_MODULE_14___default=__webpack_require__.n(_TextFile__WEBPACK_IMPORTED_MODULE_14__),_utils_acorn__WEBPACK_IMPORTED_MODULE_15__=__webpack_require__(55),_utils_acorn__WEBPACK_IMPORTED_MODULE_15___default=__webpack_require__.n(_utils_acorn__WEBPACK_IMPORTED_MODULE_15__),_ui_navigationTracking__WEBPACK_IMPORTED_MODULE_16__=__webpack_require__(12),_ui_navigationTracking__WEBPACK_IMPORTED_MODULE_16___default=__webpack_require__.n(_ui_navigationTracking__WEBPACK_IMPORTED_MODULE_16__),_ui_numeralFormat__WEBPACK_IMPORTED_MODULE_17__=__webpack_require__(3),_ui_numeralFormat__WEBPACK_IMPORTED_MODULE_17___default=__webpack_require__.n(_ui_numeralFormat__WEBPACK_IMPORTED_MODULE_17__),_utils_SetTimeoutRef__WEBPACK_IMPORTED_MODULE_18__=__webpack_require__(56),_utils_SetTimeoutRef__WEBPACK_IMPORTED_MODULE_18___default=__webpack_require__.n(_utils_SetTimeoutRef__WEBPACK_IMPORTED_MODULE_18__),_utils_DialogBox__WEBPACK_IMPORTED_MODULE_19__=__webpack_require__(9),_utils_JSONReviver__WEBPACK_IMPORTED_MODULE_20__=__webpack_require__(14),_utils_helpers_compareArrays__WEBPACK_IMPORTED_MODULE_21__=__webpack_require__(111),_utils_helpers_compareArrays__WEBPACK_IMPORTED_MODULE_21___default=__webpack_require__.n(_utils_helpers_compareArrays__WEBPACK_IMPORTED_MODULE_21__),_utils_uiHelpers_createElement__WEBPACK_IMPORTED_MODULE_22__=__webpack_require__(2),_utils_uiHelpers_createElement__WEBPACK_IMPORTED_MODULE_22___default=__webpack_require__.n(_utils_uiHelpers_createElement__WEBPACK_IMPORTED_MODULE_22__),_utils_helpers_getTimestamp__WEBPACK_IMPORTED_MODULE_23__=__webpack_require__(105),_utils_helpers_getTimestamp__WEBPACK_IMPORTED_MODULE_23___default=__webpack_require__.n(_utils_helpers_getTimestamp__WEBPACK_IMPORTED_MODULE_23__),_utils_helpers_roundToTwo__WEBPACK_IMPORTED_MODULE_24__=__webpack_require__(99),_utils_helpers_roundToTwo__WEBPACK_IMPORTED_MODULE_24___default=__webpack_require__.n(_utils_helpers_roundToTwo__WEBPACK_IMPORTED_MODULE_24__);const walk=__webpack_require__(180);function isScriptFilename(e){return e.endsWith(".js")||e.endsWith(".script")||e.endsWith(".ns")}var scriptEditorRamCheck=null,scriptEditorRamText=null;function scriptEditorInit(){const e=document.getElementById("script-editor-buttons-wrapper");if(null==e)return console.error("Could not find 'script-editor-buttons-wrapper'"),!1;const t=Object(_utils_uiHelpers_createElement__WEBPACK_IMPORTED_MODULE_22__.createElement)("button",{class:"std-button",display:"inline-block",innerText:"Beautify",clickListener:()=>{let e=getCurrentEditor();return null!=e&&e.beautifyScript(),!1}});scriptEditorRamText=Object(_utils_uiHelpers_createElement__WEBPACK_IMPORTED_MODULE_22__.createElement)("p",{display:"inline-block",margin:"10px",id:"script-editor-status-text"});const n=Object(_utils_uiHelpers_createElement__WEBPACK_IMPORTED_MODULE_22__.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"});(scriptEditorRamCheck=Object(_utils_uiHelpers_createElement__WEBPACK_IMPORTED_MODULE_22__.createElement)("input",{type:"checkbox",name:"script-editor-ram-check",id:"script-editor-ram-check",margin:"4px",marginTop:"8px"})).checked=!0;const i=Object(_utils_uiHelpers_createElement__WEBPACK_IMPORTED_MODULE_22__.createElement)("a",{class:"std-button",display:"inline-block",href:"https://bitburner.readthedocs.io/en/latest/index.html",innerText:"Netscript Documentation",target:"_blank"}),a=Object(_utils_uiHelpers_createElement__WEBPACK_IMPORTED_MODULE_22__.createElement)("button",{class:"std-button",display:"inline-block",innerText:"Save & Close (Ctrl/Cmd + b)",clickListener:()=>(saveAndCloseScriptEditor(),!1)});e.appendChild(t),e.appendChild(a),e.appendChild(scriptEditorRamText),e.appendChild(scriptEditorRamCheck),e.appendChild(n),e.appendChild(i);const r={saveAndCloseFn:saveAndCloseScriptEditor,quitFn:_engine__WEBPACK_IMPORTED_MODULE_1__.Engine.loadTerminalContent};_ScriptEditor_Ace__WEBPACK_IMPORTED_MODULE_8__.a.init(r),_ScriptEditor_CodeMirror__WEBPACK_IMPORTED_MODULE_9__.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 _Settings_SettingEnums__WEBPACK_IMPORTED_MODULE_12__.EditorSetting.Ace:const t=_ScriptEditor_CodeMirror__WEBPACK_IMPORTED_MODULE_9__.a.getCode(),n=_ScriptEditor_CodeMirror__WEBPACK_IMPORTED_MODULE_9__.a.getFilename();_ScriptEditor_Ace__WEBPACK_IMPORTED_MODULE_8__.a.create(),_ScriptEditor_CodeMirror__WEBPACK_IMPORTED_MODULE_9__.a.setInvisible(),_ScriptEditor_Ace__WEBPACK_IMPORTED_MODULE_8__.a.openScript(n,t);break;case _Settings_SettingEnums__WEBPACK_IMPORTED_MODULE_12__.EditorSetting.CodeMirror:const i=_ScriptEditor_Ace__WEBPACK_IMPORTED_MODULE_8__.a.getCode(),a=_ScriptEditor_Ace__WEBPACK_IMPORTED_MODULE_8__.a.getFilename();_ScriptEditor_CodeMirror__WEBPACK_IMPORTED_MODULE_9__.a.create(),_ScriptEditor_Ace__WEBPACK_IMPORTED_MODULE_8__.a.setInvisible(),_ScriptEditor_CodeMirror__WEBPACK_IMPORTED_MODULE_9__.a.openScript(a,i);break;default:return void console.error(`Unrecognized Editor Setting: ${e}`)}_Settings_Settings__WEBPACK_IMPORTED_MODULE_11__.Settings.Editor=e}),o.onchange()}function getCurrentEditor(){switch(_Settings_Settings__WEBPACK_IMPORTED_MODULE_11__.Settings.Editor){case _Settings_SettingEnums__WEBPACK_IMPORTED_MODULE_12__.EditorSetting.Ace:return _ScriptEditor_Ace__WEBPACK_IMPORTED_MODULE_8__.a;case _Settings_SettingEnums__WEBPACK_IMPORTED_MODULE_12__.EditorSetting.CodeMirror:return _ScriptEditor_CodeMirror__WEBPACK_IMPORTED_MODULE_9__.a;default:throw console.log(`Invalid Editor Setting: ${_Settings_Settings__WEBPACK_IMPORTED_MODULE_11__.Settings.Editor}`),new Error(`Invalid Editor Setting: ${_Settings_Settings__WEBPACK_IMPORTED_MODULE_11__.Settings.Editor}`)}}async function updateScriptEditorContent(){var e=document.getElementById("script-editor-filename").value;if(null==scriptEditorRamCheck||!scriptEditorRamCheck.checked||!isScriptFilename(e))return void(scriptEditorRamText.innerText="N/A");let t;try{t=getCurrentEditor().getCode()}catch(e){return void(scriptEditorRamText.innerText="RAM: ERROR")}var n=t.repeat(1),i=await calculateRamUsage(n);scriptEditorRamText.innerText=-1!==i?"RAM: "+_ui_numeralFormat__WEBPACK_IMPORTED_MODULE_17__.numeralWrapper.format(i,"0.00")+" GB":"RAM: Syntax Error"}function saveAndCloseScriptEditor(){var e=document.getElementById("script-editor-filename").value;let t;try{t=getCurrentEditor().getCode()}catch(e){return void Object(_utils_DialogBox__WEBPACK_IMPORTED_MODULE_19__.dialogBoxCreate)("Something went wrong when trying to save (getCurrentEditor().getCode()). Please report to game developer with details")}if(_InteractiveTutorial__WEBPACK_IMPORTED_MODULE_3__.a.isRunning&&_InteractiveTutorial__WEBPACK_IMPORTED_MODULE_3__.a.currStep===_InteractiveTutorial__WEBPACK_IMPORTED_MODULE_3__.d.TerminalTypeScript){if("foodnstuff.script"!==e)return void Object(_utils_DialogBox__WEBPACK_IMPORTED_MODULE_19__.dialogBoxCreate)("Leave the script name as 'foodnstuff'!");if(-1==(t=t.replace(/\s/g,"")).indexOf("while(true){hack('foodnstuff');}"))return void Object(_utils_DialogBox__WEBPACK_IMPORTED_MODULE_19__.dialogBoxCreate)("Please copy and paste the code from the tutorial!");let i=_Player__WEBPACK_IMPORTED_MODULE_7__.a.getCurrentServer();for(var n=0;n0;){const nextModule=parseQueue.shift();let code;if(nextModule.startsWith("https://")||nextModule.startsWith("http://"))try{const module=await eval("import(nextModule)");code="";for(const e in module)"function"==typeof module[e]&&(code+=module[e].toString()+";\n")}catch(e){return console.error(`Error dynamically importing module from ${nextModule} for RAM calculations: ${e}`),-1}else{const e=server.getScript(nextModule.startsWith("./")?nextModule.slice(2):nextModule);if(!e)return console.warn("Invalid script"),-1;code=e.code}parseCode(code,nextModule)}let ram=_Constants__WEBPACK_IMPORTED_MODULE_0__.CONSTANTS.ScriptBaseRamCost;const unresolvedRefs=Object.keys(dependencyMap).filter(e=>e.startsWith(initialModule)),resolvedRefs=new Set;for(;unresolvedRefs.length>0;){const e=unresolvedRefs.shift();if("hacknet"!==e||resolvedRefs.has("hacknet")||(ram+=_Constants__WEBPACK_IMPORTED_MODULE_0__.CONSTANTS.ScriptHacknetNodesRamCost),"document"!==e||resolvedRefs.has("document")||(ram+=_Constants__WEBPACK_IMPORTED_MODULE_0__.CONSTANTS.ScriptDomRamCost),"window"!==e||resolvedRefs.has("window")||(ram+=_Constants__WEBPACK_IMPORTED_MODULE_0__.CONSTANTS.ScriptDomRamCost),resolvedRefs.add(e),e.endsWith(".*")){const t=e.slice(0,e.length-2);for(let e of Object.keys(dependencyMap).filter(e=>e.startsWith(t)))for(let t of dependencyMap[e]||[])resolvedRefs.has(t)||unresolvedRefs.push(t)}else for(let t of dependencyMap[e]||[])resolvedRefs.has(t)||unresolvedRefs.push(t);try{function applyFuncRam(e){if("function"!=typeof e)return 0;try{let t;return"number"==typeof(t="AsyncFunction"===e.constructor.name?0:e.apply(null,[]))?t:0}catch(e){return console.log("ERROR applying function: "+e),0}}var func;func=e in workerScript.env.vars.bladeburner?workerScript.env.vars.bladeburner[e]:e in workerScript.env.vars.codingcontract?workerScript.env.vars.codingcontract[e]:e in workerScript.env.vars.gang?workerScript.env.vars.gang[e]:workerScript.env.get(e),ram+=applyFuncRam(func)}catch(e){continue}}return ram}catch(e){return-1}}function parseOnlyCalculateDeps(e,t){const n=Object(_utils_acorn__WEBPACK_IMPORTED_MODULE_15__.parse)(e,{sourceType:"module",ecmaVersion:8}),i=t+memCheckGlobalKey,a={};a[i]=new Set;let r={};var o=[];function s(e,n){const i=a[e]||(a[e]=new Set);n in r&&i.add(r[n]),i.add(t+"."+n),i.add(n)}const l=Object.getOwnPropertyNames(Object.prototype);function c(){return{Identifier:(e,t,n)=>{l.includes(e.name)||s(t.key,e.name)},WhileStatement:(e,t,n)=>{s(t.key,specialReferenceWHILE),e.test&&n(e.test,t),e.body&&n(e.body,t)},DoWhileStatement:(e,t,n)=>{s(t.key,specialReferenceWHILE),e.test&&n(e.test,t),e.body&&n(e.body,t)},ForStatement:(e,t,n)=>{s(t.key,specialReferenceFOR),e.init&&n(e.init,t),e.test&&n(e.test,t),e.update&&n(e.update,t),e.body&&n(e.body,t)},IfStatement:(e,t,n)=>{s(t.key,specialReferenceIF),e.test&&n(e.test,t),e.consequent&&n(e.consequent,t),e.alternate&&n(e.alternate,t)},MemberExpression:(e,t,n)=>{e.object&&n(e.object,t),e.property&&n(e.property,t)}}}return walk.recursive(n,{key:i},Object.assign({ImportDeclaration:(e,t,n)=>{const i=e.source.value;o.push(i),a[t.key].add(i+memCheckGlobalKey);for(let n=0;n{const a=t+"."+e.id.name;walk.recursive(e,{key:a},c())}},c())),{dependencyMap:a,additionalModules:o}}async function calculateRamUsage(e){var t=_Player__WEBPACK_IMPORTED_MODULE_7__.a.getCurrentServer(),n=new _NetscriptWorker__WEBPACK_IMPORTED_MODULE_6__.b({filename:"foo",scriptRef:{code:""},args:[],getCode:function(){return""}});n.checkingRam=!0,n.serverIp=t.ip;try{return await parseOnlyRamCalculate(t,e,n)}catch(e){console.log("Failed to parse ram using new method. Falling back.",e)}try{var i=Object(_utils_acorn__WEBPACK_IMPORTED_MODULE_15__.parse)(e,{sourceType:"module"})}catch(e){return-1}var a=[],r=_Constants__WEBPACK_IMPORTED_MODULE_0__.CONSTANTS.ScriptBaseRamCost,o=!1,s=!1,l=!1;for(a.push(i);0!=a.length;){var c=a.shift();switch(c.type){case"ImportDeclaration":for(var u=Object(_NetscriptEvaluator__WEBPACK_IMPORTED_MODULE_4__.a)(c,n,!0),p=0;p=1&&(n=1),e.dataMap)if(e.dataMap.hasOwnProperty(i)){if(0==e.dataMap[i][2]||null==e.dataMap[i][2])continue;if(null==(u=_Server__WEBPACK_IMPORTED_MODULE_10__.b[i]))continue;var a=Math.round(.5*e.dataMap[i][2]/e.onlineRunningTime*t);console.log(e.filename+" called grow() on "+u.hostname+" "+a+" times while offline"),e.log("Called grow() on "+u.hostname+" "+a+" times while offline");var r=Object(_Server__WEBPACK_IMPORTED_MODULE_10__.k)(u,450*a);e.log(u.hostname+" grown by "+_ui_numeralFormat__WEBPACK_IMPORTED_MODULE_17__.numeralWrapper.format(100*r-100,"0.000000%")+" from grow() calls made while offline")}var o=0;for(var i in e.dataMap)if(e.dataMap.hasOwnProperty(i)){if(0==e.dataMap[i][0]||null==e.dataMap[i][0])continue;if(null==(u=_Server__WEBPACK_IMPORTED_MODULE_10__.b[i]))continue;var s=.5*e.dataMap[i][0]/e.onlineRunningTime*t;(s*=n)>u.moneyAvailable&&(s=u.moneyAvailable),o+=s,_Player__WEBPACK_IMPORTED_MODULE_7__.a.gainMoney(s),_Player__WEBPACK_IMPORTED_MODULE_7__.a.recordMoneySource(s,"hacking"),console.log(e.filename+" generated $"+s+" while offline by hacking "+u.hostname),e.log(e.filename+" generated $"+s+" while offline by hacking "+u.hostname),u.moneyAvailable-=s,u.moneyAvailable<0&&(u.moneyAvailable=0),isNaN(u.moneyAvailable)&&(u.moneyAvailable=0)}var l=e.onlineExpGained/e.onlineRunningTime*.5*t;for(var i in l*=n,_Player__WEBPACK_IMPORTED_MODULE_7__.a.gainHackingExp(l),e.offlineMoneyMade+=o,e.offlineRunningTime+=t,e.offlineExpGained+=l,e.dataMap)if(e.dataMap.hasOwnProperty(i)){if(0==e.dataMap[i][1]||null==e.dataMap[i][1])continue;if(null==(u=_Server__WEBPACK_IMPORTED_MODULE_10__.b[i]))continue;var c=Math.round(.5*e.dataMap[i][1]/e.onlineRunningTime*t);console.log(e.filename+" hacked "+u.hostname+" "+c+" times while offline"),e.log("Hacked "+u.hostname+" "+c+" times while offline"),u.fortify(_Constants__WEBPACK_IMPORTED_MODULE_0__.CONSTANTS.ServerFortifyAmount*c)}for(var i in e.dataMap)if(e.dataMap.hasOwnProperty(i)){if(0==e.dataMap[i][3]||null==e.dataMap[i][3])continue;var u;if(null==(u=_Server__WEBPACK_IMPORTED_MODULE_10__.b[i]))continue;var p=Math.round(.5*e.dataMap[i][3]/e.onlineRunningTime*t);console.log(e.filename+" called weaken() on "+u.hostname+" "+p+" times while offline"),e.log("Called weaken() on "+u.hostname+" "+p+" times while offline"),u.weaken(_Constants__WEBPACK_IMPORTED_MODULE_0__.CONSTANTS.ServerWeakenAmount*p)}return o}function findRunningScript(e,t,n){for(var i=0;i0)return this.ramUsage;const e=_Server__WEBPACK_IMPORTED_MODULE_10__.b[this.server];if(null==e)return 0;for(let t=0;t_Settings_Settings__WEBPACK_IMPORTED_MODULE_11__.Settings.MaxLogCapacity&&this.logs.shift();let t=e;_Fconf__WEBPACK_IMPORTED_MODULE_2__.a.ENABLE_TIMESTAMPS&&(t="["+Object(_utils_helpers_getTimestamp__WEBPACK_IMPORTED_MODULE_23__.getTimestamp)()+"] "+t),this.logs.push(t),this.logUpd=!0},RunningScript.prototype.displayLog=function(){for(var e=0;e{r=e,null!=t.CompanyPositions[r.name]&&console.warn(`Duplicate Company Position being defined: ${r.name}`),t.CompanyPositions[r.name]=new a.CompanyPosition(r)})},function(e,t,n){"use strict";(function(e){n.d(t,"a",function(){return J});var i=n(13),a=n(6),r=n(20),o=n(1),s=n(10),l=n(63),c=n(15),u=n(51),p=n(5),m=n(0),h=n(68),d=n(3),g=n(56),_=n(29),y=n(93),f=n(9),b=n(27),E=n(14),v=n(76),k=n(60),C=n(91),O=n(2),T=n(38),S=n(12),M=n(40),P=n(4),A=n(16),w=n(105),x=n(67),R=n(23);const N=["Aevum","Chongqing","Sector-12","New Tokyo","Ishima","Volhaven"],I=1e9;var L="bladeburner-active-action",D=0,B={helpList:"Use 'help [command]' to get more information about a particular Bladeburner console command.

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 j(e={}){this.name=e.name?e.name:p.Locations.Sector12,this.pop=e.pop?e.pop:Object(A.getRandomInt)(I,1.5*I),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 W(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 J))return;let r=m.a.bladeburner.consoleHistory;if(e.keyCode===_.KEY.ENTER){e.preventDefault();var t=X.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==X.consoleInput)return;var n=D;if(0===(a=r.length))return;(n<0||n>a)&&(D=a),0!==n&&--D;var i=r[D];X.consoleInput.value=i,Object(g.setTimeoutRef)(function(){X.consoleInput.selectionStart=X.consoleInput.selectionEnd=1e4},0)}if(e.keyCode===_.KEY.DOWNARROW){if(null==X.consoleInput)return;var a;n=D;if(0==(a=r.length))return;if((n<0||n>a)&&(D=a),n==a||n==a-1)D=a,X.consoleInput.value="";else{i=r[++D];X.consoleInput.value=i}}}}),j.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}},j.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))},j.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)}},j.prototype.toJSON=function(){return Object(E.Generic_toJSON)("City",this)},j.fromJSON=function(e){return Object(E.Generic_fromJSON)(j,e.data)},E.Reviver.constructors.City=j,W.prototype.calculateCost=function(e){return Math.floor((this.baseCost+e*this.costInc)*r.BitNodeMultipliers.BladeburnerSkillCost)};var F={},U={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 H(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(v.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 i 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(i)&&this.decays[i]>1)throw new Error("Invalid decays when constructing Action "+this.name+". Decay value cannot be greater than 1")}H.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},H.prototype.getSuccessChance=function(e,t={}){if(null==e)throw new Error("Invalid Bladeburner instance passed into Action.getSuccessChance");var n=this.getDifficulty(),i=0;for(var a in this.weights)if(this.weights.hasOwnProperty(a)){var r=m.a.queryStatFromString(a),o="eff"+a.charAt(0).toUpperCase()+a.slice(1),s=e.skillMultipliers[o];null==s&&(console.log("ERROR: Failed to find Bladeburner Skill multiplier for: "+a),s=1),i+=this.weights[a]*Math.pow(s*r,this.decays[a])}(i*=e.calculateStaminaPenalty(),this instanceof Y||this instanceof z)&&(this.teamCount&&this.teamCount>0&&(this.teamCount=Math.min(this.teamCount,e.teamSize),i*=Math.pow(this.teamCount,.05)));if(!(this instanceof z)){var l=e.getCurrentCity();if(t.est?i*=Math.pow(l.popEst/I,.7):i*=Math.pow(l.pop/I,.7),l.chaos>50){var c=l.chaos-50+1;n*=Math.pow(c,.1)}if(this instanceof Y&&"Raid"===this.name&&l.comms<=0)return 0}if(i*=e.skillMultipliers.successChanceAll,(this instanceof Y||this instanceof z)&&(i*=e.skillMultipliers.successChanceOperation),this instanceof $&&(i*=e.skillMultipliers.successChanceContract),this.isStealth&&(i*=e.skillMultipliers.successChanceStealth),this.isKill&&(i*=e.skillMultipliers.successChanceKill),i*=m.a.bladeburner_success_chance_mult,isNaN(i))throw new Error("Competence calculated as NaN in Action.getSuccessChance()");return Math.min(1,i/n)},H.prototype.attempt=function(e){return Math.random()=this.getSuccessesNeededForNextLevel(e)&&++this.maxLevel},H.prototype.toJSON=function(){return Object(E.Generic_toJSON)("Action",this)},H.fromJSON=function(e){return Object(E.Generic_fromJSON)(H,e.data)},E.Reviver.constructors.Action=H;var G={};const K=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 q(e={}){e.name&&(this.name=e.name),e.type&&(this.type=e.type)}function $(e={}){H.call(this,e)}function Y(e={}){H.call(this,e),this.reqdRank=e.reqdRank?e.reqdRank:100,this.teamCount=e.teamCount?e.teamCount:0}function z(e={}){Y.call(this,e),this.count=1,this.countGrowth=0}q.prototype.toJSON=function(){return Object(E.Generic_toJSON)("ActionIdentifier",this)},q.fromJSON=function(e){return Object(E.Generic_fromJSON)(q,e.data)},E.Reviver.constructors.ActionIdentifier=q,$.prototype=Object.create(H.prototype),$.prototype.toJSON=function(){return Object(E.Generic_toJSON)("Contract",this)},$.fromJSON=function(e){return Object(E.Generic_fromJSON)($,e.data)},E.Reviver.constructors.Contract=$,Y.prototype=Object.create(H.prototype),Y.prototype.toJSON=function(){return Object(E.Generic_toJSON)("Operation",this)},Y.fromJSON=function(e){return Object(E.Generic_fromJSON)(Y,e.data)},E.Reviver.constructors.Operation=Y,z.prototype=Object.create(H.prototype),z.prototype.toJSON=function(){return Object(E.Generic_toJSON)("BlackOperation",this)},z.fromJSON=function(e){return Object(E.Generic_fromJSON)(z,e.data)},E.Reviver.constructors.BlackOperation=z;var V={};function J(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=K.Idle;this.action=new q({type:t}),this.cities={};for(var n=0;n
Does NOT require stamina."}),G[e="Recruitment"]=new H({name:e,desc:"Attempt to recruit members for your Bladeburner team. These members can help you conduct operations.

Does NOT require stamina."}),G[e="Diplomacy"]=new H({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."}),G[e="Hyperbolic Regeneration Chamber"]=new H({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 gain.

"}),V["Operation Typhoon"]=new z({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}),V["Operation Zero"]=new z({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}),V["Operation X"]=new z({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}),V["Operation Titan"]=new z({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}),V["Operation Ares"]=new z({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}),V["Operation Archangel"]=new z({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}),V["Operation Juggernaut"]=new z({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}),V["Operation Red Dragon"]=new z({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}),V["Operation K"]=new z({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}),V["Operation Deckard"]=new z({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}),V["Operation Tyrell"]=new z({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}),V["Operation Wallace"]=new z({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}),V["Operation Shoulder of Orion"]=new z({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}),V["Operation Hyron"]=new z({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}),V["Operation Morpheus"]=new z({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}),V["Operation Ion Storm"]=new z({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}),V["Operation Annihilus"]=new z({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}),V["Operation Ultron"]=new z({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}),V["Operation Centurion"]=new z({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}}),V["Operation Vindictus"]=new z({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}}),V["Operation Daedalus"]=new z({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()}J.prototype.prestige=function(){this.resetAction();var e=c.Factions.Bladeburners;this.rank>=25&&Object(u.c)(e)},J.prototype.create=function(){this.contracts.Tracking=new $({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 $({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 $({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 Y({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 Y({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 Y({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 Y({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 Y({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 Y({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})},J.prototype.storeCycles=function(e=1){this.storedCycles+=e},J.prototype.process=function(){if(!1===h.b&&this.blackops.hasOwnProperty("Operation Daedalus"))return Object(h.a)(m.a.bitNodeN);if(!1===i.Augmentations[a.AugmentationNames.BladesSimulacrum].owned&&m.a.isWorking){if(this.action.type!==K.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(f.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 q({type:this.automateActionHigh.type,name:this.automateActionHigh.name}),this.startAction(this.action)))),S.routing.isOn(S.Page.Bladeburner)&&this.updateContent()}},J.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},J.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)},J.prototype.calculateStaminaPenalty=function(){return Math.min(1,this.stamina/(.5*this.maxStamina))},J.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 i=3*(this.totalSkillPoints+1);if(this.maxRank>=i){var a=Math.floor((this.maxRank-i)/3+1);this.skillPoints+=a,this.totalSkillPoints+=a}},J.prototype.getCurrentCity=function(){var e=this.cities[this.city];if(!(e instanceof j))throw new Error("Bladeburner.getCurrentCity() did not properly return a City object");return e},J.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}},J.prototype.updateSkillMultipliers=function(){for(var e in this.resetSkillMultipliers(),this.skills)if(this.skills.hasOwnProperty(e)){var t=F[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 i=Object.keys(this.skillMultipliers),a=0;a=this.actionTimeToComplete?this.completeAction():void 0}},J.prototype.completeAction=function(){switch(this.action.type){case K.Contract:case K.Operation:try{var e=this.action.type===K.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,i=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 a=0;if(e||(a=25e4*i*this.skillMultipliers.money,m.a.gainMoney(a),m.a.recordMoneySource(a,"bladeburner")),e?p.setMaxLevel(2.5):p.setMaxLevel(3),p.rankGain){var s=Object(v.addOffset)(p.rankGain*i*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(a,"$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(v.addOffset)(p.rankLoss*i,10),this.changeRank(-1*l)),p.hpLoss&&(c=p.hpLoss*n,c=Math.ceil(Object(v.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 K.BlackOp:case K.BlackOperation:try{var p;if(null==(p=this.getActionObject(this.action))||!(p instanceof z))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 y=0;if(p.rankGain&&(y=Object(v.addOffset)(p.rankGain*r.BitNodeMultipliers.BladeburnerRank,10),this.changeRank(y)),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)(y,1)+" rank")}else{this.gainActionStats(p,!1);var f=0;c=0;p.rankLoss&&(f=Object(v.addOffset)(p.rankLoss,10),this.changeRank(-1*f)),p.hpLoss&&(c=p.hpLoss*n,c=Math.ceil(Object(v.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)(f,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 K.Training:this.stamina-=.1425;var E=30*m.a.strength_exp_mult,k=30*m.a.defense_exp_mult,C=30*m.a.dexterity_exp_mult,O=30*m.a.agility_exp_mult,T=.04*this.skillMultipliers.stamina;m.a.gainStrengthExp(E),m.a.gainDefenseExp(k),m.a.gainDexterityExp(C),m.a.gainAgilityExp(O),this.staminaBonus+=T,this.logging.general&&this.log("Training completed. Gained: "+Object(P.formatNumber)(E,1)+" str exp, "+Object(P.formatNumber)(k,1)+" def exp, "+Object(P.formatNumber)(C,1)+" dex exp, "+Object(P.formatNumber)(O,1)+" agi exp, "+Object(P.formatNumber)(T,3)+" max stamina"),this.startAction(this.action);break;case K.FieldAnalysis:case K["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 K.Recruitment:var N=this.getRecruitmentSuccessChance();if(Math.random()=1){n=e?Math.ceil(i/2):Math.floor(i);var a=Object(A.getRandomInt)(0,n);this.teamSize-=a,this.teamLost+=a,this.logging.ops&&a>0&&this.log("Lost "+Object(P.formatNumber)(a,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)}},J.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))},J.prototype.getRecruitmentSuccessChance=function(){return Math.pow(m.a.charisma,.45)/(this.teamSize+1)},J.prototype.getDiplomacyEffectiveness=function(){return(100-(Math.pow(m.a.charisma,.045)+m.a.charisma/1e3))/100},J.prototype.gainActionStats=function(e,t){var n=e.getDifficulty(),i=Math.pow(n,.28)+n/650,a=this.actionTimeToComplete,r=t?1:.5,o=1*a*r*i,s=.001*a*r*i;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)},J.prototype.randomEvent=function(){var e=Math.random(),t=N[Object(A.getRandomInt)(0,5)],n=this.cities[t];if(!(n instanceof j))throw new Error("sourceCity was not a City object in Bladeburner.randomEvent()");for(var i=N[Object(A.getRandomInt)(0,5)];i===t;)i=N[Object(A.getRandomInt)(0,5)];var a=this.cities[i];if(!(n instanceof j&&a instanceof j))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,++a.comms;r=Object(A.getRandomInt)(10,20)/100,o=Math.round(n.pop*r);n.pop-=o,a.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")}},J.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),--i.comms,++n.comms);var o=Math.round(i.pop*r);i.pop-=o,n.pop+=o};var X={};J.prototype.initializeDomElementRefs=function(){X={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}},J.prototype.createContent=function(){if(X.bladeburnerDiv=Object(O.createElement)("div",{id:"bladeburner-container",position:"fixed",class:"generic-menupage-container"}),X.overviewConsoleParentDiv=Object(O.createElement)("div",{height:"60%",display:"block",position:"relative"}),X.overviewDiv=Object(O.createElement)("div",{width:"30%",display:"inline-block",border:"1px solid white"}),X.actionAndSkillsDiv=Object(O.createElement)("div",{height:"60%",width:"70%",display:"block",border:"1px solid white",margin:"6px",padding:"6px"}),X.currentTab="general",this.createOverviewContent(),this.createActionAndSkillsContent(),X.consoleDiv=Object(O.createElement)("div",{class:"bladeburner-console-div",clickListener:()=>(X.consoleInput instanceof Element&&X.consoleInput.focus(),!1)}),X.consoleTable=Object(O.createElement)("table",{class:"bladeburner-console-table"}),X.consoleInputRow=Object(O.createElement)("tr",{class:"bladeburner-console-input-row",id:"bladeubrner-console-input-row"}),X.consoleInputCell=Object(O.createElement)("td",{class:"bladeburner-console-input-cell"}),X.consoleInputHeader=Object(O.createElement)("pre",{innerText:"> "}),X.consoleInput=Object(O.createElement)("input",{type:"text",class:"bladeburner-console-input",tabIndex:1,onfocus:()=>{X.consoleInput.value=X.consoleInput.value}}),X.consoleInputCell.appendChild(X.consoleInputHeader),X.consoleInputCell.appendChild(X.consoleInput),X.consoleInputRow.appendChild(X.consoleInputCell),X.consoleTable.appendChild(X.consoleInputRow),X.consoleDiv.appendChild(X.consoleTable),X.overviewConsoleParentDiv.appendChild(X.overviewDiv),X.overviewConsoleParentDiv.appendChild(X.consoleDiv),X.bladeburnerDiv.appendChild(X.overviewConsoleParentDiv),X.bladeburnerDiv.appendChild(X.actionAndSkillsDiv),document.getElementById("entire-game-container").appendChild(X.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(f.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.")}}),X.overviewGen1=Object(O.createElement)("p",{display:"block"}),X.overviewEstPop=Object(O.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."}),X.overviewEstPopHelpTip=Object(O.createElement)("div",{innerText:"?",class:"help-tip",clickListener:()=>{Object(f.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.")}}),X.overviewEstComms=Object(O.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."}),X.overviewChaos=Object(O.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."}),X.overviewBonusTime=Object(O.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."}),X.overviewSkillPoints=Object(O.createElement)("p",{display:"block"}),X.overviewAugSuccessMult=Object(O.createElement)("p",{display:"block"}),X.overviewAugMaxStaminaMult=Object(O.createElement)("p",{display:"block"}),X.overviewAugStaminaGainMult=Object(O.createElement)("p",{display:"block"}),X.overviewAugAnalysisMult=Object(O.createElement)("p",{display:"block"}),X.overviewDiv.appendChild(X.overviewRank),Object(k.appendLineBreaks)(X.overviewDiv,1),X.overviewDiv.appendChild(X.overviewStamina),X.overviewDiv.appendChild(X.overviewStaminaHelpTip),X.overviewDiv.appendChild(X.overviewGen1),X.overviewDiv.appendChild(X.overviewEstPop),X.overviewDiv.appendChild(X.overviewEstPopHelpTip),Object(k.appendLineBreaks)(X.overviewDiv,1),X.overviewDiv.appendChild(X.overviewEstComms),Object(k.appendLineBreaks)(X.overviewDiv,1),X.overviewDiv.appendChild(X.overviewChaos),Object(k.appendLineBreaks)(X.overviewDiv,2),X.overviewDiv.appendChild(X.overviewBonusTime),X.overviewDiv.appendChild(X.overviewSkillPoints),Object(k.appendLineBreaks)(X.overviewDiv,1),X.overviewDiv.appendChild(X.overviewAugSuccessMult),X.overviewDiv.appendChild(X.overviewAugMaxStaminaMult),X.overviewDiv.appendChild(X.overviewAugStaminaGainMult),X.overviewDiv.appendChild(X.overviewAugAnalysisMult),Object(k.appendLineBreaks)(X.overviewDiv,1),X.overviewDiv.appendChild(Object(O.createElement)("a",{innerHTML:"Travel",class:"a-link-button",display:"inline-block",clickListener:()=>{var e="bladeburner-travel-popup-cancel-btn",t=[];t.push(Object(O.createElement)("a",{innerText:"Cancel",class:"a-link-button",clickListener:()=>(Object(R.removeElementById)(e),!1)})),t.push(Object(O.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=N[i],Object(R.removeElementById)(e),n.updateOverviewContent(),!1)}))}(this,n);Object(T.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");X.overviewDiv.appendChild(Object(O.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(f.dialogBoxCreate)("Congratulations! You were accepted into the Bladeburners faction"),Object(b.removeChildrenFromElement)(X.overviewDiv),this.createOverviewContent()):Object(f.dialogBoxCreate)("You need a rank of 25 to join the Bladeburners Faction!"),!1)}))}X.overviewDiv.appendChild(Object(O.createElement)("br")),X.overviewDiv.appendChild(Object(O.createElement)("br")),this.updateOverviewContent()},J.prototype.createActionAndSkillsContent=function(){null==X.currentTab&&(X.currentTab="general"),Object(b.removeChildrenFromElement)(X.actionAndSkillsDiv),Object(C.clearObject)(X.generalActions),Object(C.clearObject)(X.contracts),Object(C.clearObject)(X.operations),Object(C.clearObject)(X.blackops),Object(C.clearObject)(X.skills);for(var e=X.currentTab.toLowerCase(),t=["General","Contracts","Operations","BlackOps","Skills"],n=0;n(X.currentTab=e[t].toLowerCase(),n.createActionAndSkillsContent(),!1)}))}(t,n,this,e);switch(X.actionsAndSkillsDesc=Object(O.createElement)("p",{display:"block",margin:"4px",padding:"4px"}),Object(b.removeChildrenFromElement)(X.actionsAndSkillsList),X.actionsAndSkillsList=Object(O.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(),X.actionAndSkillsDiv.appendChild(X.actionsAndSkillsDesc),X.actionAndSkillsDiv.appendChild(X.actionsAndSkillsList)},J.prototype.createGeneralActionsContent=function(){if(null==X.actionsAndSkillsList||null==X.actionsAndSkillsDesc)throw new Error("Bladeburner.createGeneralActionsContent called with either DomElems.actionsAndSkillsList or DomElems.actionsAndSkillsDesc = null");for(var e in X.actionsAndSkillsDesc.innerText="These are generic actions that will assist you in your Bladeburner duties. They will not affect your Bladeburner rank in any way.",G)G.hasOwnProperty(e)&&(X.generalActions[e]=Object(O.createElement)("div",{class:"bladeburner-action",name:e}),X.actionsAndSkillsList.appendChild(X.generalActions[e]))},J.prototype.createContractsContent=function(){if(null==X.actionsAndSkillsList||null==X.actionsAndSkillsDesc)throw new Error("Bladeburner.createContractsContent called with either DomElems.actionsAndSkillsList or DomElems.actionsAndSkillsDesc = null");for(var e in X.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)&&(X.contracts[e]=Object(O.createElement)("div",{class:"bladeburner-action",name:e}),X.actionsAndSkillsList.appendChild(X.contracts[e]))},J.prototype.createOperationsContent=function(){if(null==X.actionsAndSkillsList||null==X.actionsAndSkillsDesc)throw new Error("Bladeburner.createOperationsContent called with either DomElems.actionsAndSkillsList or DomElems.actionsAndSkillsDesc = null");for(var e in X.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)&&(X.operations[e]=Object(O.createElement)("div",{class:"bladeburner-action",name:e}),X.actionsAndSkillsList.appendChild(X.operations[e]))},J.prototype.createBlackOpsContent=function(){if(null==X.actionsAndSkillsList||null==X.actionsAndSkillsDesc)throw new Error("Bladeburner.createBlackOpsContent called with either DomElems.actionsAndSkillsList or DomElems.actionsAndSkillsDesc = null");X.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 V)V.hasOwnProperty(t)&&e.push(V[t]);e.sort(function(e,t){return e.reqdRank-t.reqdRank});for(var n=0;n
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":X.actionsAndSkillsDesc.innerHTML+="Stealth Success Chance: x"+n+"
";break;case"successChanceKill":X.actionsAndSkillsDesc.innerHTML+="Retirement Success Chance: x"+n+"
";break;case"successChanceContract":X.actionsAndSkillsDesc.innerHTML+="Contract Success Chance: x"+n+"
";break;case"successChanceOperation":X.actionsAndSkillsDesc.innerHTML+="Operation Success Chance: x"+n+"
";break;case"successChanceEstimate":X.actionsAndSkillsDesc.innerHTML+="Synthoid Data Estimate: x"+n+"
";break;case"actionTime":X.actionsAndSkillsDesc.innerHTML+="Action Time: x"+n+"
";break;case"effHack":X.actionsAndSkillsDesc.innerHTML+="Hacking Skill: x"+n+"
";break;case"effStr":X.actionsAndSkillsDesc.innerHTML+="Strength: x"+n+"
";break;case"effDef":X.actionsAndSkillsDesc.innerHTML+="Defense: x"+n+"
";break;case"effDex":X.actionsAndSkillsDesc.innerHTML+="Dexterity: x"+n+"
";break;case"effAgi":X.actionsAndSkillsDesc.innerHTML+="Agility: x"+n+"
";break;case"effCha":X.actionsAndSkillsDesc.innerHTML+="Charisma: x"+n+"
";break;case"effInt":X.actionsAndSkillsDesc.innerHTML+="Intelligence: x"+n+"
";break;case"stamina":X.actionsAndSkillsDesc.innerHTML+="Stamina: x"+n+"
";break;case"money":X.actionsAndSkillsDesc.innerHTML+="Contract Money: x"+n+"
";break;case"expGain":X.actionsAndSkillsDesc.innerHTML+="Exp Gain: x"+n+"
";break;case"weaponAbility":case"gunAbility":break;default:console.log("Warning: Unrecognized SkillMult Key: "+e[t])}}for(var i in X.skillPointsDisplay=Object(O.createElement)("p",{innerHTML:"
Skill Points: "+Object(P.formatNumber)(this.skillPoints,0)+""}),X.actionAndSkillsDiv.appendChild(X.skillPointsDisplay),F)F.hasOwnProperty(i)&&(X.skills[i]=Object(O.createElement)("div",{class:"bladeburner-action",name:i}),X.actionsAndSkillsList.appendChild(X.skills[i]))},J.prototype.updateContent=function(){this.updateOverviewContent(),this.updateActionAndSkillsContent()},J.prototype.updateOverviewContent=function(){S.routing.isOn(S.Page.Bladeburner)&&(X.overviewRank.childNodes[0].nodeValue="Rank: "+Object(P.formatNumber)(this.rank,2),X.overviewStamina.innerText="Stamina: "+Object(P.formatNumber)(this.stamina,3)+" / "+Object(P.formatNumber)(this.maxStamina,3),X.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+"
",X.overviewEstPop.childNodes[0].nodeValue="Est. Synthoid Population: "+d.numeralWrapper.format(this.getCurrentCity().popEst,"0.000a"),X.overviewEstComms.childNodes[0].nodeValue="Est. Synthoid Communities: "+Object(P.formatNumber)(this.getCurrentCity().comms,0),X.overviewChaos.childNodes[0].nodeValue="City Chaos: "+Object(P.formatNumber)(this.getCurrentCity().chaos),X.overviewSkillPoints.innerText="Skill Points: "+Object(P.formatNumber)(this.skillPoints,0),X.overviewBonusTime.childNodes[0].nodeValue="Bonus time: "+this.storedCycles/5,X.overviewAugSuccessMult.innerText="Aug. Success Chance Mult: "+Object(P.formatNumber)(100*m.a.bladeburner_success_chance_mult,1)+"%",X.overviewAugMaxStaminaMult.innerText="Aug. Max Stamina Mult: "+Object(P.formatNumber)(100*m.a.bladeburner_max_stamina_mult,1)+"%",X.overviewAugStaminaGainMult.innerText="Aug. Stamina Gain Mult: "+Object(P.formatNumber)(100*m.a.bladeburner_stamina_gain_mult,1)+"%",X.overviewAugAnalysisMult.innerText="Aug. Field Analysis Mult: "+Object(P.formatNumber)(100*m.a.bladeburner_analysis_mult,1)+"%")},J.prototype.updateActionAndSkillsContent=function(){switch(null==X.currentTab&&(X.currentTab="general"),X.currentTab.toLowerCase()){case"general":for(var e=Object.keys(X.generalActions),t=0;t";var d=Object.keys(X.skills);for(t=0;t(this.action.type=K[t.name],this.action.name=t.name,this.startAction(this.action),this.updateActionAndSkillsContent(),!1)}));Object(k.appendLineBreaks)(e,2),e.appendChild(Object(O.createElement)("pre",{innerHTML:t.desc,display:"inline-block"}))},J.prototype.updateContractsUIElement=function(e,t){Object(b.removeChildrenFromElement)(e);var n=e.classList.contains(L),i=t.getSuccessChance(this,{est:!0});if(e.appendChild(Object(O.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 a=this.actionTimeCurrent/this.actionTimeToComplete;e.appendChild(Object(O.createElement)("p",{display:"block",innerText:Object(y.createProgressBarText)({progress:a})}))}else e.appendChild(Object(O.createElement)("a",{innerText:"Start",class:"a-link-button",padding:"3px",margin:"3px",clickListener:()=>(this.action.type=K.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(O.createElement)("pre",{display:"inline-block",innerText:"Level: "+t.level+" / "+t.maxLevel,tooltip:t.getSuccessesNeededForNextLevel(3)+" successes needed for next level"})),e.appendChild(Object(O.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(O.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(O.createElement)("pre",{display:"inline-block",innerHTML:t.desc+"\n\nEstimated success chance: "+Object(P.formatNumber)(100*i,1)+"%\nTime Required (s): "+Object(P.formatNumber)(o,0)+"\nContracts remaining: "+Math.floor(t.count)+"\nSuccesses: "+t.successes+"\nFailures: "+t.failures})),e.appendChild(Object(O.createElement)("br"));var s="bladeburner-"+t.name+"-autolevel-checkbox";e.appendChild(Object(O.createElement)("label",{for:s,innerText:"Autolevel",color:"white",tooltip:"Automatically increase contract level when possible"}));var l=Object(O.createElement)("input",{type:"checkbox",id:s,margin:"4px",checked:t.autoLevel,changeListener:()=>{t.autoLevel=l.checked}});e.appendChild(l)},J.prototype.updateOperationsUIElement=function(e,t){Object(b.removeChildrenFromElement)(e);var n=e.classList.contains(L),i=t.getSuccessChance(this,{est:!0});if(e.appendChild(Object(O.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 a=this.actionTimeCurrent/this.actionTimeToComplete;e.appendChild(Object(O.createElement)("p",{display:"block",innerText:Object(y.createProgressBarText)({progress:a})}))}else e.appendChild(Object(O.createElement)("a",{innerText:"Start",class:"a-link-button",margin:"3px",padding:"3px",clickListener:()=>(this.action.type=K.Operation,this.action.name=t.name,this.startAction(this.action),this.updateActionAndSkillsContent(),!1)})),e.appendChild(Object(O.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",i=Object(O.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."}),a=Object(O.createElement)("input",{type:"number",placeholder:"Team Members"}),r=Object(O.createElement)("a",{innerText:"Confirm",class:"a-link-button",clickListener:()=>{var i=Math.round(parseFloat(a.value));return isNaN(i)?Object(f.dialogBoxCreate)("Invalid value entered for number of Team Members (must be numeric)"):(t.teamCount=i,this.updateOperationsUIElement(e,t)),Object(R.removeElementById)(n),!1}}),o=Object(O.createElement)("a",{innerText:"Cancel",class:"a-link-button",clickListener:()=>(Object(R.removeElementById)(n),!1)});Object(T.createPopup)(n,[i,a,r,o])}}));var r=t.level>=t.maxLevel;Object(k.appendLineBreaks)(e,2),e.appendChild(Object(O.createElement)("pre",{display:"inline-block",innerText:"Level: "+t.level+" / "+t.maxLevel,tooltip:t.getSuccessesNeededForNextLevel(2.5)+" successes needed for next level"})),e.appendChild(Object(O.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(O.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(O.createElement)("pre",{display:"inline-block",innerHTML:t.desc+"\n\nEstimated success chance: "+Object(P.formatNumber)(100*i,1)+"%\nTime Required(s): "+Object(P.formatNumber)(o,1)+"\nOperations remaining: "+Math.floor(t.count)+"\nSuccesses: "+t.successes+"\nFailures: "+t.failures})),e.appendChild(Object(O.createElement)("br"));var s="bladeburner-"+t.name+"-autolevel-checkbox";e.appendChild(Object(O.createElement)("label",{for:s,innerText:"Autolevel",color:"white",tooltip:"Automatically increase operation level when possible"}));var l=Object(O.createElement)("input",{type:"checkbox",id:s,margin:"4px",checked:t.autoLevel,changeListener:()=>{t.autoLevel=l.checked}});e.appendChild(l)},J.prototype.updateBlackOpsUIElement=function(e,t){Object(b.removeChildrenFromElement)(e);var n=e.classList.contains(L),i=null!=this.blackops[t.name],a=t.getSuccessChance(this,{est:!0}),r=(t.getDifficulty(),t.getActionTime(this)),o=this.rank>=t.reqdRank;if(i)e.appendChild(Object(O.createElement)("h2",{innerText:t.name+" (COMPLETED)",display:"block"}));else{if(e.appendChild(Object(O.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(O.createElement)("p",{display:"block",innerText:Object(y.createProgressBarText)({progress:s})}))}else e.appendChild(Object(O.createElement)("a",{innerText:"Start",margin:"3px",padding:"3px",class:o?"a-link-button":"a-link-button-inactive",clickListener:()=>(this.action.type=K.BlackOperation,this.action.name=t.name,this.startAction(this.action),this.updateActionAndSkillsContent(),!1)})),e.appendChild(Object(O.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",i=Object(O.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."}),a=Object(O.createElement)("input",{type:"number",placeholder:"Team Members"}),r=Object(O.createElement)("a",{innerText:"Confirm",class:"a-link-button",clickListener:()=>{var i=Math.round(parseFloat(a.value));return isNaN(i)?Object(f.dialogBoxCreate)("Invalid value entered for number of Team Members (must be numeric)"):(t.teamCount=i,this.updateBlackOpsUIElement(e,t)),Object(R.removeElementById)(n),!1}}),o=Object(O.createElement)("a",{innerText:"Cancel",class:"a-link-button",clickListener:()=>(Object(R.removeElementById)(n),!1)});Object(T.createPopup)(n,[i,a,r,o])}}));Object(k.appendLineBreaks)(e,2),e.appendChild(Object(O.createElement)("p",{display:"inline-block",innerHTML:"
"+t.desc+"

"})),e.appendChild(Object(O.createElement)("p",{display:"block",color:o?"white":"red",innerHTML:"Required Rank: "+Object(P.formatNumber)(t.reqdRank,0)+"
"})),e.appendChild(Object(O.createElement)("p",{display:"inline-block",innerHTML:"Estimated Success Chance: "+Object(P.formatNumber)(100*a,1)+"%\nTime Required(s): "+Object(P.formatNumber)(r,1)}))}},J.prototype.updateSkillsUIElement=function(e,t){Object(b.removeChildrenFromElement)(e);var n=t.name,i=0;this.skills[n]&&!isNaN(this.skills[n])&&(i=this.skills[n]);var a=t.calculateCost(i);e.appendChild(Object(O.createElement)("h2",{innerText:t.name+" (Lvl "+i+")",display:"inline-block"}));var r=this.skillPoints>=a,o=!!t.maxLvl&&i>=t.maxLvl;e.appendChild(Object(O.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!=X.consoleDiv&&(e("#bladeubrner-console-input-row").before(''+t+""),X.consoleTable.childNodes.length>100&&X.consoleTable.removeChild(X.consoleTable.firstChild),this.updateConsoleScroll())},J.prototype.updateConsoleScroll=function(){X.consoleDiv.scrollTop=X.consoleDiv.scrollHeight},J.prototype.resetConsoleInput=function(){X.consoleInput.value=""},J.prototype.clearConsole=function(){for(;X.consoleTable.childNodes.length>1;)X.consoleTable.removeChild(X.consoleTable.firstChild);this.consoleLogs.length=0},J.prototype.log=function(e){this.postToConsole(`[${Object(w.getTimestamp)()}] ${e}`)},J.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)),D=this.consoleHistory.length;for(var t=e.split(";"),n=0;n"))}},J.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]")}},J.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(F),n=0;n=c?(this.skillPoints-=c,this.upgradeSkill(i),this.log(i.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")}},J.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!=G[t]?(this.action.type=K[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=K.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=K.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!=V[t]?(this.action.type=K.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]")}},J.prototype.getActionIdFromTypeAndName=function(e="",t=""){if(""===e||""===t)return null;var n=new q,i=e.toLowerCase().trim(),a=t.toLowerCase().trim();switch(i){case"contract":case"contracts":case"contr":return n.type=K.Contract,this.contracts.hasOwnProperty(t)?(n.name=t,n):null;case"operation":case"operations":case"op":case"ops":return n.type=K.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=K.BlackOp,V.hasOwnProperty(t)?(n.name=t,n):null;case"general":case"general action":case"gen":break;default:return null}if(i.startsWith("gen")){switch(a){case"training":n.type=K.Training,n.name="Training";break;case"recruitment":case"recruit":n.type=K.Recruitment,n.name="Recruitment";break;case"field analysis":case"fieldanalysis":n.type=K["Field Analysis"],n.name="Field Analysis";break;case"diplomacy":n.type=K.Diplomacy,n.name="Diplomacy";break;case"hyperbolic regeneration chamber":n.type=K["Hyperbolic Regeneration Chamber"],n.name="Hyperbolic Regeneration Chamber";break;default:return null}return n}},J.prototype.getTypeAndNameFromActionId=function(e){var t={};let n=Object.keys(K);for(let i=0;ithis.rank)return n.log(`Failed to start Black Op ${a.name} due to insufficient rank`),!1;if(null!=this.blackops[a.name])return n.log(`Failed to start Black Op ${a.name} because its already been completed`),!1;var r=[];for(const e in V)V.hasOwnProperty(e)&&r.push(e);r.sort(function(e,t){return V[e].reqdRank-V[t].reqdRank});let e=r.indexOf(a.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 ${a.name} because you have not done the preceding one`),!1}try{return this.startAction(a),n.shouldLog("startAction")&&n.log("Starting bladeburner action with type "+e+" and name "+t),!0}catch(i){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}},J.prototype.getActionTimeNetscriptFn=function(e,t,n){var i="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.",a=this.getActionIdFromTypeAndName(e,t);if(null==a)return n.log(i),-1;var r=this.getActionObject(a);if(null==r)return n.log(i),-1;switch(a.type){case K.Contract:case K.Operation:case K.BlackOp:case K.BlackOperation:return r.getActionTime(this);case K.Training:case K["Field Analysis"]:case K.FieldAnalysis:return 30;case K.Recruitment:return this.getRecruitmentTime();default:return n.log(i),-1}},J.prototype.getActionEstimatedSuccessChanceNetscriptFn=function(e,t,n){var i="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.",a=this.getActionIdFromTypeAndName(e,t);if(null==a)return n.log(i),-1;var r=this.getActionObject(a);if(null==r)return n.log(i),-1;switch(a.type){case K.Contract:case K.Operation:case K.BlackOp:case K.BlackOperation:return r.getSuccessChance(this,{est:!0});case K.Training:case K["Field Analysis"]:case K.FieldAnalysis:return 1;case K.Recruitment:return this.getRecruitmentSuccessChance();default:return n.log(i),-1}},J.prototype.getActionCountRemainingNetscriptFn=function(e,t,n){var i="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.",a=this.getActionIdFromTypeAndName(e,t);if(null==a)return n.log(i),-1;var r=this.getActionObject(a);if(null==r)return n.log(i),-1;switch(a.type){case K.Contract:case K.Operation:return Math.floor(r.count);case K.BlackOp:case K.BlackOperation:return null!=this.blackops[t]?0:1;case K.Training:case K["Field Analysis"]:case K.FieldAnalysis:return 1/0;default:return n.log(i),-1}},J.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:F.hasOwnProperty(e)?null==this.skills[e]?0:this.skills[e]:(t.log(n),-1)},J.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(!F.hasOwnProperty(e))return t.log(n),-1;var i=F[e];return null==this.skills[e]?i.calculateCost(0):i.calculateCost(this.skills[e])},J.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(!F.hasOwnProperty(e))return t.log(n),!1;var i=F[e],a=0;this.skills[e]&&!isNaN(this.skills[e])&&(a=this.skills[e]);var r=i.calculateCost(a);return i.maxLvl&&a>=i.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)(X.overviewDiv),this.createOverviewContent()),!0):(e.shouldLog("joinBladeburnerFaction")&&e.log("Failed to join Bladeburners Faction because you do not have the required 25 rank"),!1))},J.prototype.toJSON=function(){return Object(E.Generic_toJSON)("Bladeburner",this)},J.fromJSON=function(e){return Object(E.Generic_fromJSON)(J,e.data)},E.Reviver.constructors.Bladeburner=J}).call(this,n(73))},function(e,t,n){"use strict";n.d(t,"b",function(){return C}),n.d(t,"h",function(){return O}),n.d(t,"a",function(){return T}),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 i=n(78),a=n(1),r=n(10),o=n(160),s=n(138),l=n(7),c=n(47),u=n(139),p=n(83),m=n(11),h=n(18),d=n(56),g=n(130),_=n(55),y=n(9),f=n(111),b=n(64),E=n(99),v=n(4);const k=n(180);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=a.CONSTANTS.ScriptBaseRamCost,this.dynamicLoadedFns={}}C.prototype.getServer=function(){return m.b[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,i=e.code;e.running=!0;try{let a=function(e,t){var n=Object(_.parse)(e,{ecmaVersion:6,allowReserved:!0,sourceType:"module"}),i=t.getServer();if(null==i)throw new Error("Failed to find underlying Server object for script");var a="",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),i.push(e)}}),a="var "+t+";\n(function (namespace) {\n",i.forEach(e=>{a+=Object(g.generate)(e),a+="\n"}),n.forEach(e=>{a+="namespace."+e+" = "+e,a+="\n"}),a+="})("+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=>{a+=Object(g.generate)(e),a+="\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=(a.match(/\n/g)||[]).length-o;return e=Object(g.generate)(n),{code:e=a+e,lineOffset:s}}(i,e);t=a.code,n=a.lineOffset}catch(t){return Object(y.dialogBoxCreate)("Error processing Imports in "+e.name+":
"+t),e.env.stopFlag=!0,void(e.running=!1)}var a;try{a=new o.a(t,function(t,n){var i=Object(c.a)(e);for(let e in i){let a=i[e];if("function"==typeof a)if("hack"===e||"grow"===e||"weaken"===e||"sleep"===e||"prompt"===e||"run"===e||"exec"===e){let i=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 i(){try{if(e.env.stopFlag)return n(e);a.step()?Object(d.setTimeoutRef)(i,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(v.isString)(t)?(e.errorMessage=t,n(e)):n(t instanceof C?t:e)}})}function w(){for(var e=!1,t=O.length-1;t>=0;t--)if(0==O[t].running&&1==O[t].env.stopFlag){e=!0;var n=O[t].serverIp,a=O[t].name;m.b[n].ramUsed=0;for(let e=0;eServer Ip: "+n+"
Script name: "+i+"
Args:"+Object(b.arrayToString)(e.args)+"
"+a),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(y.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(y.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(y.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(E.roundToTwo)(t.ramUsed+a);var r=new C(e);r.ramUsage=a,Object(i.a)(r),O.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 y(),!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"),a=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"),a.removeAttribute("class"),r.removeAttribute("class"),o.removeAttribute("class");var s=document.getElementById("interactive-tutorial-next");switch(d.currStep){case h.Start:i.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:i.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 i.Engine.loadCharacterContent(),y(),!1});break;case h.CharacterPage:i.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:i.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 i.Engine.loadTerminalContent(),y(),!1});break;case h.TerminalIntro:i.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:i.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:i.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:i.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:i.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:i.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:i.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:i.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:i.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:i.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:i.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:i.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:i.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:i.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:i.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:i.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 i.Engine.loadActiveScriptsContent(),y(),!1});break;case h.ActiveScriptsPage:i.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 i.Engine.loadTerminalContent(),y(),!1});break;case h.ActiveScriptsToTerminal:i.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:i.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:i.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",a.setAttribute("class","flashing-button"),a.addEventListener("click",function(){return i.Engine.loadHacknetNodesContent(),y(),!1});break;case h.HacknetNodesIntroduction:i.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:i.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 i.Engine.loadWorldContent(),y(),!1});break;case h.WorldDescription:i.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 i.Engine.loadTutorialContent(),y(),!1});break;case h.TutorialPageInfo:i.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:f();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 y(){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 GuideWikiDocumentation

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]),a.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});const i=n(2),a=n(62);t.createPopup=function(e,t,n={}){const r=i.createElement("div",{class:"popup-box-container",display:"flex",id:e}),o=i.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),a.getElementById("entire-game-container").appendChild(r),r}},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 i=n(9);t.exceptionAlert=function(e){i.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";n.d(t,"b",function(){return o}),n.d(t,"a",function(){return s});var i=n(0),a=n(58),r=n(7);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(!(i.a.gang instanceof a.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";n.d(t,"b",function(){return f}),n.d(t,"c",function(){return _}),n.d(t,"f",function(){return g}),n.d(t,"e",function(){return b}),n.d(t,"d",function(){return v}),n.d(t,"a",function(){return h});n(17);var i=n(13),a=n(6),r=n(28),o=n(65),s=n(0),l=n(68),c=n(11),u=n(18),p=n(9),m=n(14);function h(e="",t=""){this.filename=e,this.msg=t,this.recvd=!1}function d(e,t=!1){e.recvd=!0,!t&&u.Settings.SuppressMessages||g(e),function(e,t){var n=Object(c.c)(t);if(null==n)return void console.log("WARNING: Did not locate "+t);for(var i=0;i

This message was saved as "+e.filename+" onto your home computer.";Object(p.dialogBoxCreate)(t)}function _(){var e=f[E.Jumper0],t=f[E.Jumper1],n=f[E.Jumper2],c=f[E.Jumper3],u=f[E.Jumper4],m=f[E.CyberSecTest],h=f[E.NiteSecTest],g=f[E.BitRunnersTest],_=f[E.RedPill],y=!1;i.Augmentations[a.AugmentationNames.TheRedPill].owned&&(y=!0),_&&y&&0===s.a.sourceFiles.length&&!l.b&&!o.c?p.dialogBoxOpened||d(_,!0):_&&y?l.b||o.c||p.dialogBoxOpened||d(_):e&&!e.recvd&&s.a.hacking_skill>=25?(d(e),s.a.getHomeComputer().programs.push(r.Programs.Flight.name)):t&&!t.recvd&&s.a.hacking_skill>=40?d(t):m&&!m.recvd&&s.a.hacking_skill>=50?d(m):n&&!n.recvd&&s.a.hacking_skill>=175?d(n):h&&!h.recvd&&s.a.hacking_skill>=200?d(h):c&&!c.recvd&&s.a.hacking_skill>=350?d(c):u&&!u.recvd&&s.a.hacking_skill>=490?d(u):g&&!g.recvd&&s.a.hacking_skill>=500&&d(g)}function y(e){f[e.filename]=e}h.prototype.toJSON=function(){return Object(m.Generic_toJSON)("Message",this)},h.fromJSON=function(e){return Object(m.Generic_fromJSON)(h,e.data)},m.Reviver.constructors.Message=h;let f={};function b(e){f=JSON.parse(e,m.Reviver)}let E={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={},y(new h(E.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")),y(new h(E.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")),y(new h(E.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")),y(new h(E.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")),y(new h(E.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")),y(new h(E.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")),y(new h(E.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")),y(new h(E.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")),y(new h(E.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";var i=this&&this.__awaiter||function(e,t,n,i){return new(n||(n=Promise))(function(a,r){function o(e){try{l(i.next(e))}catch(e){r(e)}}function s(e){try{l(i.throw(e))}catch(e){r(e)}}function l(e){e.done?a(e.value):new n(function(t){t(e.value)}).then(o,s)}l((i=i.apply(e,t||[])).next())})};Object.defineProperty(t,"__esModule",{value:!0});const a=n(255),r=n(14),o=n(29),s=n(2),l=n(38),c=n(23);class u{constructor(e,t,n,i,a,r){this.name=e,this.desc=t,this.generate=n,this.solver=i,this.difficulty=a,this.numTries=r}}t.CodingContractType=u,t.CodingContractTypes={};for(const e of a.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",i=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=i}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 i(this,void 0,void 0,function*(){return new Promise((e,n)=>{const i=t.CodingContractTypes[this.type],a=`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.

",`${i.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(a)},innerText:"Solve"}),h=s.createElement("a",{class:"a-link-button",clickListener:()=>{e(p.Cancelled),c.removeElementById(a)},innerText:"Cancel"});const d=s.createElement("br");l.createPopup(a,[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";Object.defineProperty(t,"__esModule",{value:!0});const i=n(155),a=n(1);t.Crimes={Shoplift:new i.Crime("Shoplift",a.CONSTANTS.CrimeShoplift,2e3,15e3,.05,.1,{dexterity_success_weight:1,agility_success_weight:1,dexterity_exp:2,agility_exp:2}),RobStore:new i.Crime("Rob Store",a.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*a.CONSTANTS.IntelligenceCrimeBaseExpGain}),Mug:new i.Crime("Mug",a.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 i.Crime("Larceny",a.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*a.CONSTANTS.IntelligenceCrimeBaseExpGain}),DealDrugs:new i.Crime("Deal Drugs",a.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 i.Crime("Bond Forgery",a.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*a.CONSTANTS.IntelligenceCrimeBaseExpGain}),TraffickArms:new i.Crime("Traffick Arms",a.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 i.Crime("Homicide",a.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 i.Crime("Grand Theft Auto",a.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:a.CONSTANTS.IntelligenceCrimeBaseExpGain}),Kidnap:new i.Crime("Kidnap",a.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*a.CONSTANTS.IntelligenceCrimeBaseExpGain}),Assassination:new i.Crime("Assassination",a.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*a.CONSTANTS.IntelligenceCrimeBaseExpGain,kills:1}),Heist:new i.Crime("Heist",a.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*a.CONSTANTS.IntelligenceCrimeBaseExpGain})}},function(e,t,n){"use strict";(function(e){n.d(t,"a",function(){return ue}),n.d(t,"g",function(){return ce}),n.d(t,"d",function(){return re}),n.d(t,"f",function(){return ae}),n.d(t,"h",function(){return se}),n.d(t,"e",function(){return Z}),n.d(t,"b",function(){return te}),n.d(t,"c",function(){return ne});var i=n(78),a=n(17),r=n(13),o=n(66),s=n(6),l=n(20),c=n(113),u=n(34),p=n(74),m=n(19),h=n(109),d=n(33),g=n(1),_=n(82),y=n(53),f=n(58),b=n(63),E=n(15),v=n(51),k=n(77),C=n(5),O=n(44),T=n(65),S=n(0),M=n(28),P=n(32),A=n(11),w=n(57),x=(n(18),n(36)),R=(n(31),n(24)),N=n(80),I=n(3),L=n(8),D=n(56),B=n(75),j=n(61),W=n(42),F=n(35),U=n(7),H=n(83),G=(n(41),n(12)),K=(n(9),n(137),n(64)),q=n(71),$=n(4),Y=n(48),z=n(2),V=n(38),J=n(23),X=n(181).sprintf,Q=n(181).vsprintf,Z=!1,ee=!1,te=!1,ne=!1,ie=!1,ae=!1,re=!1,oe=1,se=1,le={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 ce(){for(var e=0;e1.01*t.ramUsage)throw Object(U.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)},Z=function(e,n){return t.loadedFns[e]?0:(t.loadedFns[e]=!0,n)},ne=function(e,n=""){var i=Object(A.e)(e);if(null==i)throw Object(U.d)(t,`Invalid IP or hostname passed into ${n}() function`);return i},re=function(e){if(isNaN(e))throw Object(U.d)(t,"Invalid index specified for Hacknet Node: "+e);if(e<0||e>=S.a.hacknetNodes.length)throw Object(U.d)(t,"Index specified for Hacknet Node is out-of-bounds: "+e);return S.a.hacknetNodes[e]},ce=function(e,t){return ne(t,"getCodingContract").getContract(e)};return{hacknet:{numNodes:function(){return S.a.hacknetNodes.length},purchaseNode:function(){return Object(k.e)()},getPurchaseNodeCost:function(){return Object(k.c)()},getNodeStats:function(e){var t=re(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 re(e).purchaseLevelUpgrade(t)},upgradeRam:function(e,t){return re(e).purchaseRamUpgrade(t)},upgradeCore:function(e,t){return re(e).purchaseCoreUpgrade(t)},getLevelUpgradeCost:function(e,t){return re(e).calculateLevelUpgradeCost(t)},getRamUpgradeCost:function(e,t){return re(e).calculateRamUpgradeCost(t)},getCoreUpgradeCost:function(e,t){return re(e).calculateCoreUpgradeCost(t)}},sprintf:X,vsprintf:Q,scan:function(e=t.serverIp,i=!0){if(t.checkingRam)return Z("scan",g.CONSTANTS.ScriptScanRamCost);n("scan",g.CONSTANTS.ScriptScanRamCost);var a=Object(A.e)(e);if(null==a)throw Object(U.d)(t,"Invalid IP or hostname passed into scan() command");for(var r=[],o=0;oS.a.hacking_skill)throw t.scriptRef.log("Cannot hack this server ("+a.hostname+") because user's hacking skill is not high enough"),Object(U.d)(t,"Cannot hack this server ("+a.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="+i+")"),Object(U.e)(1e3*r,t).then(function(){if(t.env.stopFlag)return Promise.reject(t);var e=Object(y.b)(a),n=Math.random(),r=Object(y.c)(a)*i,o=r/4;if(na.moneyAvailable&&(s=a.moneyAvailable),a.moneyAvailable-=s,a.moneyAvailable<0&&(a.moneyAvailable=0),S.a.gainMoney(s),t.scriptRef.onlineMoneyMade+=s,S.a.scriptProdSinceLastAug+=s,S.a.recordMoneySource(s,"hacking"),t.scriptRef.recordHack(a.ip,s,i),S.a.gainHackingExp(r),t.scriptRef.onlineExpGained+=r,null==t.disableLogs.ALL&&null==t.disableLogs.hack&&t.scriptRef.log("Script SUCCESSFULLY hacked "+a.hostname+" for $"+Object($.formatNumber)(s,2)+" and "+Object($.formatNumber)(r,4)+" exp (t="+i+")"),a.fortify(g.CONSTANTS.ServerFortifyAmount*Math.min(i,n)),Promise.resolve(s)}return S.a.gainHackingExp(o),t.scriptRef.onlineExpGained+=o,null==t.disableLogs.ALL&&null==t.disableLogs.hack&&t.scriptRef.log("Script FAILED to hack "+a.hostname+". Gained "+Object($.formatNumber)(o,4)+" exp (t="+i+")"),Promise.resolve(0)})},hackAnalyzeThreads:function(e,i){if(t.checkingRam)return Z("hackAnalyzeThreads",g.CONSTANTS.ScriptHackAnalyzeRamCost);n("hackAnalyzeThreads",g.CONSTANTS.ScriptHackAnalyzeRamCost);const a=ne(e,"hackAnalyzeThreads");if(isNaN(i))throw Object(U.d)(t,`Invalid growth argument passed into hackAnalyzeThreads: ${i}. Must be numeric`);if(i<0||i>a.moneyAvailable)return-1;const r=Object(y.e)(a);return i/Math.floor(a.moneyAvailable*r)},hackAnalyzePercent:function(e){if(t.checkingRam)return Z("hackAnalyzePercent",g.CONSTANTS.ScriptHackAnalyzeRamCost);n("hackAnalyzePercent",g.CONSTANTS.ScriptHackAnalyzeRamCost);const i=ne(e,"hackAnalyzePercent");return 100*Object(y.e)(i)},hackChance:function(e){if(t.checkingRam)return Z("hackChance",g.CONSTANTS.ScriptHackAnalyzeRamCost);n("hackChance",g.CONSTANTS.ScriptHackAnalyzeRamCost);const i=ne(e,"hackChance");return Object(y.b)(i)},sleep:function(e){if(t.checkingRam)return 0;if(void 0===e)throw Object(U.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(U.e)(e,t).then(function(){return Promise.resolve(!0)})},grow:function(e){if(t.checkingRam)return Z("grow",g.CONSTANTS.ScriptGrowRamCost);n("grow",g.CONSTANTS.ScriptGrowRamCost);var i=t.scriptRef.threads;if((isNaN(i)||i<1)&&(i=1),void 0===e)throw Object(U.d)(t,"grow() call has incorrect number of arguments. Takes 1 argument");var a=Object(A.e)(e);if(null==a)throw t.scriptRef.log("Cannot grow(). Invalid IP or hostname passed in: "+e),Object(U.d)(t,"Cannot grow(). Invalid IP or hostname passed in: "+e);if(0==a.hasAdminRights)throw t.scriptRef.log("Cannot grow this server ("+a.hostname+") because user does not have root access"),Object(U.d)(t,"Cannot grow this server ("+a.hostname+") because user does not have root access");var r=Object(y.a)(a);return null==t.disableLogs.ALL&&null==t.disableLogs.grow&&t.scriptRef.log("Executing grow() on server "+a.hostname+" in "+Object($.formatNumber)(r,3)+" seconds (t="+i+")"),Object(U.e)(1e3*r,t).then(function(){if(t.env.stopFlag)return Promise.reject(t);const e=a.moneyAvailable<=0?1:a.moneyAvailable;a.moneyAvailable+=1*i;var n=Object(A.k)(a,450*i);const r=a.moneyAvailable;t.scriptRef.recordGrow(a.ip,i);var o=Object(y.c)(a)*i;return 1==n&&(o=0),null==t.disableLogs.ALL&&null==t.disableLogs.grow&&t.scriptRef.log("Available money on "+a.hostname+" grown by "+Object($.formatNumber)(r/e*100-100,6)+"%. Gained "+Object($.formatNumber)(o,4)+" hacking exp (t="+i+")"),t.scriptRef.onlineExpGained+=o,S.a.gainHackingExp(o),Promise.resolve(r/e)})},growthAnalyze:function(e,i){if(t.checkingRam)return Z("growthAnalyze",g.CONSTANTS.ScriptGrowthAnalyzeRamCost);n("growthAnalyze",g.CONSTANTS.ScriptGrowthAnalyzeRamCost);const a=ne(e,"growthAnalyze");if(isNaN(i))throw Object(U.d)(t,`Invalid growth argument passed into growthAnalyze: ${i}. Must be numeric`);return Object(A.h)(a,Number(i))},weaken:function(e){if(t.checkingRam)return Z("weaken",g.CONSTANTS.ScriptWeakenRamCost);n("weaken",g.CONSTANTS.ScriptWeakenRamCost);var i=t.scriptRef.threads;if((isNaN(i)||i<1)&&(i=1),void 0===e)throw Object(U.d)(t,"weaken() call has incorrect number of arguments. Takes 1 argument");var a=Object(A.e)(e);if(null==a)throw t.scriptRef.log("Cannot weaken(). Invalid IP or hostname passed in: "+e),Object(U.d)(t,"Cannot weaken(). Invalid IP or hostname passed in: "+e);if(0==a.hasAdminRights)throw t.scriptRef.log("Cannot weaken this server ("+a.hostname+") because user does not have root access"),Object(U.d)(t,"Cannot weaken this server ("+a.hostname+") because user does not have root access");var r=Object(y.f)(a);return null==t.disableLogs.ALL&&null==t.disableLogs.weaken&&t.scriptRef.log("Executing weaken() on server "+a.hostname+" in "+Object($.formatNumber)(r,3)+" seconds (t="+i+")"),Object(U.e)(1e3*r,t).then(function(){if(t.env.stopFlag)return Promise.reject(t);a.weaken(g.CONSTANTS.ServerWeakenAmount*i),t.scriptRef.recordWeaken(a.ip,i);var e=Object(y.c)(a)*i;return null==t.disableLogs.ALL&&null==t.disableLogs.weaken&&t.scriptRef.log("Server security level on "+a.hostname+" weakened to "+a.hackDifficulty+". Gained "+Object($.formatNumber)(e,4)+" hacking exp (t="+i+")"),t.scriptRef.onlineExpGained+=e,S.a.gainHackingExp(e),Promise.resolve(g.CONSTANTS.ServerWeakenAmount*i)})},print:function(e){if(t.checkingRam)return 0;if(void 0===e)throw Object(U.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(U.d)(t,"tprint() call has incorrect number of arguments. Takes 1 argument");e.toString();Object(L.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===le[e])throw Object(U.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===le[e])throw Object(U.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===le[e])throw Object(U.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 i=Object(A.e)(n);if(null==i)throw t.log(`getScriptLogs() failed. Invalid IP or hostname passed in: ${n}`),Object(U.d)(t,`getScriptLogs() failed. Invalid IP or hostname passed in: ${n}`);let a=[];for(let e=2;e{if(void 0===e)throw Object(U.d)(t,"spawn() call has incorrect number of arguments. Usage: spawn(scriptname, numThreads, [arg1], [arg2]...)");if(isNaN(i)||i<0)throw Object(U.d)(t,"Invalid argument for thread count passed into run(). Must be numeric and greater than 0");for(var n=[],a=2;a0,r=i.runningScripts.length-1;r>=0;--r)Object(F.d)(i.runningScripts[r],i.ip);return null==t.disableLogs.ALL&&null==t.disableLogs.killall&&t.scriptRef.log("killall(): Killing all scripts on "+i.hostname+". May take a few minutes for the scripts to die"),a},exit:function(){if(t.checkingRam)return 0;var e=Object(A.e)(t.serverIp);if(null==e)throw Object(U.d)(t,"Error getting Server for this script in exit(). This is a bug please contact game dev");Object(F.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,i,a){if(t.checkingRam)return Z("scp",g.CONSTANTS.ScriptScpRamCost);if(n("scp",g.CONSTANTS.ScriptScpRamCost),2!==arguments.length&&3!==arguments.length)throw Object(U.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){ue(t).scp(e,i,a)&&(r=!0)}),r}if(!e.endsWith(".lit")&&!Object(P.e)(e)&&!e.endsWith("txt"))throw Object(U.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!=a){if(void 0===e||void 0===i||void 0===a)throw Object(U.d)(t,"ERROR: scp() call has incorrect number of arguments. Takes 2 or 3 arguments");if(null==(o=Object(A.e)(a)))throw Object(U.d)(t,`ERROR: Invalid hostname/ip passed into scp() command: ${a}`);if(null==(s=Object(A.e)(i)))throw Object(U.d)(t,`ERROR: Invalid hostname/ip passed into scp() command: ${i}`)}else{if(null==i)throw Object(U.d)(t,"ERROR: scp() call has incorrect number of arguments. Takes 2 or 3 arguments");if(void 0===e||void 0===i)throw Object(U.d)(t,"ERROR: scp() call has incorrect number of arguments. Takes 2 or 3 arguments");if(null==(o=Object(A.e)(i)))throw Object(U.d)(t,`ERROR: Invalid hostname/ip passed into scp() command: ${i}`);if(null==(s=Object(A.e)(t.serverIp)))throw Object(U.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=i.toString());for(var o=[],s=0;sa.maxShares)return t.scriptRef.log(`You cannot purchase this many shares. ${a.symbol} has a maximum of `+`${a.maxShares} shares.`),0;var o=a.playerShares*a.playerAvgPx;S.a.loseMoney(r+g.CONSTANTS.StockMarketCommission);var s=o+r;return a.playerShares+=i,a.playerAvgPx=s/a.playerShares,G.routing.isOn(G.Page.StockMarket)&&Object(R.r)(a),null==t.disableLogs.ALL&&null==t.disableLogs.buyStock&&t.scriptRef.log("Bought "+Object($.formatNumber)(i,0)+" shares of "+a.symbol+" at $"+Object($.formatNumber)(a.price,2)+" per share"),a.price},sellStock:function(e,i){if(t.checkingRam)return Z("sellStock",g.CONSTANTS.ScriptBuySellStockRamCost);if(n("sellStock",g.CONSTANTS.ScriptBuySellStockRamCost),!S.a.hasTixApiAccess)throw Object(U.d)(t,"You don't have TIX API Access! Cannot use sellStock()");var a=R.e[e];if(null==a)throw Object(U.d)(t,"Invalid stock symbol passed into sellStock()");if(i<0||isNaN(i))return t.scriptRef.log("ERROR: Invalid 'shares' argument passed to sellStock()"),0;if((i=Math.round(i))>a.playerShares&&(i=a.playerShares),0===i)return 0;var r=a.price*i-g.CONSTANTS.StockMarketCommission;S.a.gainMoney(r);var o=(a.price-a.playerAvgPx)*i-g.CONSTANTS.StockMarketCommission;return isNaN(o)&&(o=0),t.scriptRef.onlineMoneyMade+=o,S.a.scriptProdSinceLastAug+=o,S.a.recordMoneySource(o,"stock"),a.playerShares-=i,0==a.playerShares&&(a.playerAvgPx=0),G.routing.isOn(G.Page.StockMarket)&&Object(R.r)(a),null==t.disableLogs.ALL&&null==t.disableLogs.sellStock&&t.scriptRef.log("Sold "+Object($.formatNumber)(i,0)+" shares of "+a.symbol+" at $"+Object($.formatNumber)(a.price,2)+" per share. Gained $"+Object($.formatNumber)(r,2)),a.price},shortStock(e,i){if(t.checkingRam)return Z("shortStock",g.CONSTANTS.ScriptBuySellStockRamCost);if(n("shortStock",g.CONSTANTS.ScriptBuySellStockRamCost),!S.a.hasTixApiAccess)throw Object(U.d)(t,"You don't have TIX API Access! Cannot use shortStock()");if(8!==S.a.bitNodeN&&!(ae&&se>=2))throw Object(U.d)(t,"ERROR: Cannot use shortStock(). You must either be in BitNode-8 or you must have Level 2 of Source-File 8");var a=R.e[e];if(null==a)throw Object(U.d)(t,"ERROR: Invalid stock symbol passed into shortStock()");return Object(R.p)(a,i,t)?a.price:0},sellShort(e,i){if(t.checkingRam)return Z("sellShort",g.CONSTANTS.ScriptBuySellStockRamCost);if(n("sellShort",g.CONSTANTS.ScriptBuySellStockRamCost),!S.a.hasTixApiAccess)throw Object(U.d)(t,"You don't have TIX API Access! Cannot use sellShort()");if(8!==S.a.bitNodeN&&!(ae&&se>=2))throw Object(U.d)(t,"ERROR: Cannot use sellShort(). You must either be in BitNode-8 or you must have Level 2 of Source-File 8");var a=R.e[e];if(null==a)throw Object(U.d)(t,"ERROR: Invalid stock symbol passed into sellShort()");return Object(R.n)(a,i,t)?a.price:0},placeOrder(e,i,a,r,o){if(t.checkingRam)return Z("placeOrder",g.CONSTANTS.ScriptBuySellStockRamCost);if(n("placeOrder",g.CONSTANTS.ScriptBuySellStockRamCost),!S.a.hasTixApiAccess)throw Object(U.d)(t,"You don't have TIX API Access! Cannot use placeOrder()");if(8!==S.a.bitNodeN&&!(ae&&se>=3))throw Object(U.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=R.e[e];if(null==c)throw Object(U.d)(t,"ERROR: Invalid stock symbol passed into placeOrder()");if((r=r.toLowerCase()).includes("limit")&&r.includes("buy"))s=R.a.LimitBuy;else if(r.includes("limit")&&r.includes("sell"))s=R.a.LimitSell;else if(r.includes("stop")&&r.includes("buy"))s=R.a.StopBuy;else{if(!r.includes("stop")||!r.includes("sell"))throw Object(U.d)(t,"ERROR: Invalid Order Type passed into placeOrder()");s=R.a.StopSell}if((o=o.toLowerCase()).includes("l"))l=R.b.Long;else{if(!o.includes("s"))throw Object(U.d)(t,"ERROR: Invalid Position Type passed into placeOrder()");l=R.b.Short}return Object(R.l)(c,i,a,s,l,t)},cancelOrder(e,i,a,r,o){if(t.checkingRam)return Z("cancelOrder",g.CONSTANTS.ScriptBuySellStockRamCost);if(n("cancelOrder",g.CONSTANTS.ScriptBuySellStockRamCost),!S.a.hasTixApiAccess)throw Object(U.d)(t,"You don't have TIX API Access! Cannot use cancelOrder()");if(8!==S.a.bitNodeN&&!(ae&&se>=3))throw Object(U.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=R.e[e];if(null==c)throw Object(U.d)(t,"ERROR: Invalid stock symbol passed into cancelOrder()");if(isNaN(i)||isNaN(a))throw Object(U.d)(t,"ERROR: Invalid shares or price argument passed into cancelOrder(). Must be numeric");if((r=r.toLowerCase()).includes("limit")&&r.includes("buy"))s=R.a.LimitBuy;else if(r.includes("limit")&&r.includes("sell"))s=R.a.LimitSell;else if(r.includes("stop")&&r.includes("buy"))s=R.a.StopBuy;else{if(!r.includes("stop")||!r.includes("sell"))throw Object(U.d)(t,"ERROR: Invalid Order Type passed into placeOrder()");s=R.a.StopSell}if((o=o.toLowerCase()).includes("l"))l=R.b.Long;else{if(!o.includes("s"))throw Object(U.d)(t,"ERROR: Invalid Position Type passed into placeOrder()");l=R.b.Short}var u={stock:c,shares:i,price:a,type:s,pos:l};return Object(R.f)(u,t)},getOrders:function(){if(t.checkingRam)return Z("getOrders",g.CONSTANTS.ScriptBuySellStockRamCost);if(n("getOrders",g.CONSTANTS.ScriptBuySellStockRamCost),!S.a.hasTixApiAccess)throw Object(U.d)(t,"You don't have TIX API Access! Cannot use getOrders()");if(8!==S.a.bitNodeN&&!(ae&&se>=3))throw Object(U.d)(t,"ERROR: Cannot use getOrders(). You must either be in BitNode-8 or have Level 3 of Source-File 8");const e={},i=R.c.Orders;for(let t in i){const n=i[t];if(n.constructor===Array&&n.length>0){e[t]=[];for(let i=0;i=Object(w.b)())return t.log(`ERROR: You have reached the maximum limit of ${Object(w.b)()} servers. You cannot purchase any more.`),"";const r=Object(w.a)(i);if(r===1/0)return t.log("ERROR: 'purchaseServer()' failed due to an invalid 'ram' argument"),1/0;if(S.a.money.lt(r))return t.log("ERROR: Not enough money to purchase server. Need $"+Object($.formatNumber)(r,2)),"";var o=new A.d({ip:Object(q.a)(),hostname:a,organizationName:"",isConnectedTo:!1,adminRights:!0,purchasedByPlayer:!0,maxRam:i});Object(A.a)(o),S.a.purchasedServers.push(o.ip);var s=S.a.getHomeComputer();return s.serversOnNetwork.push(o.ip),o.serversOnNetwork.push(s.ip),S.a.loseMoney(r),null==t.disableLogs.ALL&&null==t.disableLogs.purchaseServer&&t.scriptRef.log("Purchased new server with hostname "+o.hostname+" for $"+Object($.formatNumber)(r,2)),o.hostname},deleteServer:function(e){if(t.checkingRam)return Z("deleteServer",g.CONSTANTS.ScriptPurchaseServerRamCost);n("deleteServer",g.CONSTANTS.ScriptPurchaseServerRamCost);var i=String(e);i=i.replace(/\s\s+/g,"");var a=Object(A.c)(i);if(null==a)return t.scriptRef.log("ERROR: Could not find server with hostname "+i+". deleteServer() failed"),!1;if(!a.purchasedByPlayer||"home"===a.hostname)return t.scriptRef.log("ERROR: Server "+a.hostname+" is not a purchased server. Cannot be deleted. deleteServer() failed"),!1;var r=a.ip;if(a.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(a.runningScripts.length>0)return t.scriptRef.log("ERROR: Cannot delete server "+a.hostname+" because it still has scripts running."),!1;for(var o=!1,s=0;sg.CONSTANTS.NumNetscriptPorts)throw Object(U.d)(t,"ERROR: Trying to write to invalid port: "+e+". Only ports 1-"+g.CONSTANTS.NumNetscriptPorts+" are valid.");if(null==(e=F.a[e-1])||!(e instanceof H.a))throw Object(U.d)(t,"Could not find port: "+e+". This is a bug contact the game developer");return e.write(i)},tryWrite:function(e,i=""){if(t.checkingRam)return Z("tryWrite",g.CONSTANTS.ScriptReadWriteRamCost);if(n("tryWrite",g.CONSTANTS.ScriptReadWriteRamCost),isNaN(e))throw Object(U.d)(t,"Invalid argument passed in for tryWrite: "+e);if((e=Math.round(e))<1||e>g.CONSTANTS.NumNetscriptPorts)throw Object(U.d)(t,"ERROR: tryWrite() called on invalid port: "+e+". Only ports 1-"+g.CONSTANTS.NumNetscriptPorts+" are valid.");if(null==(e=F.a[e-1])||!(e instanceof H.a))throw Object(U.d)(t,"Could not find port: "+e+". This is a bug contact the game developer");return e.tryWrite(i)},read:function(e){if(t.checkingRam)return Z("read",g.CONSTANTS.ScriptReadWriteRamCost);if(n("read",g.CONSTANTS.ScriptReadWriteRamCost),isNaN(e)){if(Object(Y.isString)(e)){let n=e,i=Object(A.e)(t.serverIp);if(null==i)throw Object(U.d)(t,"Error getting Server for this script in read(). This is a bug please contact game dev");if(Object(P.e)(n)){let e=t.getScriptOnServer(n);return null==e?"":e.code}{let e=Object(B.getTextFile)(n,i);return null!==e?e.text:""}}throw Object(U.d)(t,"Invalid argument passed in for read(): "+e)}if((e=Math.round(e))<1||e>g.CONSTANTS.NumNetscriptPorts)throw Object(U.d)(t,"ERROR: Trying to read from invalid port: "+e+". Only ports 1-"+g.CONSTANTS.NumNetscriptPorts+" are valid.");if(null==(e=F.a[e-1])||!(e instanceof H.a))throw Object(U.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 Z("peek",g.CONSTANTS.ScriptReadWriteRamCost);if(n("peek",g.CONSTANTS.ScriptReadWriteRamCost),isNaN(e))throw Object(U.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(U.d)(t,"ERROR: peek() called with invalid argument. Must be a port number between 1 and "+g.CONSTANTS.NumNetscriptPorts);if(null==(e=F.a[e-1])||!(e instanceof H.a))throw Object(U.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 Z("clear",g.CONSTANTS.ScriptReadWriteRamCost);if(n("clear",g.CONSTANTS.ScriptReadWriteRamCost),!isNaN(e)){if((e=Math.round(e))<1||e>g.CONSTANTS.NumNetscriptPorts)throw Object(U.d)(t,"ERROR: Trying to clear invalid port: "+e+". Only ports 1-"+g.CONSTANTS.NumNetscriptPorts+" are valid");if(null==(e=F.a[e-1])||!(e instanceof H.a))throw Object(U.d)(t,"ERROR: Could not find port: "+e+". This is a bug contact the game developer");return e.clear()}if(!Object(Y.isString)(e))throw Object(U.d)(t,"Invalid argument passed in for clear(): "+e);var i=e,a=Object(A.e)(t.serverIp);if(null==a)throw Object(U.d)(t,"Error getting Server for this script in clear(). This is a bug please contact game dev");var r=Object(B.getTextFile)(i,a);return null!=r&&r.write(""),0},getPortHandle:function(e){if(t.checkingRam)return Z("getPortHandle",10*g.CONSTANTS.ScriptReadWriteRamCost);if(n("getPortHandle",10*g.CONSTANTS.ScriptReadWriteRamCost),isNaN(e))throw Object(U.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(U.d)(t,"ERROR: getPortHandle() called with invalid port number: "+e+". Only ports 1-"+g.CONSTANTS.NumNetscriptPorts+" are valid");if(null==(e=F.a[e-1])||!(e instanceof H.a))throw Object(U.d)(t,"ERROR: Could not find port: "+e+". This is a bug contact the game developer");return e},rm:function(e,i){if(t.checkingRam)return Z("rm",g.CONSTANTS.ScriptReadWriteRamCost);n("rm",g.CONSTANTS.ScriptReadWriteRamCost),null!=i&&""!==i||(i=t.serverIp);var a=Object(A.e)(i);if(null==a)throw Object(U.d)(t,`Invalid server specified for rm(): ${i}`);if(e.includes(".exe")){for(var r=0;r{Object(J.removeElementById)(n),e(!0)}}),r=Object(z.createElement)("button",{class:"popup-box-button",innerText:"No",clickListener:()=>{Object(J.removeElementById)(n),e(!1)}});Object(V.createPopup)(n,[i,a,r])})},wget:async function(n,i,a=t.serverIp){if(t.checkingRam)return 0;if(!Object(P.e)(i)&&!i.endsWith(".txt"))return workerSript.log(`ERROR: wget() failed because of an invalid target file: ${i}. Target file must be a script or text file`),Promise.resolve(!1);var r=ne(a,"wget");return new Promise(function(o,s){e.get(n,function(e){let n;return(n=Object(P.e)(i)?r.writeToScriptFile(i,e):r.writeToTextFile(i,e)).success?n.overwritten?(t.log(`wget() successfully retrieved content and overwrote ${i} on ${a}`),o(!0)):(t.log(`wget successfully retrieved content to new file ${i} on ${a}`),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?Z("getFavorToDonate",g.CONSTANTS.ScriptGetFavorToDonate):(n("getFavorToDonate",g.CONSTANTS.ScriptGetFavorToDonate),Math.floor(g.CONSTANTS.BaseFavorToDonate*l.BitNodeMultipliers.RepToDonateToFaction))},universityCourse:function(e,i){var a=g.CONSTANTS.ScriptSingularityFn1RamCost;if(4!==S.a.bitNodeN&&(a*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return Z("universityCourse",a);if(n("universityCourse",a),4!=S.a.bitNodeN&&!(ee&&oe>=1))throw Object(U.d)(t,"Cannot run universityCourse(). It is a Singularity Function and requires SourceFile-4 (level 1) to run.");if(!T.c){if(S.a.isWorking){var r=S.a.singularityStopWork();null==t.disableLogs.ALL&&null==t.disableLogs.universityCourse&&t.scriptRef.log(r)}var o,s,l;switch(e.toLowerCase()){case C.Locations.AevumSummitUniversity.toLowerCase():if(S.a.city!=C.Locations.Aevum)return t.scriptRef.log("ERROR: You cannot study at Summit University because you are not in Aevum. universityCourse() failed"),!1;S.a.location=C.Locations.AevumSummitUniversity,o=4,s=3;break;case C.Locations.Sector12RothmanUniversity.toLowerCase():if(S.a.city!=C.Locations.Sector12)return t.scriptRef.log("ERROR: You cannot study at Rothman University because you are not in Sector-12. universityCourse() failed"),!1;S.a.location=C.Locations.Sector12RothmanUniversity,o=3,s=2;break;case C.Locations.VolhavenZBInstituteOfTechnology.toLowerCase():if(S.a.city!=C.Locations.Volhaven)return t.scriptRef.log("ERROR: You cannot study at ZB Institute of Technology because you are not in Volhaven. universityCourse() failed"),!1;S.a.location=C.Locations.VolhavenZBInstituteOfTechnology,o=5,s=4;break;default:return t.scriptRef.log("Invalid university name: "+e+". universityCourse() failed"),!1}switch(i.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: "+i+". universityCourse() failed"),!1}return S.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,i){var a=g.CONSTANTS.ScriptSingularityFn1RamCost;if(4!==S.a.bitNodeN&&(a*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return Z("gymWorkout",a);if(n("gymWorkout",a),4!=S.a.bitNodeN&&!(ee&&oe>=1))throw Object(U.d)(t,"Cannot run gymWorkout(). It is a Singularity Function and requires SourceFile-4 (level 1) to run.");if(!T.c){if(S.a.isWorking){var r=S.a.singularityStopWork();null==t.disableLogs.ALL&&null==t.disableLogs.gymWorkout&&t.scriptRef.log(r)}var o,s;switch(e.toLowerCase()){case C.Locations.AevumCrushFitnessGym.toLowerCase():if(S.a.city!=C.Locations.Aevum)return t.scriptRef.log("ERROR: You cannot workout at Crush Fitness because you are not in Aevum. gymWorkout() failed"),!1;S.a.location=C.Locations.AevumCrushFitnessGym,o=3,s=2;break;case C.Locations.AevumSnapFitnessGym.toLowerCase():if(S.a.city!=C.Locations.Aevum)return t.scriptRef.log("ERROR: You cannot workout at Snap Fitness because you are not in Aevum. gymWorkout() failed"),!1;S.a.location=C.Locations.AevumSnapFitnessGym,o=10,s=5;break;case C.Locations.Sector12IronGym.toLowerCase():if(S.a.city!=C.Locations.Sector12)return t.scriptRef.log("ERROR: You cannot workout at Iron Gym because you are not in Sector-12. gymWorkout() failed"),!1;S.a.location=C.Locations.Sector12IronGym,o=1,s=1;break;case C.Locations.Sector12PowerhouseGym.toLowerCase():if(S.a.city!=C.Locations.Sector12)return t.scriptRef.log("ERROR: You cannot workout at Powerhouse Gym because you are not in Sector-12. gymWorkout() failed"),!1;S.a.location=C.Locations.Sector12PowerhouseGym,o=20,s=10;break;case C.Locations.VolhavenMilleniumFitnessGym.toLowerCase():if(S.a.city!=C.Locations.Volhaven)return t.scriptRef.log("ERROR: You cannot workout at Millenium Fitness Gym because you are not in Volhaven. gymWorkout() failed"),!1;S.a.location=C.Locations.VolhavenMilleniumFitnessGym,o=7,s=4;break;default:return t.scriptRef.log("Invalid gym name: "+e+". gymWorkout() failed"),!1}switch(i.toLowerCase()){case"strength".toLowerCase():case"str".toLowerCase():S.a.startClass(o,s,g.CONSTANTS.ClassGymStrength);break;case"defense".toLowerCase():case"def".toLowerCase():S.a.startClass(o,s,g.CONSTANTS.ClassGymDefense);break;case"dexterity".toLowerCase():case"dex".toLowerCase():S.a.startClass(o,s,g.CONSTANTS.ClassGymDexterity);break;case"agility".toLowerCase():case"agi".toLowerCase():S.a.startClass(o,s,g.CONSTANTS.ClassGymAgility);break;default:return t.scriptRef.log("Invalid stat: "+i+". gymWorkout() failed"),!1}return null==t.disableLogs.ALL&&null==t.disableLogs.gymWorkout&&t.scriptRef.log("Started training "+i+" at "+e),!0}t.scriptRef.log("ERROR: gymWorkout() failed because you are in the middle of a mission.")},travelToCity(e){var i=g.CONSTANTS.ScriptSingularityFn1RamCost;if(4!==S.a.bitNodeN&&(i*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return Z("travelToCity",i);if(n("travelToCity",i),4!=S.a.bitNodeN&&!(ee&&oe>=1))throw Object(U.d)(t,"Cannot run travelToCity(). It is a Singularity Function and requires SourceFile-4 (level 1) to run.");switch(e){case C.Locations.Aevum:case C.Locations.Chongqing:case C.Locations.Sector12:case C.Locations.NewTokyo:case C.Locations.Ishima:case C.Locations.Volhaven:if(S.a.money.lt(g.CONSTANTS.TravelCost))throw t.scriptRef.log("ERROR: not enough money to travel with travelToCity()."),Object(U.d)(t,"ERROR: not enough money to travel with travelToCity().");return S.a.loseMoney(g.CONSTANTS.TravelCost),S.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!==S.a.bitNodeN&&(e*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return Z("purchaseTor",e);if(n("purchaseTor",e),4!=S.a.bitNodeN&&!(ee&&oe>=1))throw Object(U.d)(t,"Cannot run purchaseTor(). It is a Singularity Function and requires SourceFile-4 (level 1) to run.");if(null!=x.a["Darkweb Server"])return t.scriptRef.log("You already have a TOR router! purchaseTor() failed"),!1;if(S.a.money.lt(g.CONSTANTS.TorRouterCost))return t.scriptRef.log("ERROR: You cannot afford to purchase a Tor router. purchaseTor() failed"),!1;S.a.loseMoney(g.CONSTANTS.TorRouterCost);var i=new A.d({ip:Object(q.a)(),hostname:"darkweb",organizationName:"",isConnectedTo:!1,adminRights:!1,purchasedByPlayer:!1,maxRam:1});Object(A.a)(i),x.a.addIp("Darkweb Server",i.ip);const a=document.getElementById("location-purchase-tor");return a.setAttribute("class","a-link-button-bought"),a.innerHTML="TOR Router - Purchased",S.a.getHomeComputer().serversOnNetwork.push(i.ip),i.serversOnNetwork.push(S.a.getHomeComputer().ip),S.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 i=g.CONSTANTS.ScriptSingularityFn1RamCost;if(4!==S.a.bitNodeN&&(i*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return Z("purchaseProgram",i);if(n("purchaseProgram",i),4!=S.a.bitNodeN&&!(ee&&oe>=1))throw Object(U.d)(t,"Cannot run purchaseProgram(). It is a Singularity Function and requires SourceFile-4 (level 1) to run.");if(null==x.a["Darkweb Server"])return t.scriptRef.log("ERROR: You do not have the TOR router. purchaseProgram() failed."),!1;e=e.toLowerCase();let a=null;for(const t in _.DarkWebItems){const n=_.DarkWebItems[t];n.program.toLowerCase()==e&&(a=n)}return null==a?(t.scriptRef.log("ERROR: Invalid program name passed into purchaseProgram()."),!1):S.a.money.lt(a.price)?(t.scriptRef.log("Not enough money to purchase "+a.program),!1):S.a.hasProgram(a.program)?(t.scriptRef.log("You already have the "+a.program+" program"),!0):(S.a.loseMoney(a.price),S.a.getHomeComputer().programs.push(a.program),null==t.disableLogs.ALL&&null==t.disableLogs.purchaseProgram&&t.scriptRef.log("You have purchased the "+a.program+" program. The new program can be found on your home computer."),!0)},getStats:function(){var e=g.CONSTANTS.ScriptSingularityFn1RamCost/4;if(4!==S.a.bitNodeN&&(e*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return Z("getStats",e);if(n("getStats",e),4!=S.a.bitNodeN&&!(ee&&oe>=1))throw Object(U.d)(t,"Cannot run getStats(). It is a Singularity Function and requires SourceFile-4 (level 1) to run.");return{hacking:S.a.hacking_skill,strength:S.a.strength,defense:S.a.defense,dexterity:S.a.dexterity,agility:S.a.agility,charisma:S.a.charisma,intelligence:S.a.intelligence}},getCharacterInformation:function(){var e=g.CONSTANTS.ScriptSingularityFn1RamCost/4;if(4!==S.a.bitNodeN&&(e*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return Z("getCharacterInformation",e);if(n("getCharacterInformation",e),4!=S.a.bitNodeN&&!(ee&&oe>=1))throw Object(U.d)(t,"Cannot run getCharacterInformation(). It is a Singularity Function and requires SourceFile-4 (level 1) to run.");return{bitnode:S.a.bitNodeN,city:S.a.city,factions:S.a.factions.slice(),hp:S.a.hp,jobs:Object.keys(S.a.jobs),jobTitles:Object.values(S.a.jobs),maxHp:S.a.max_hp,mult:{agility:S.a.agility_mult,agilityExp:S.a.agility_exp_mult,companyRep:S.a.company_rep_mult,crimeMoney:S.a.crime_money_mult,crimeSuccess:S.a.crime_success_mult,defense:S.a.defense_mult,defenseExp:S.a.defense_exp_mult,dexterity:S.a.dexterity_mult,dexterityExp:S.a.dexterity_exp_mult,factionRep:S.a.faction_rep_mult,hacking:S.a.hacking_mult,hackingExp:S.a.hacking_exp_mult,strength:S.a.strength_mult,strengthExp:S.a.strength_exp_mult,workMoney:S.a.work_money_mult},timeWorked:S.a.timeWorked,tor:x.a.hasOwnProperty("Darkweb Server"),workHackExpGain:S.a.workHackExpGained,workStrExpGain:S.a.workStrExpGained,workDefExpGain:S.a.workDefExpGained,workDexExpGain:S.a.workDexExpGained,workAgiExpGain:S.a.workAgiExpGained,workChaExpGain:S.a.workChaExpGained,workRepGain:S.a.workRepGained,workMoneyGain:S.a.workMoneyGained}},isBusy:function(){var e=g.CONSTANTS.ScriptSingularityFn1RamCost/4;if(4!==S.a.bitNodeN&&(e*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return Z("isBusy",e);if(n("isBusy",e),4!=S.a.bitNodeN&&!(ee&&oe>=1))throw Object(U.d)(t,"Cannot run isBusy(). It is a Singularity Function and requires SourceFile-4 (level 1) to run.");return S.a.isWorking},stopAction:function(){var e=g.CONSTANTS.ScriptSingularityFn1RamCost/2;if(4!==S.a.bitNodeN&&(e*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return Z("stopAction",e);if(n("stopAction",e),4!=S.a.bitNodeN&&!(ee&&oe>=1))throw Object(U.d)(t,"Cannot run stopAction(). It is a Singularity Function and requires SourceFile-4 (level 1) to run.");if(S.a.isWorking){var i=S.a.singularityStopWork();return null==t.disableLogs.ALL&&null==t.disableLogs.stopAction&&t.scriptRef.log(i),!0}return!1},upgradeHomeRam:function(){var e=g.CONSTANTS.ScriptSingularityFn2RamCost;if(4!==S.a.bitNodeN&&(e*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return Z("upgradeHomeRam",e);if(n("upgradeHomeRam",e),4!=S.a.bitNodeN&&!(ee&&oe>=2))throw Object(U.d)(t,"Cannot run upgradeHomeRam(). It is a Singularity Function and requires SourceFile-4 (level 2) to run.");const i=S.a.getHomeComputer();if(i.maxRam>=g.CONSTANTS.HomeComputerMaxRam)return t.log("ERROR: upgradeHomeRam() failed because your home computer is at max RAM"),!1;const a=S.a.getUpgradeHomeRamCost();return S.a.money.lt(a)?(t.scriptRef.log("ERROR: upgradeHomeRam() failed because you don't have enough money"),!1):(i.maxRam*=2,S.a.loseMoney(a),S.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 "+i.maxRam+"GB of RAM."),!0)},getUpgradeHomeRamCost:function(){var e=g.CONSTANTS.ScriptSingularityFn2RamCost/2;if(4!==S.a.bitNodeN&&(e*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return Z("getUpgradeHomeRamCost",e);if(n("getUpgradeHomeRamCost",e),4!=S.a.bitNodeN&&!(ee&&oe>=2))throw Object(U.d)(t,"Cannot run getUpgradeHomeRamCost(). It is a Singularity Function and requires SourceFile-4 (level 2) to run.");return S.a.getUpgradeHomeRamCost()},workForCompany:function(e){var i=g.CONSTANTS.ScriptSingularityFn2RamCost;if(4!==S.a.bitNodeN&&(i*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return Z("workForCompany",i);if(n("workForCompany",i),4!=S.a.bitNodeN&&!(ee&&oe>=2))throw Object(U.d)(t,"Cannot run workForCompany(). It is a Singularity Function and requires SourceFile-4 (level 2) to run.");if(null==e&&(e=S.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(S.a.jobs).includes(e))return t.scriptRef.log(`ERROR: workForCompany() failed because you do not have a job at ${e}`),!1;if(T.c)return t.scriptRef.log("ERROR: workForCompany() failed because you are in the middle of a mission."),!1;const a=S.a.jobs[e],r=d.CompanyPositions[a];if(""===a||!(r instanceof h.CompanyPosition))return t.scriptRef.log("ERROR: workForCompany() failed because you do not have a job"),!1;if(S.a.isWorking){var o=S.a.singularityStopWork();null==t.disableLogs.ALL&&null==t.disableLogs.workForCompany&&t.scriptRef.log(o)}return r.isPartTimeJob()?S.a.startWorkPartTime(e):S.a.startWork(e),null==t.disableLogs.ALL&&null==t.disableLogs.workForCompany&&t.log(`Began working at ${S.a.companyName} as a ${a}`),!0},applyToCompany:function(e,i){var a,r=g.CONSTANTS.ScriptSingularityFn2RamCost;if(4!==S.a.bitNodeN&&(r*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return Z("applyToCompany",r);if(n("applyToCompany",r),4!=S.a.bitNodeN&&!(ee&&oe>=2))throw Object(U.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(S.a.location=e,i.toLowerCase()){case"software":a=S.a.applyForSoftwareJob(!0);break;case"software consultant":a=S.a.applyForSoftwareConsultantJob(!0);break;case"it":a=S.a.applyForItJob(!0);break;case"security engineer":a=S.a.applyForSecurityEngineerJob(!0);break;case"network engineer":a=S.a.applyForNetworkEngineerJob(!0);break;case"business":a=S.a.applyForBusinessJob(!0);break;case"business consultant":a=S.a.applyForBusinessConsultantJob(!0);break;case"security":a=S.a.applyForSecurityJob(!0);break;case"agent":a=S.a.applyForAgentJob(!0);break;case"employee":a=S.a.applyForEmployeeJob(!0);break;case"part-time employee":a=S.a.applyForPartTimeEmployeeJob(!0);break;case"waiter":a=S.a.applyForWaiterJob(!0);break;case"part-time waiter":a=S.a.applyForPartTimeWaiterJob(!0);break;default:return t.scriptRef.log("ERROR: Invalid job passed into applyToCompany: "+i+". applyToCompany() failed"),!1}return Object(Y.isString)(a)?(t.scriptRef.log(a),!1):(a?null==t.disableLogs.ALL&&null==t.disableLogs.applyToCompany&&t.log(`You were offered a new job at ${e} as a ${S.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 ${i} field.`),a)},getCompanyRep:function(e){var i=g.CONSTANTS.ScriptSingularityFn2RamCost/2;if(4!==S.a.bitNodeN&&(i*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return Z("getCompanyRep",i);if(n("getCompanyRep",i),4!=S.a.bitNodeN&&!(ee&&oe>=2))throw Object(U.d)(t,"Cannot run getCompanyRep(). It is a Singularity Function and requires SourceFile-4 (level 2) to run.");var a=m.Companies[e];return null!=a&&a instanceof p.Company?a.playerReputation:(t.scriptRef.log("ERROR: Invalid companyName passed into getCompanyRep(): "+e),-1)},getCompanyFavor:function(e){var i=g.CONSTANTS.ScriptSingularityFn2RamCost/4;if(4!==S.a.bitNodeN&&(i*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return Z("getCompanyFavor",i);if(n("getCompanyFavor",i),4!=S.a.bitNodeN&&!(ee&&oe>=2))throw Object(U.d)(t,"Cannot run getCompanyFavor(). It is a Singularity Function and requires SourceFile-4 (level 2) to run.");var a=m.Companies[e];return null!=a&&a instanceof p.Company?a.favor:(t.scriptRef.log("ERROR: Invalid companyName passed into getCompanyFavor(): "+e),-1)},getCompanyFavorGain:function(e){var i=g.CONSTANTS.ScriptSingularityFn2RamCost/4;if(4!==S.a.bitNodeN&&(i*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return Z("getCompanyFavorGain",i);if(n("getCompanyFavorGain",i),4!=S.a.bitNodeN&&!(ee&&oe>=2))throw Object(U.d)(t,"Cannot run getCompanyFavorGain(). It is a Singularity Function and requires SourceFile-4 (level 2) to run.");var a=m.Companies[e];return null!=a&&a instanceof p.Company?a.getFavorGain()[0]:(t.scriptRef.log("ERROR: Invalid companyName passed into getCompanyFavorGain(): "+e),-1)},checkFactionInvitations:function(){var e=g.CONSTANTS.ScriptSingularityFn2RamCost;if(4!==S.a.bitNodeN&&(e*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return Z("checkFactionInvitations",e);if(n("checkFactionInvitations",e),4!=S.a.bitNodeN&&!(ee&&oe>=2))throw Object(U.d)(t,"Cannot run checkFactionInvitations(). It is a Singularity Function and requires SourceFile-4 (level 2) to run.");return S.a.factionInvitations.slice()},joinFaction:function(e){var i=g.CONSTANTS.ScriptSingularityFn2RamCost;if(4!==S.a.bitNodeN&&(i*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return Z("joinFaction",i);if(n("joinFaction",i),4!=S.a.bitNodeN&&!(ee&&oe>=2))throw Object(U.d)(t,"Cannot run joinFaction(). It is a Singularity Function and requires SourceFile-4 (level 2) to run.");if(!Object(E.factionExists)(e))return t.scriptRef.log("ERROR: Faction specified in joinFaction() does not exist."),!1;if(!S.a.factionInvitations.includes(e))return t.scriptRef.log("ERROR: Cannot join "+e+" Faction because you have not been invited. joinFaction() failed"),!1;var a=E.Factions[e];Object(v.c)(a);for(var r=0;r=2))throw Object(U.d)(t,"Cannot run workForFaction(). It is a Singularity Function and requires SourceFile-4 (level 2) to run.");if(S.a.inGang()&&void 0!==f.a[e])t.scriptRef.log("ERROR: Faction specified in workForFaction() does not offer work at the moment.");else{if(!T.c){if(!Object(E.factionExists)(e))return t.scriptRef.log("ERROR: Faction specified in workForFaction() does not exist."),!1;if(!S.a.factions.includes(e))return t.scriptRef.log("ERROR: workForFaction() failed because you are not a member of "+e),!1;if(S.a.isWorking){var r=S.a.singularityStopWork();null==t.disableLogs.ALL&&null==t.disableLogs.workForFaction&&t.scriptRef.log(r)}var o=E.Factions[e];switch(i.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)?(S.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)?(S.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)?(S.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(): "+i)}return!0}t.scriptRef.log("ERROR: workForFaction() failed because you are in the middle of a mission.")}},getFactionRep:function(e){var i=g.CONSTANTS.ScriptSingularityFn2RamCost/4;if(4!==S.a.bitNodeN&&(i*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return Z("getFactionRep",i);if(n("getFactionRep",i),4!=S.a.bitNodeN&&!(ee&&oe>=2))throw Object(U.d)(t,"Cannot run getFactionRep(). It is a Singularity Function and requires SourceFile-4 (level 2) to run.");return Object(E.factionExists)(e)?E.Factions[e].playerReputation:(t.scriptRef.log("ERROR: Faction specified in getFactionRep() does not exist."),-1)},getFactionFavor:function(e){var i=g.CONSTANTS.ScriptSingularityFn2RamCost;if(4!==S.a.bitNodeN&&(i*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return Z("getFactionFavor",i);if(n("getFactionFavor",i),4!=S.a.bitNodeN&&!(ee&&oe>=2))throw Object(U.d)(t,"Cannot run getFactionFavor(). It is a Singularity Function and requires SourceFile-4 (level 2) to run.");return Object(E.factionExists)(e)?E.Factions[e].favor:(t.scriptRef.log("ERROR: Faction specified in getFactionFavor() does not exist."),-1)},getFactionFavorGain:function(e){var i=g.CONSTANTS.ScriptSingularityFn2RamCost;if(4!==S.a.bitNodeN&&(i*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return Z("getFactionFavorGain",i);if(n("getFactionFavorGain",i),4!=S.a.bitNodeN&&!(ee&&oe>=2))throw Object(U.d)(t,"Cannot run getFactionFavorGain(). It is a Singularity Function and requires SourceFile-4 (level 2) to run.");return Object(E.factionExists)(e)?E.Factions[e].getFavorGain()[0]:(t.scriptRef.log("ERROR: Faction specified in getFactionFavorGain() does not exist."),-1)},donateToFaction:function(e,i){var a=g.CONSTANTS.ScriptSingularityFn3RamCost;if(4!==S.a.bitNodeN&&(a*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return Z("donateToFaction",a);if(n("donateToFaction",a),4!=S.a.bitNodeN&&!(ee&&oe>=3))throw Object(U.d)(t,"Cannot run donateToFaction(). It is a Singularity Function and requires SourceFile-4 (level 3) to run.");if(!Object(E.factionExists)(e))return t.log(`ERROR: Faction specified in donateToFaction() does not exist: ${e}`),!1;if("number"!=typeof i||i<=0)return t.log(`ERROR: Invalid donation amount specified in donateToFaction(): ${i}. Must be numeric and positive`),!1;if(S.a.money.lt(i))return t.log(`ERROR: You do not have enough money to donate $${i} to ${e}`),!1;var r=Math.round(g.CONSTANTS.BaseFavorToDonate*l.BitNodeMultipliers.RepToDonateToFaction);if(E.Factions[e].favor=3))throw Object(U.d)(t,"Cannot run createProgram(). It is a Singularity Function and requires SourceFile-4 (level 3) to run.");if(T.c)return void t.scriptRef.log("ERROR: createProgram() failed because you are in the middle of a mission.");if(S.a.isWorking){var a=S.a.singularityStopWork();null==t.disableLogs.ALL&&null==t.disableLogs.createProgram&&t.scriptRef.log(a)}e=e.toLowerCase();let r=null;for(const t in M.Programs)M.Programs[t].name.toLowerCase()==e&&(r=M.Programs[t]);return null==r?(t.scriptRef.log("ERROR: createProgram() failed because the specified program does not exist: "+e),!1):S.a.hasProgram(r.name)?(t.scriptRef.log("ERROR: createProgram() failed because you already have the "+r.name+" program"),!1):r.create.req(S.a)?(S.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 i=g.CONSTANTS.ScriptSingularityFn3RamCost;if(4!==S.a.bitNodeN&&(i*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return Z("commitCrime",i);if(n("commitCrime",i),4!=S.a.bitNodeN&&!(ee&&oe>=3))throw Object(U.d)(t,"Cannot run commitCrime(). It is a Singularity Function and requires SourceFile-4 (level 3) to run.");if(T.c)return void t.scriptRef.log("ERROR: commitCrime() failed because you are in the middle of a mission.");if(S.a.isWorking){var a=S.a.singularityStopWork();null==t.disableLogs.ALL&&null==t.disableLogs.commitCrime&&t.scriptRef.log(a)}switch(S.a.city){case C.Locations.Aevum:S.a.location=C.Locations.AevumSlums;break;case C.Locations.Chongqing:S.a.location=C.Locations.ChongqingSlums;break;case C.Locations.Sector12:S.a.location=C.Locations.Sector12Slums;break;case C.Locations.NewTokyo:S.a.location=C.Locations.NewTokyoSlums;break;case C.Locations.Ishima:S.a.location=C.Locations.IshimaSlums;break;case C.Locations.Volhaven:S.a.location=C.Locations.VolhavenSlums;break;default:console.log("Invalid Player.city value")}const r=Object(c.findCrime)(e.toLowerCase());if(null==r)throw Object(U.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(S.a,1,{workerscript:t})},getCrimeChance:function(e){var i=g.CONSTANTS.ScriptSingularityFn3RamCost;if(4!==S.a.bitNodeN&&(i*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return Z("getCrimeChance",i);if(n("getCrimeChance",i),4!=S.a.bitNodeN&&!(ee&&oe>=3))throw Object(U.d)(t,"Cannot run getCrimeChance(). It is a Singularity Function and requires SourceFile-4 (level 3) to run.");const a=Object(c.findCrime)(e.toLowerCase());if(null==a)throw Object(U.d)(t,"Invalid crime passed into getCrimeChance(): "+a);return a.successRate(S.a)},getOwnedAugmentations:function(e=!1){var i=g.CONSTANTS.ScriptSingularityFn3RamCost;if(4!==S.a.bitNodeN&&(i*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return Z("getOwnedAugmentations",i);if(n("getOwnedAugmentations",i),4!=S.a.bitNodeN&&!(ee&&oe>=3))throw Object(U.d)(t,"Cannot run getOwnedAugmentations(). It is a Singularity Function and requires SourceFile-4 (level 3) to run.");for(var a=[],r=0;r=3))throw Object(U.d)(t,"Cannot run getOwnedSourceFiles(). It is a Singularity Function and requires SourceFile-4 (level 3) to run.");let i=[];for(let e=0;e=3))throw Object(U.d)(t,"Cannot run getAugmentationsFromFaction(). It is a Singularity Function and requires SourceFile-4 (level 3) to run.");if(!Object(E.factionExists)(e))return t.scriptRef.log("ERROR: getAugmentationsFromFaction() failed. Invalid faction name passed in (this is case-sensitive): "+e),[];for(var a=E.Factions[e],r=[],o=0;o=3))throw Object(U.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 i=g.CONSTANTS.ScriptSingularityFn3RamCost;if(4!==S.a.bitNodeN&&(i*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return Z("getAugmentationCost",i);if(n("getAugmentationCost",i),4!=S.a.bitNodeN&&!(ee&&oe>=3))throw Object(U.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 a=r.Augmentations[e];return[a.baseRepRequirement,a.baseCost]},purchaseAugmentation:function(e,i){var o=g.CONSTANTS.ScriptSingularityFn3RamCost;if(4!==S.a.bitNodeN&&(o*=g.CONSTANTS.ScriptSingularityFnRamMult),t.checkingRam)return Z("purchaseAugmentation",o);if(n("purchaseAugmentation",o),4!=S.a.bitNodeN&&!(ee&&oe>=3))throw Object(U.d)(t,"Cannot run purchaseAugmentation(). It is a Singularity Function and requires SourceFile-4 (level 3) to run.");var l=E.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(i))return t.scriptRef.log("ERROR: purchaseAugmentation() failed because the faction "+e+" does not contain the "+i+" augmentation"),!1;var c=r.Augmentations[i];if(null==c||!(c instanceof a.Augmentation))return t.scriptRef.log("ERROR: purchaseAugmentation() failed because of invalid augmentation name: "+i),!1;var u=!1;if(c.name===s.AugmentationNames.NeuroFluxGovernor&&(u=!0),!u){for(var p=0;p=3))throw Object(U.d)(t,"Cannot run installAugmentations(). It is a Singularity Function and requires SourceFile-4 (level 3) to run.");return 0===S.a.queuedAugmentations.length?(t.scriptRef.log("ERROR: installAugmentations() failed because you do not have any Augmentations to be installed"),!1):(S.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 Z("getMemberNames",g.CONSTANTS.ScriptGangApiBaseRamCost/4);n("getMemberNames",g.CONSTANTS.ScriptGangApiBaseRamCost/4),W.a(t,"getMemberNames");try{const e=[];for(const t of S.a.gang.members)e.push(t.name);return e}catch(e){throw Object(U.d)(t,W.b("getMemberNames",e))}},getGangInformation:function(){if(t.checkingRam)return Z("getGangInformation",g.CONSTANTS.ScriptGangApiBaseRamCost/2);n("getGangInformation",g.CONSTANTS.ScriptGangApiBaseRamCost/2),W.a(t,"getGangInformation");try{return{faction:S.a.gang.facName,isHacking:S.a.gang.isHackingGang,moneyGainRate:S.a.gang.moneyGainRate,power:S.a.gang.getPower(),respect:S.a.gang.respect,respectGainRate:S.a.gang.respectGainRate,territory:S.a.gang.getTerritory(),territoryClashChance:S.a.gang.territoryClashChance,territoryWarfareEngaged:S.a.gang.territoryWarfareEngaged,wantedLevel:S.a.gang.wanted,wantedLevelGainRate:S.a.gang.wantedGainRate}}catch(e){throw Object(U.d)(t,W.b("getGangInformation",e))}},getOtherGangInformation:function(){if(t.checkingRam)return Z("getOtherGangInformation",g.CONSTANTS.ScriptGangApiBaseRamCost/2);n("getOtherGangInformation",g.CONSTANTS.ScriptGangApiBaseRamCost/2),W.a(t,"getOtherGangInformation");try{return Object.assign(f.a)}catch(e){throw Object(U.d)(t,W.b("getOtherGangInformation",e))}},getMemberInformation:function(e){if(t.checkingRam)return Z("getMemberInformation",g.CONSTANTS.ScriptGangApiBaseRamCost/2);n("getMemberInformation",g.CONSTANTS.ScriptGangApiBaseRamCost/2),W.a(t,"getMemberInformation");try{for(const t of S.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(U.d)(t,W.b("getMemberInformation",e))}},canRecruitMember:function(){if(t.checkingRam)return Z("canRecruitMember",g.CONSTANTS.ScriptGangApiBaseRamCost/4);n("canRecruitMember",g.CONSTANTS.ScriptGangApiBaseRamCost/4),W.a(t,"canRecruitMember");try{return S.a.gang.canRecruitMember()}catch(e){throw Object(U.d)(t,W.b("canRecruitMember",e))}},recruitMember:function(e){if(t.checkingRam)return Z("recruitMember",g.CONSTANTS.ScriptGangApiBaseRamCost/2);n("recruitMember",g.CONSTANTS.ScriptGangApiBaseRamCost/2),W.a(t,"recruitMember");try{const n=S.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(U.d)(t,W.b("recruitMember",e))}},getTaskNames:function(){if(t.checkingRam)return Z("getTaskNames",g.CONSTANTS.ScriptGangApiBaseRamCost/4);n("getTaskNames",g.CONSTANTS.ScriptGangApiBaseRamCost/4),W.a(t,"getTaskNames");try{const e=S.a.gang.getAllTaskNames();return e.unshift("Unassigned"),e}catch(e){throw Object(U.d)(t,W.b("getTaskNames",e))}},setMemberTask:function(e,i){if(t.checkingRam)return Z("setMemberTask",g.CONSTANTS.ScriptGangApiBaseRamCost/2);n("setMemberTask",g.CONSTANTS.ScriptGangApiBaseRamCost/2),W.a(t,"setMemberTask");try{for(const n of S.a.gang.members)if(n.name===e){const a=n.assignToTask(i);return t.shouldLog("setMemberTask")&&(a?t.log(`Successfully assigned Gang Member ${e} to ${i} task`):t.log(`Failed to assign Gang Member ${e} to ${i} task. ${e} is now Unassigned`)),a}return t.log(`Invalid argument passed to gang.setMemberTask(). No gang member could be found with name ${e}`),!1}catch(e){throw Object(U.d)(t,W.b("setMemberTask",e))}},getEquipmentNames:function(){if(t.checkingRam)return Z("getEquipmentNames",g.CONSTANTS.ScriptGangApiBaseRamCost/4);n("getEquipmentNames",g.CONSTANTS.ScriptGangApiBaseRamCost/4),W.a(t,"getEquipmentNames");try{return S.a.gang.getAllUpgradeNames()}catch(e){throw Object(U.d)(t,W.b("getEquipmentNames",e))}},getEquipmentCost:function(e){if(t.checkingRam)return Z("getEquipmentCost",g.CONSTANTS.ScriptGangApiBaseRamCost/2);n("getEquipmentCost",g.CONSTANTS.ScriptGangApiBaseRamCost/2),W.a(t,"getEquipmentCost");try{return S.a.gang.getUpgradeCost(e)}catch(e){throw Object(U.d)(t,W.b("getEquipmentCost",e))}},getEquipmentType:function(e){if(t.checkingRam)return Z("getEquipmentType",g.CONSTANTS.ScriptGangApiBaseRamCost/2);n("getEquipmentType",g.CONSTANTS.ScriptGangApiBaseRamCost/2),W.a(t,"getEquipmentType");try{return S.a.gang.getUpgradeType(e)}catch(e){throw Object(U.d)(t,W.b("getEquipmentType",e))}},purchaseEquipment:function(e,i){if(t.checkingRam)return Z("purchaseEquipment",g.CONSTANTS.ScriptGangApiBaseRamCost);n("purchaseEquipment",g.CONSTANTS.ScriptGangApiBaseRamCost),W.a(t,"purchaseEquipment");try{for(const n of S.a.gang.members)if(n.name===e){const a=n.buyUpgrade(i,S.a,S.a.gang);return t.shouldLog("purchaseEquipment")&&(a?t.log(`Purchased ${i} for Gang member ${e}`):t.log(`Failed to purchase ${i} for Gang member ${e}`)),a}return t.log(`Invalid argument passed to gang.purchaseEquipment(). No gang member could be found with name ${e}`),!1}catch(e){throw Object(U.d)(t,W.b("purchaseEquipment",e))}},ascendMember:function(e){if(t.checkingRam)return Z("ascendMember",g.CONSTANTS.ScriptGangApiBaseRamCost);n("ascendMember",g.CONSTANTS.ScriptGangApiBaseRamCost),W.a(t,"ascendMember");try{for(const n of S.a.gang.members)if(n.name===e)return S.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(U.d)(t,W.b("ascendMember",e))}},setTerritoryWarfare:function(e){if(t.checkingRam)return Z("setTerritoryWarfare",g.CONSTANTS.ScriptGangApiBaseRamCost/2);n("setTerritoryWarfare",g.CONSTANTS.ScriptGangApiBaseRamCost/2),W.a(t,"setTerritoryWarfare");try{e?(S.a.gang.territoryWarfareEngaged=!0,t.shouldLog("setTerritoryWarfare")&&t.log("Engaging in Gang Territory Warfare")):(S.a.gang.territoryWarfareEngaged=!1,t.shouldLog("setTerritoryWarfare")&&t.log("Disengaging in Gang Territory Warfare"))}catch(e){throw Object(U.d)(t,W.b("setTerritoryWarfare",e))}},getChanceToWinClash:function(e){if(t.checkingRam)return Z("getChanceToWinClash",g.CONSTANTS.ScriptGangApiBaseRamCost);n("getChanceToWinClash",g.CONSTANTS.ScriptGangApiBaseRamCost),W.a(t,"getChanceToWinClash");try{if(null==f.a[e])return t.log(`Invalid gang specified in gang.getChanceToWinClash() : ${e}`),0;const n=f.a[S.a.gang.facName].power;return n/(f.a[e].power+n)}catch(e){throw Object(U.d)(t,W.b("getChanceToWinClash",e))}},getBonusTime:function(){if(t.checkingRam)return 0;W.a(t,"getBonusTime");try{return Math.round(S.a.gang.storedCycles/5)}catch(e){throw Object(U.d)(t,W.b("getBonusTime",e))}}},bladeburner:{getContractNames:function(){if(t.checkingRam)return Z("getContractNames",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost/10);if(n("getContractNames",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost/10),S.a.bladeburner instanceof u.a&&(7===S.a.bitNodeN||ie))return S.a.bladeburner.getContractNamesNetscriptFn();throw Object(U.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 Z("getOperationNames",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost/10);if(n("getOperationNames",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost/10),S.a.bladeburner instanceof u.a&&(7===S.a.bitNodeN||ie))return S.a.bladeburner.getOperationNamesNetscriptFn();throw Object(U.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 Z("getBlackOpNames",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost/10);if(n("getBlackOpNames",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost/10),S.a.bladeburner instanceof u.a&&(7===S.a.bitNodeN||ie))return S.a.bladeburner.getBlackOpNamesNetscriptFn();throw Object(U.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")},getGeneralActionNames:function(){if(t.checkingRam)return Z("getGeneralActionNames",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost/10);if(n("getGeneralActionNames",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost/10),S.a.bladeburner instanceof u.a&&(7===S.a.bitNodeN||ie))return S.a.bladeburner.getGeneralActionNamesNetscriptFn();throw Object(U.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 Z("getSkillNames",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost/10);if(n("getSkillNames",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost/10),S.a.bladeburner instanceof u.a&&(7===S.a.bitNodeN||ie))return S.a.bladeburner.getSkillNamesNetscriptFn();throw Object(U.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="",i=""){if(t.checkingRam)return Z("startAction",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);if(n("startAction",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),S.a.bladeburner instanceof u.a&&(7===S.a.bitNodeN||ie))try{return S.a.bladeburner.startActionNetscriptFn(e,i,t)}catch(e){throw Object(U.d)(t,"Bladeburner.startAction() failed with exception: "+e)}throw Object(U.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 Z("stopBladeburnerAction",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost/2);if(n("stopBladeburnerAction",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost/2),S.a.bladeburner instanceof u.a&&(7===S.a.bitNodeN||ie))return S.a.bladeburner.resetAction();throw Object(U.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 Z("getCurrentAction",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost/4);if(n("getCurrentAction",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost/4),S.a.bladeburner instanceof u.a&&(7===S.a.bitNodeN||ie))return S.a.bladeburner.getTypeAndNameFromActionId(S.a.bladeburner.action);throw Object(U.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="",i=""){if(t.checkingRam)return Z("getActionTime",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);if(n("getActionTime",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),S.a.bladeburner instanceof u.a&&(7===S.a.bitNodeN||ie))try{return S.a.bladeburner.getActionTimeNetscriptFn(e,i,t)}catch(e){throw Object(U.d)(t,"Bladeburner.getActionTime() failed with exception: "+e)}throw Object(U.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="",i=""){if(t.checkingRam)return Z("getActionEstimatedSuccessChance",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);if(n("getActionEstimatedSuccessChance",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),S.a.bladeburner instanceof u.a&&(7===S.a.bitNodeN||ie))try{return S.a.bladeburner.getActionEstimatedSuccessChanceNetscriptFn(e,i,t)}catch(e){throw Object(U.d)(t,"Bladeburner.getActionEstimatedSuccessChance() failed with exception: "+e)}throw Object(U.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="",i="",a){if(t.checkingRam)return Z("getActionRepGain",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);n("getActionRepGain",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),Object(j.a)(t,"getActionRepGain");try{var r=Object(j.b)("getActionAutolevel",e,i);const n=S.a.bladeburner.getActionIdFromTypeAndName(e,i);if(null==n)return t.log(r),-1;const s=S.a.bladeburner.getActionObject(n);return null==s?(t.log(r),-1):(o=null==a||isNaN(a)?Math.pow(s.rewardFac,s.level-1):Math.pow(s.rewardFac,a-1),s.rankGain*o*l.BitNodeMultipliers.BladeburnerRank);var o}catch(e){throw Object(U.d)(t,Object(j.c)("getActionAutolevel",e))}},getActionCountRemaining:function(e="",i=""){if(t.checkingRam)return Z("getActionCountRemaining",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);if(n("getActionCountRemaining",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),S.a.bladeburner instanceof u.a&&(7===S.a.bitNodeN||ie))try{return S.a.bladeburner.getActionCountRemainingNetscriptFn(e,i,t)}catch(e){throw Object(U.d)(t,"Bladeburner.getActionCountRemaining() failed with exception: "+e)}throw Object(U.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="",i=""){if(t.checkingRam)return Z("getActionMaxLevel",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);n("getActionMaxLevel",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),Object(j.a)(t,"getActionMaxLevel");try{var a=Object(j.b)("getActionMaxLevel",e,i);const n=S.a.bladeburner.getActionIdFromTypeAndName(e,i);if(null==n)return t.log(a),-1;const r=S.a.bladeburner.getActionObject(n);return null==r?(t.log(a),-1):r.maxLevel}catch(e){throw Object(U.d)(t,Object(j.c)("getActionMaxLevel",e))}},getActionCurrentLevel:function(e="",i=""){if(t.checkingRam)return Z("getActionCurrentLevel",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);n("getActionCurrentLevel",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),Object(j.a)(t,"getActionCurrentLevel");try{var a=Object(j.b)("getActionCurrentLevel",e,i);const n=S.a.bladeburner.getActionIdFromTypeAndName(e,i);if(null==n)return t.log(a),-1;const r=S.a.bladeburner.getActionObject(n);return null==r?(t.log(a),-1):r.level}catch(e){throw Object(U.d)(t,Object(j.c)("getActionCurrentLevel",e))}},getActionAutolevel:function(e="",i=""){if(t.checkingRam)return Z("getActionAutolevel",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);n("getActionAutolevel",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),Object(j.a)(t,"getActionAutolevel");try{var a=Object(j.b)("getActionAutolevel",e,i);const n=S.a.bladeburner.getActionIdFromTypeAndName(e,i);if(null==n)return t.log(a),!1;const r=S.a.bladeburner.getActionObject(n);return null==r?(t.log(a),!1):r.autoLevel}catch(e){throw Object(U.d)(t,Object(j.c)("getActionAutolevel",e))}},setActionAutolevel:function(e="",i="",a=!0){if(t.checkingRam)return Z("setActionAutolevel",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);n("setActionAutolevel",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),Object(j.a)(t,"setActionAutolevel");try{var r=Object(j.b)("setActionAutolevel",e,i);const n=S.a.bladeburner.getActionIdFromTypeAndName(e,i);if(null==n)return void t.log(r);const o=S.a.bladeburner.getActionObject(n);if(null==o)return void t.log(r);o.autoLevel=a}catch(e){throw Object(U.d)(t,Object(j.c)("setActionAutolevel",e))}},setActionLevel:function(e="",i="",a=1){if(t.checkingRam)return Z("setActionLevel",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);n("setActionLevel",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),Object(j.a)(t,"setActionLevel");try{var r=Object(j.b)("setActionLevel",e,i);const n=S.a.bladeburner.getActionIdFromTypeAndName(e,i);if(null==n)return void t.log(r);const o=S.a.bladeburner.getActionObject(n);if(null==o)return void t.log(r);if(a>o.maxLevel)return void t.log(`ERROR: bladeburner.${setActionLevel}() failed because level exceeds max level for given action.`);if(a<1)return void t.log(`ERROR: bladeburner.${setActionLevel}() failed because level is below 1.`);o.level=a}catch(e){throw Object(U.d)(t,Object(j.c)("setActionLevel",e))}},getRank:function(){if(t.checkingRam)return Z("getRank",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);if(n("getRank",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),S.a.bladeburner instanceof u.a&&(7===S.a.bitNodeN||ie))return S.a.bladeburner.rank;throw Object(U.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 Z("getSkillPoints",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);if(n("getSkillPoints",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),S.a.bladeburner instanceof u.a&&(7===S.a.bitNodeN||ie))return S.a.bladeburner.skillPoints;throw Object(U.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 Z("getSkillLevel",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);if(n("getSkillLevel",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),S.a.bladeburner instanceof u.a&&(7===S.a.bitNodeN||ie))try{return S.a.bladeburner.getSkillLevelNetscriptFn(e,t)}catch(e){throw Object(U.d)(t,"Bladeburner.getSkillLevel() failed with exception: "+e)}throw Object(U.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 Z("getSkillUpgradeCost",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);if(n("getSkillUpgradeCost",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),S.a.bladeburner instanceof u.a&&(7===S.a.bitNodeN||ie))try{return S.a.bladeburner.getSkillUpgradeCostNetscriptFn(e,t)}catch(e){throw Object(U.d)(t,"Bladeburner.getSkillUpgradeCost() failed with exception: "+e)}throw Object(U.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 Z("upgradeSkill",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);if(n("upgradeSkill",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),S.a.bladeburner instanceof u.a&&(7===S.a.bitNodeN||ie))try{return S.a.bladeburner.upgradeSkillNetscriptFn(e,t)}catch(e){throw Object(U.d)(t,"Bladeburner.upgradeSkill() failed with exception: "+e)}throw Object(U.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="",i=""){if(t.checkingRam)return Z("getTeamSize",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);if(n("getTeamSize",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),S.a.bladeburner instanceof u.a&&(7===S.a.bitNodeN||ie))try{return S.a.bladeburner.getTeamSizeNetscriptFn(e,i,t)}catch(e){throw Object(U.d)(t,"Bladeburner.getTeamSize() failed with exception: "+e)}throw Object(U.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="",i="",a){if(t.checkingRam)return Z("setTeamSize",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);if(n("setTeamSize",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),S.a.bladeburner instanceof u.a&&(7===S.a.bitNodeN||ie))try{return S.a.bladeburner.setTeamSizeNetscriptFn(e,i,a,t)}catch(e){throw Object(U.d)(t,"Bladeburner.setTeamSize() failed with exception: "+e)}throw Object(U.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 Z("getCityEstimatedPopulation",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);if(n("getCityEstimatedPopulation",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),S.a.bladeburner instanceof u.a&&(7===S.a.bitNodeN||ie))try{return S.a.bladeburner.getCityEstimatedPopulationNetscriptFn(e,t)}catch(e){throw Object(U.d)(t,"Bladeburner.getCityEstimatedPopulation() failed with exception: "+e)}throw Object(U.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 Z("getCityEstimatedCommunities",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);if(n("getCityEstimatedCommunities",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),S.a.bladeburner instanceof u.a&&(7===S.a.bitNodeN||ie))try{return S.a.bladeburner.getCityEstimatedCommunitiesNetscriptFn(e,t)}catch(e){throw Object(U.d)(t,"Bladeburner.getCityEstimatedCommunities() failed with exception: "+e)}throw Object(U.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 Z("getCityChaos",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);if(n("getCityChaos",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),S.a.bladeburner instanceof u.a&&(7===S.a.bitNodeN||ie))try{return S.a.bladeburner.getCityChaosNetscriptFn(e,t)}catch(e){throw Object(U.d)(t,"Bladeburner.getCityChaos() failed with exception: "+e)}throw Object(U.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 Z("getCity",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);if(n("getCity",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),S.a.bladeburner instanceof u.a&&(7===S.a.bitNodeN||ie))try{return S.a.bladeburner.city}catch(e){throw Object(U.d)(t,"Bladeburner.getCity() failed with exception: "+e)}throw Object(U.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 Z("switchCity",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);if(n("switchCity",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),S.a.bladeburner instanceof u.a&&(7===S.a.bitNodeN||ie))try{return S.a.bladeburner.switchCityNetscriptFn(e,t)}catch(e){throw Object(U.d)(t,"Bladeburner.switchCity() failed with exception: "+e)}throw Object(U.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 Z("getStamina",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);if(n("getStamina",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),S.a.bladeburner instanceof u.a&&(7===S.a.bitNodeN||ie))return[S.a.bladeburner.stamina,S.a.bladeburner.maxStamina];throw Object(U.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 Z("joinBladeburnerFaction",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);if(n("joinBladeburnerFaction",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),S.a.bladeburner instanceof u.a&&(7===S.a.bitNodeN||ie))return S.a.bladeburner.joinBladeburnerFactionNetscriptFn(t);throw Object(U.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 Z("joinBladeburnerDivision",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost);if(n("joinBladeburnerDivision",g.CONSTANTS.ScriptBladeburnerApiBaseRamCost),7===S.a.bitNodeN||ie)return S.a.bladeburner instanceof u.a||(S.a.strength>=100&&S.a.defense>=100&&S.a.dexterity>=100&&S.a.agility>=100?(S.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(U.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===S.a.bitNodeN||ie)return Math.round(S.a.bladeburner.storedCycles/5);throw Object(U.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,i,a=t.serverIp){if(t.checkingRam)return Z("attempt",g.CONSTANTS.ScriptCodingContractBaseRamCost);n("attempt",g.CONSTANTS.ScriptCodingContractBaseRamCost);const r=ce(i,a);if(null==r)return t.log(`ERROR: codingcontract.getData() failed because it could find the specified contract ${i} on server ${a}`),!1;e=String(e);const o=ne(a,"codingcontract.attempt()");if(r.isSolution(e)){const e=S.a.gainCodingContractReward(r.reward,r.getDifficulty());return t.log(`Successfully completed Coding Contract ${i}. Reward: ${e}`),o.removeContract(i),!0}return++r.tries,r.tries>=r.getMaxNumTries()?(t.log(`Coding Contract ${i} failed. Contract is now self-destructing`),o.removeContract(i)):t.log(`Coding Contract ${i} failed. ${r.getMaxNumTries()-r.tries} attempts remaining`),!1},getContractType:function(e,i=t.serverIp){if(t.checkingRam)return Z("getContractType",g.CONSTANTS.ScriptCodingContractBaseRamCost/2);n("getContractType",g.CONSTANTS.ScriptCodingContractBaseRamCost/2);let a=ce(e,i);return null==a?(t.log(`ERROR: codingcontract.getData() failed because it could find the specified contract ${e} on server ${i}`),null):a.getType()},getData:function(e,i=t.serverIp){if(t.checkingRam)return Z("getData",g.CONSTANTS.ScriptCodingContractBaseRamCost/2);n("getData",g.CONSTANTS.ScriptCodingContractBaseRamCost/2);let a=ce(e,i);if(null==a)return t.log(`ERROR: codingcontract.getData() failed because it could find the specified contract ${e} on server ${i}`),null;let r=a.getData();if(r.constructor===Array){const e=r.slice();for(let t=0;t0){if("unalias"===n[0])return n.join(" ");if(null!=(r=(t=n[0],a.hasOwnProperty(t)?a[t]:null)))n[0]=r;else null!=(r=u(n[0]))&&(n[0]=r);for(var i=0;i"+n.infoText+""})),i.push(Object(k.createElement)("p",{innerText:"---------------"}));var a=t.getFavorGain();2!=a.length&&(a=0),a=a[0],i.push(Object(k.createElement)("p",{innerText:"Reputation: "+Object(C.formatNumber)(t.playerReputation,4),tooltip:"You will earn "+Object(C.formatNumber)(a,0)+" faction favor upon resetting after installing an Augmentation"})),i.push(Object(k.createElement)("p",{innerText:"---------------"})),i.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"})),i.push(Object(k.createElement)("p",{innerText:"---------------"})),i.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!"})),i.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+)"})),i.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."})),i.push(h);var y=Object(k.createElement)("div",{class:"faction-work-div"}),E=Object(k.createElement)("div",{class:"faction-work-div-wrapper"});y.appendChild(E),E.appendChild(Object(k.createElement)("a",{class:"std-button",innerText:"Field Work",clickListener:()=>(m.a.startFactionFieldWork(t),!1)})),E.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."})),i.push(y);var T=Object(k.createElement)("div",{class:"faction-work-div"}),S=Object(k.createElement)("div",{class:"faction-work-div-wrapper"});T.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."})),i.push(T);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",{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 i=n/s.CONSTANTS.DonateMoneyToRepDivisor*m.a.faction_rep_mult;t.playerReputation+=i,Object(b.dialogBoxCreate)("You just donated "+f.numeralWrapper.format(n,"$0.000a")+" to "+t.name+" to gain "+Object(C.formatNumber)(i,3)+" reputation"),M(e)}}})),w.appendChild(R),w.appendChild(x),i.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.

"})),i.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."})),i.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",y.style.display=n.offerFieldWork?"inline":"none",T.style.display=n.offerSecurityWork?"inline":"none";for(B=0;B{if(m.a.inGang())l.Engine.loadGangContent();else{let i=!1;"NiteSec"!==e&&"The Black Hand"!==e||(i=!0);var t=Object(O.yesNoBoxGetYesButton)(),n=Object(O.yesNoBoxGetNoButton)();t.innerHTML="Create Gang",n.innerHTML="Cancel",t.addEventListener("click",()=>{m.a.startGang(e,i),document.getElementById("world-menu-header").click(),document.getElementById("world-menu-header").click(),l.Engine.loadGangContent(),Object(O.yesNoBoxClose)()}),n.addEventListener("click",()=>{Object(O.yesNoBoxClose)()});let a="";a=i?"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(O.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.

"+a+"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."})),i.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 a=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=i.Augmentations[e],a=i.Augmentations[t];if(null==n||null==a)throw new Error("Invalid Augmentation Names");return n.baseCost-a.baseCost}),Object(v.removeChildrenFromElement)(a),A(a,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=i.Augmentations[e],a=i.Augmentations[t];if(null==n||null==a)throw new Error("Invalid Augmentation Names");return n.baseRepRequirement-a.baseRepRequirement}),Object(v.removeChildrenFromElement)(a),A(a,e,t)}}),s=Object(k.createElement)("a",{innerText:"Sort by Default Order",class:"a-link-button",clickListener:()=>{d.Settings.PurchaseAugmentationsOrder=h.PurchaseAugmentationsOrderSetting.Default,Object(v.removeChildrenFromElement)(a),A(a,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(a);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"}),y=s.baseRepRequirement*a.augmentationRepRequirementMult;x(s)?s.name!=r.AugmentationNames.NeuroFluxGovernor&&(s.owned||l)?(g.setAttribute("class","a-link-button-inactive"),_.innerHTML="ALREADY OWNED"):n.playerReputation>=y?(g.setAttribute("class","a-link-button"),_.innerHTML="UNLOCKED - "+f.numeralWrapper.format(s.baseCost*a.augmentationPriceMult,"$0.000a")):(g.setAttribute("class","a-link-button-inactive"),_.innerHTML="LOCKED (Requires "+Object(C.formatNumber)(y,1)+" faction reputation) - "+f.numeralWrapper.format(s.baseCost*a.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 i=Object(O.yesNoBoxGetYesButton)(),a=Object(O.yesNoBoxGetNoButton)();i.innerHTML="Purchase",a.innerHTML="Cancel",i.addEventListener("click",function(){R(e,t)}),a.addEventListener("click",function(){Object(O.yesNoBoxClose)()}),Object(O.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;n1?1:i<0?0:i}function o(e){null==e.baseDifficulty&&(e.baseDifficulty=e.hackDifficulty);var t=3;return(t+=e.baseDifficulty*a.a.hacking_exp_mult*.3)*i.BitNodeMultipliers.HackExpGain}function s(e){const t=(100-e.hackDifficulty)/100*((a.a.hacking_skill-(e.requiredHackingSkill-1))/a.a.hacking_skill)*a.a.hacking_money_mult/240;return t<0?0:t>1?1:t*i.BitNodeMultipliers.ScriptHackMoney}function l(e,t,n){const i=e.requiredHackingSkill*e.hackDifficulty;null==t&&(t=a.a.hacking_skill),null==n&&(n=a.a.intelligence);var r=2.5*i+500;return 5*(r/=t+50+.1*n)/a.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 i=n(2);t.createOptionElement=function(e,t=""){let n=t;return""===n&&(n=e),i.createElement("option",{text:e,value:n})}},function(e,t,n){!function(e){"use strict";var t={3:"abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile",5:"class enum extends super const export import",6:"enum",strict:"implements interface let package private protected public static yield",strictBind:"eval arguments"},n="break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this",i={5:n,6:n+" const class extends export import super"},a="ªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͰ-ʹͶͷͺ-ͽͿΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԯԱ-Ֆՙա-ևא-תװ-ײؠ-يٮٯٱ-ۓەۥۦۮۯۺ-ۼۿܐܒ-ܯݍ-ޥޱߊ-ߪߴߵߺࠀ-ࠕࠚࠤࠨࡀ-ࡘࢠ-ࢴࢶ-ࢽऄ-हऽॐक़-ॡॱ-ঀঅ-ঌএঐও-নপ-রলশ-হঽৎড়ঢ়য়-ৡৰৱਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽૐૠૡૹଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽଡ଼ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹௐఅ-ఌఎ-ఐఒ-నప-హఽౘ-ౚౠౡಀಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽೞೠೡೱೲഅ-ഌഎ-ഐഒ-ഺഽൎൔ-ൖൟ-ൡൺ-ൿඅ-ඖක-නඳ-රලව-ෆก-ะาำเ-ๆກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ະາຳຽເ-ໄໆໜ-ໟༀཀ-ཇཉ-ཬྈ-ྌက-ဪဿၐ-ၕၚ-ၝၡၥၦၮ-ၰၵ-ႁႎႠ-ჅჇჍა-ჺჼ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏽᏸ-ᏽᐁ-ᙬᙯ-ᙿᚁ-ᚚᚠ-ᛪᛮ-ᛸᜀ-ᜌᜎ-ᜑᜠ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡷᢀ-ᢨᢪᢰ-ᣵᤀ-ᤞᥐ-ᥭᥰ-ᥴᦀ-ᦫᦰ-ᧉᨀ-ᨖᨠ-ᩔᪧᬅ-ᬳᭅ-ᭋᮃ-ᮠᮮᮯᮺ-ᯥᰀ-ᰣᱍ-ᱏᱚ-ᱽᲀ-ᲈᳩ-ᳬᳮ-ᳱᳵᳶᴀ-ᶿḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₜℂℇℊ-ℓℕ℘-ℝℤΩℨK-ℹℼ-ℿⅅ-ⅉⅎⅠ-ↈⰀ-Ⱞⰰ-ⱞⱠ-ⳤⳫ-ⳮⳲⳳⴀ-ⴥⴧⴭⴰ-ⵧⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞ々-〇〡-〩〱-〵〸-〼ぁ-ゖ゛-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆺㇰ-ㇿ㐀-䶵一-鿕ꀀ-ꒌꓐ-ꓽꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙮꙿ-ꚝꚠ-ꛯꜗ-ꜟꜢ-ꞈꞋ-ꞮꞰ-ꞷꟷ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢꡀ-ꡳꢂ-ꢳꣲ-ꣷꣻꣽꤊ-ꤥꤰ-ꥆꥠ-ꥼꦄ-ꦲꧏꧠ-ꧤꧦ-ꧯꧺ-ꧾꨀ-ꨨꩀ-ꩂꩄ-ꩋꩠ-ꩶꩺꩾ-ꪯꪱꪵꪶꪹ-ꪽꫀꫂꫛ-ꫝꫠ-ꫪꫲ-ꫴꬁ-ꬆꬉ-ꬎꬑ-ꬖꬠ-ꬦꬨ-ꬮꬰ-ꭚꭜ-ꭥꭰ-ꯢ가-힣ힰ-ퟆퟋ-ퟻ豈-舘並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ",r="‌‍·̀-ͯ·҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-٩ٰۖ-ۜ۟-۪ۤۧۨ-ۭ۰-۹ܑܰ-݊ަ-ް߀-߉߫-߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࡙࠭-࡛ࣔ-ࣣ࣡-ःऺ-़ा-ॏ॑-ॗॢॣ०-९ঁ-ঃ়া-ৄেৈো-্ৗৢৣ০-৯ਁ-ਃ਼ਾ-ੂੇੈੋ-੍ੑ੦-ੱੵઁ-ઃ઼ા-ૅે-ૉો-્ૢૣ૦-૯ଁ-ଃ଼ା-ୄେୈୋ-୍ୖୗୢୣ୦-୯ஂா-ூெ-ைொ-்ௗ௦-௯ఀ-ఃా-ౄె-ైొ-్ౕౖౢౣ౦-౯ಁ-ಃ಼ಾ-ೄೆ-ೈೊ-್ೕೖೢೣ೦-೯ഁ-ഃാ-ൄെ-ൈൊ-്ൗൢൣ൦-൯ංඃ්ා-ුූෘ-ෟ෦-෯ෲෳัิ-ฺ็-๎๐-๙ັິ-ູົຼ່-ໍ໐-໙༘༙༠-༩༹༵༷༾༿ཱ-྄྆྇ྍ-ྗྙ-ྼ࿆ါ-ှ၀-၉ၖ-ၙၞ-ၠၢ-ၤၧ-ၭၱ-ၴႂ-ႍႏ-ႝ፝-፟፩-፱ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳ឴-៓៝០-៩᠋-᠍᠐-᠙ᢩᤠ-ᤫᤰ-᤻᥆-᥏᧐-᧚ᨗ-ᨛᩕ-ᩞ᩠-᩿᩼-᪉᪐-᪙᪰-᪽ᬀ-ᬄ᬴-᭄᭐-᭙᭫-᭳ᮀ-ᮂᮡ-ᮭ᮰-᮹᯦-᯳ᰤ-᰷᱀-᱉᱐-᱙᳐-᳔᳒-᳨᳭ᳲ-᳴᳸᳹᷀-᷵᷻-᷿‿⁀⁔⃐-⃥⃜⃡-⃰⳯-⵿⳱ⷠ-〪ⷿ-゙゚〯꘠-꘩꙯ꙴ-꙽ꚞꚟ꛰꛱ꠂ꠆ꠋꠣ-ꠧꢀꢁꢴ-ꣅ꣐-꣙꣠-꣱꤀-꤉ꤦ-꤭ꥇ-꥓ꦀ-ꦃ꦳-꧀꧐-꧙ꧥ꧰-꧹ꨩ-ꨶꩃꩌꩍ꩐-꩙ꩻ-ꩽꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꫫ-ꫯꫵ꫶ꯣ-ꯪ꯬꯭꯰-꯹ﬞ︀-️︠-︯︳︴﹍-﹏0-9_",o=new RegExp("["+a+"]"),s=new RegExp("["+a+r+"]");a=r=null;var l=[0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,17,26,6,37,11,29,3,35,5,7,2,4,43,157,19,35,5,35,5,39,9,51,157,310,10,21,11,7,153,5,3,0,2,43,2,1,4,0,3,22,11,22,10,30,66,18,2,1,11,21,11,25,71,55,7,1,65,0,16,3,2,2,2,26,45,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,56,50,14,50,785,52,76,44,33,24,27,35,42,34,4,0,13,47,15,3,22,0,2,0,36,17,2,24,85,6,2,0,2,3,2,14,2,9,8,46,39,7,3,1,3,21,2,6,2,1,2,4,4,0,19,0,13,4,159,52,19,3,54,47,21,1,2,0,185,46,42,3,37,47,21,0,60,42,86,25,391,63,32,0,449,56,264,8,2,36,18,0,50,29,881,921,103,110,18,195,2749,1070,4050,582,8634,568,8,30,114,29,19,47,17,3,32,20,6,18,881,68,12,0,67,12,65,0,32,6124,20,754,9486,1,3071,106,6,12,4,8,8,9,5991,84,2,70,2,1,3,0,3,1,3,3,2,11,2,0,2,6,2,64,2,3,3,7,2,6,2,27,2,3,2,4,2,0,4,6,2,339,3,24,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,7,4149,196,60,67,1213,3,2,26,2,1,2,0,3,0,2,9,2,3,2,0,2,0,7,0,5,0,2,0,2,0,2,2,2,1,2,0,3,0,2,0,2,0,2,0,2,0,2,1,2,0,3,3,2,6,2,3,2,3,2,0,2,9,2,16,6,2,2,4,2,16,4421,42710,42,4148,12,221,3,5761,10591,541],c=[509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,1306,2,54,14,32,9,16,3,46,10,54,9,7,2,37,13,2,9,52,0,13,2,49,13,10,2,4,9,83,11,7,0,161,11,6,9,7,3,57,0,2,6,3,1,3,2,10,0,11,1,3,6,4,4,193,17,10,9,87,19,13,9,214,6,3,8,28,1,83,16,16,9,82,12,9,9,84,14,5,9,423,9,838,7,2,7,17,9,57,21,2,13,19882,9,135,4,60,6,26,9,1016,45,17,3,19723,1,5319,4,4,5,9,7,3,6,31,3,149,2,1418,49,513,54,5,49,9,0,15,0,23,4,2,14,1361,6,2,16,3,6,2,1,2,4,2214,6,110,6,6,9,792487,239];function u(e,t){for(var n=65536,i=0;ie)return!1;if((n+=t[i+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},y={};function f(e,t){return void 0===t&&(t={}),t.keyword=e,y[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:f("break"),_case:f("case",g),_catch:f("catch"),_continue:f("continue"),_debugger:f("debugger"),_default:f("default",g),_do:f("do",{isLoop:!0,beforeExpr:!0}),_else:f("else",g),_finally:f("finally"),_for:f("for",{isLoop:!0}),_function:f("function",_),_if:f("if"),_return:f("return",g),_switch:f("switch"),_throw:f("throw",g),_try:f("try"),_var:f("var"),_const:f("const"),_while:f("while",{isLoop:!0}),_with:f("with"),_new:f("new",{beforeExpr:!0,startsExpr:!0}),_this:f("this",_),_super:f("super",_),_class:f("class"),_extends:f("extends",g),_export:f("export"),_import:f("import"),_null:f("null",_),_true:f("true",_),_false:f("false",_),_in:f("in",{beforeExpr:!0,binop:7}),_instanceof:f("instanceof",{beforeExpr:!0,binop:7}),_typeof:f("typeof",{beforeExpr:!0,prefix:!0,startsExpr:!0}),_void:f("void",{beforeExpr:!0,prefix:!0,startsExpr:!0}),_delete:f("delete",{beforeExpr:!0,prefix:!0,startsExpr:!0})},E=/\r\n?|\n|\u2028|\u2029/,v=new RegExp(E.source,"g");function k(e){return 10===e||13===e||8232===e||8233===e}var C=/[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/,O=/(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g,T=Object.prototype,S=T.hasOwnProperty,M=T.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,i=0;;){v.lastIndex=i;var a=v.exec(e);if(!(a&&a.index=2015&&(t.ecmaVersion-=2009),null==t.allowReserved&&(t.allowReserved=t.ecmaVersion<5),A(t.onToken)){var i=t.onToken;t.onToken=function(e){return i.push(e)}}return A(t.onComment)&&(t.onComment=function(e,t){return function(n,i,a,r,o,s){var l={type:n?"Block":"Line",value:i,start:a,end:r};e.locations&&(l.loc=new x(this,o,s)),e.ranges&&(l.range=[a,r]),t.push(l)}}(t,t.onComment)),t}var L={};function D(e){return new RegExp("^("+e.replace(/ /g,"|")+")$")}var B=function(e,n,a){this.options=e=I(e),this.sourceFile=e.sourceFile,this.keywords=D(i[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),a?(this.pos=a,this.lineStart=this.input.lastIndexOf("\n",a-1)+1,this.curLine=this.input.slice(0,this.lineStart).split(E).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 j=B.prototype,W=/^(?:'((?:[^']|\.)*)'|"((?:[^"]|\.)*)"|;)/;j.strictDirective=function(e){for(;;){O.lastIndex=e,e+=O.exec(this.input)[0].length;var t=W.exec(this.input.slice(e));if(!t)return!1;if("use strict"==(t[1]||t[2]))return!0;e+=t[0].length}},j.eat=function(e){return this.type===e&&(this.next(),!0)},j.isContextual=function(e){return this.type===b.name&&this.value===e},j.eatContextual=function(e){return this.value===e&&this.eat(b.name)},j.expectContextual=function(e){this.eatContextual(e)||this.unexpected()},j.canInsertSemicolon=function(){return this.type===b.eof||this.type===b.braceR||E.test(this.input.slice(this.lastTokEnd,this.start))},j.insertSemicolon=function(){if(this.canInsertSemicolon())return this.options.onInsertedSemicolon&&this.options.onInsertedSemicolon(this.lastTokEnd,this.lastTokEndLoc),!0},j.semicolon=function(){this.eat(b.semi)||this.insertSemicolon()||this.unexpected()},j.afterTrailingComma=function(e,t){if(this.type==e)return this.options.onTrailingComma&&this.options.onTrailingComma(this.lastTokStart,this.lastTokStartLoc),t||this.next(),!0},j.expect=function(e){this.eat(e)||this.unexpected()},j.unexpected=function(e){this.raise(null!=e?e:this.start,"Unexpected token")};var F=function(){this.shorthandAssign=this.trailingComma=this.parenthesizedAssign=this.parenthesizedBind=-1};j.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")}},j.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")},j.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;O.lastIndex=this.pos;var e=O.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 i=t+1;m(this.input.charCodeAt(i),!0);)++i;var a=this.input.slice(t,i);if(!this.isKeyword(a))return!0}return!1},U.isAsyncFunction=function(){if(this.type!==b.name||this.options.ecmaVersion<8||"async"!=this.value)return!1;O.lastIndex=this.pos;var e=O.exec(this.input),t=this.pos+e[0].length;return!(E.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 i,a=this.type,r=this.startNode();switch(this.isLet()&&(a=b._var,i="let"),a){case b._break:case b._continue:return this.parseBreakContinueStatement(r,a.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 i=i||this.value,e||"var"==i||this.unexpected(),this.parseVarStatement(r,i);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'")),a===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 a===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 i=0;i=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(),i=t?"let":this.value;return this.next(),this.parseVar(n,!0,i),this.finishNode(n,"VariableDeclaration"),!(this.type===b._in||this.options.ecmaVersion>=6&&this.isContextual("of"))||1!==n.declarations.length||"var"!==i&&n.declarations[0].init?this.parseFor(e,n):this.parseForIn(e,n)}var a=new F,r=this.parseExpression(!0,a);return this.type===b._in||this.options.ecmaVersion>=6&&this.isContextual("of")?(this.toAssignable(r),this.checkLVal(r),this.checkPatternErrors(a,!0),this.parseForIn(e,r)):(this.checkExpressionErrors(a,!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 i=this.type===b._case;t&&this.finishNode(t,"SwitchCase"),e.cases.push(t=this.startNode()),t.consequent=[],this.next(),i?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(),E.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 i=0;i=0;r--){var o=this.labels[r];if(o.statementStart!=e.start)break;o.statementStart=this.start,o.kind=a}return this.labels.push({name:t,kind:a,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 i=this.startNode();if(this.parseVarId(i,n),this.eat(b.eq)?i.init=this.parseMaybeAssign(t):"const"!==n||this.type===b._in||this.options.ecmaVersion>=6&&this.isContextual("of")?"Identifier"==i.id.type||t&&(this.type===b._in||this.isContextual("of"))?i.init=null:this.raise(this.lastTokEnd,"Complex binding patterns require an initialization value"):this.unexpected(),e.declarations.push(this.finishNode(i,"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,i){this.initFunction(e),this.options.ecmaVersion>=6&&!i&&(e.generator=this.eat(b.star)),this.options.ecmaVersion>=8&&(e.async=!!i),t&&(e.id="nullableID"===t&&this.type!=b.name?null:this.parseIdent(),e.id&&this.checkLVal(e.id,"var"));var a=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=a,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(),i=!1;for(n.body=[],this.expect(b.braceL);!this.eat(b.braceR);)if(!this.eat(b.semi)){var a=this.startNode(),r=this.eat(b.star),o=!1,s=this.type===b.name&&"static"===this.value;this.parsePropertyName(a),a.static=s&&this.type!==b.parenL,a.static&&(r&&this.unexpected(),r=this.eat(b.star),this.parsePropertyName(a)),this.options.ecmaVersion>=8&&!r&&!a.computed&&"Identifier"===a.key.type&&"async"===a.key.name&&this.type!==b.parenL&&!this.canInsertSemicolon()&&(o=!0,this.parsePropertyName(a)),a.kind="method";var l=!1;if(!a.computed){var c=a.key;r||o||"Identifier"!==c.type||this.type===b.parenL||"get"!==c.name&&"set"!==c.name||(l=!0,a.kind=c.name,c=this.parsePropertyName(a)),!a.static&&("Identifier"===c.type&&"constructor"===c.name||"Literal"===c.type&&"constructor"===c.value)&&(i&&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"),a.kind="constructor",i=!0)}if(this.parseClassMethod(n,a,r,o),l){var u="get"===a.kind?0:1;if(a.value.params.length!==u){var p=a.value.start;"get"===a.kind?this.raiseRecoverable(p,"getter should have no params"):this.raiseRecoverable(p,"setter should have exactly one param")}else"set"===a.kind&&"RestElement"===a.value.params[0].type&&this.raiseRecoverable(a.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,i){t.value=this.parseMethod(n,i),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 i=this.startNode();this.next(),n&&this.next(),e.declaration=this.parseFunction(i,"nullableID",!1,n)}else if(this.type===b._class){var a=this.startNode();e.declaration=this.parseClass(a,"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,i=e.key;switch(i.type){case"Identifier":n=i.name;break;case"Literal":n=String(i.value);break;default:return}var a=e.kind;if(this.options.ecmaVersion>=6)"__proto__"===n&&"init"===a&&(t.proto&&this.raiseRecoverable(i.start,"Redefinition of __proto__ property"),t.proto=!0);else{var r=t[n="$"+n];r?("init"===a?this.strict&&r.init||r.get||r.set:r.init||r[a])&&this.raiseRecoverable(i.start,"Redefinition of property"):r=t[n]={init:!1,get:!1,set:!1},r[a]=!0}}},$.parseExpression=function(e,t){var n=this.start,i=this.startLoc,a=this.parseMaybeAssign(e,t);if(this.type===b.comma){var r=this.startNodeAt(n,i);for(r.expressions=[a];this.eat(b.comma);)r.expressions.push(this.parseMaybeAssign(e,t));return this.finishNode(r,"SequenceExpression")}return a},$.parseMaybeAssign=function(e,t,n){if(this.inGenerator&&this.isContextual("yield"))return this.parseYield();var i=!1,a=-1,r=-1;t?(a=t.parenthesizedAssign,r=t.trailingComma,t.parenthesizedAssign=t.trailingComma=-1):(t=new F,i=!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),i||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 i&&this.checkExpressionErrors(t,!0),a>-1&&(t.parenthesizedAssign=a),r>-1&&(t.trailingComma=r),l},$.parseMaybeConditional=function(e,t){var n=this.start,i=this.startLoc,a=this.parseExprOps(e,t);if(this.checkExpressionErrors(t))return a;if(this.eat(b.question)){var r=this.startNodeAt(n,i);return r.test=a,r.consequent=this.parseMaybeAssign(),this.expect(b.colon),r.alternate=this.parseMaybeAssign(e),this.finishNode(r,"ConditionalExpression")}return a},$.parseExprOps=function(e,t){var n=this.start,i=this.startLoc,a=this.parseMaybeUnary(t,!1);return this.checkExpressionErrors(t)?a:a.start==n&&"ArrowFunctionExpression"===a.type?a:this.parseExprOp(a,n,i,-1,e)},$.parseExprOp=function(e,t,n,i,a){var r=this.type.binop;if(null!=r&&(!a||this.type!==b._in)&&r>i){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,a),p=this.buildBinary(t,n,e,u,s,o);return this.parseExprOp(p,t,n,i,a)}return e},$.buildBinary=function(e,t,n,i,a,r){var o=this.startNodeAt(e,t);return o.left=n,o.operator=a,o.right=i,this.finishNode(o,r?"LogicalExpression":"BinaryExpression")},$.parseMaybeUnary=function(e,t){var n,i=this.start,a=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(i,a);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(i,a,n,this.parseMaybeUnary(null,!1),"**",!1):n},$.parseExprSubscripts=function(e){var t=this.start,n=this.startLoc,i=this.parseExprAtom(e),a="ArrowFunctionExpression"===i.type&&")"!==this.input.slice(this.lastTokStart,this.lastTokEnd);if(this.checkExpressionErrors(e)||a)return i;var r=this.parseSubscripts(i,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,i){for(var a,r=this.options.ecmaVersion>=8&&"Identifier"===e.type&&"async"===e.name&&this.lastTokEnd==e.end&&!this.canInsertSemicolon();;)if((a=this.eat(b.bracketL))||this.eat(b.dot)){var o=this.startNodeAt(t,n);o.object=e,o.property=a?this.parseExpression():this.parseIdent(!0),o.computed=!!a,a&&this.expect(b.bracketR),e=this.finishNode(o,"MemberExpression")}else if(!i&&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 i=this.type===b._this?"ThisExpression":"Super";return t=this.startNode(),this.next(),this.finishNode(t,i);case b.name:var a=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(a,r),!1,!1,!0);if(n&&!this.canInsertSemicolon()){if(this.eat(b.arrow))return this.parseArrowExpression(this.startNodeAt(a,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(a,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,i=this.startLoc,a=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),a&&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,i,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 y=this.startNodeAt(n,i);return y.expression=t,this.finishNode(y,"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,i=this.startLoc;return e.callee=this.parseSubscripts(this.parseExprAtom(),n,i,!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(),i=!0,a={};for(n.properties=[],this.next();!this.eat(b.braceR);){if(i)i=!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,a),n.properties.push(this.finishNode(c,"Property"))}return this.finishNode(n,e?"ObjectPattern":"ObjectExpression")},$.parsePropertyValue=function(e,t,n,i,a,r,o){if((n||i)&&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,i);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||i||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(a,r,e.key):this.type===b.eq&&o?(o.shorthandAssign<0&&(o.shorthandAssign=this.start),e.value=this.parseMaybeDefault(a,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(),i=this.inGenerator,a=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=i,this.inAsync=a,this.yieldPos=r,this.awaitPos=o,this.inFunction=s,this.finishNode(n,"FunctionExpression")},$.parseArrowExpression=function(e,t,n){var i=this.inGenerator,a=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=i,this.inAsync=a,this.yieldPos=r,this.awaitPos=o,this.inFunction=s,this.finishNode(e,"ArrowFunctionExpression")},$.parseFunctionBody=function(e,t){var n=t&&this.type!==b.braceL,i=this.strict,a=!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);i&&!r||(a=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=[],a&&(this.strict=!0),this.checkParams(e,!i&&!a&&!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=i},$.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 i=new SyntaxError(t);throw i.pos=e,i.loc=n,i.raisedAt=this.pos,i},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 i=0;i=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 ie=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])},ae=B.prototype,re="object"==typeof Packages&&"[object JavaPackage]"==Object.prototype.toString.call(Packages);function oe(e,t,n,i){try{return new RegExp(e,t)}catch(e){if(void 0!==n)throw e instanceof SyntaxError&&i.raise(n,"Error parsing regular expression: "+e.message),e}}ae.next=function(){this.options.onToken&&this.options.onToken(new ie(this)),this.lastTokEnd=this.end,this.lastTokStart=this.start,this.lastTokEndLoc=this.endLoc,this.lastTokStartLoc=this.startLoc,this.nextToken()},ae.getToken=function(){return this.next(),new ie(this)},"undefined"!=typeof Symbol&&(ae[Symbol.iterator]=function(){var e=this;return{next:function(){var t=e.getToken();return{done:t.type===b.eof,value:t}}}}),ae.curContext=function(){return this.context[this.context.length-1]},ae.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())},ae.readToken=function(e){return p(e,this.options.ecmaVersion>=6)||92===e?this.readWord():this.getTokenFromCode(e)},ae.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},ae.skipBlockComment=function(){var e,t=this.options.onComment&&this.curPosition(),n=this.pos,i=this.input.indexOf("*/",this.pos+=2);if(-1===i&&this.raise(this.pos-2,"Unterminated comment"),this.pos=i+2,this.options.locations)for(v.lastIndex=n;(e=v.exec(this.input))&&e.index8&&e<14||e>=5760&&C.test(String.fromCharCode(e))))break e;++this.pos}}},ae.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)},ae.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))},ae.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)},ae.readToken_mult_modulo_exp=function(e){var t=this.input.charCodeAt(this.pos+1),n=1,i=42===e?b.star:b.modulo;return this.options.ecmaVersion>=7&&42===t&&(++n,i=b.starstar,t=this.input.charCodeAt(this.pos+2)),61===t?this.finishOp(b.assign,n+1):this.finishOp(i,n)},ae.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)},ae.readToken_caret=function(){var e=this.input.charCodeAt(this.pos+1);return 61===e?this.finishOp(b.assign,2):this.finishOp(b.bitwiseXOR,1)},ae.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)&&E.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)},ae.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))},ae.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)},ae.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)+"'")},ae.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)))}ae.readRegexp=function(){for(var e,t,n=this,i=this.pos;;){n.pos>=n.input.length&&n.raise(i,"Unterminated regular expression");var a=n.input.charAt(n.pos);if(E.test(a)&&n.raise(i,"Unterminated regular expression"),e)e=!1;else{if("["===a)t=!0;else if("]"===a&&t)t=!1;else if("/"===a&&!t)break;e="\\"===a}++n.pos}var r=this.input.slice(i,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(i,"Invalid regular expression flag"),o.indexOf("u")>=0&&(se?l="u":(s=(s=s.replace(/\\u\{([0-9a-fA-F]+)\}/g,function(e,t,a){return(t=Number("0x"+t))>1114111&&n.raise(i+a+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,i,this),u=oe(r,o)),this.finishToken(b.regexp,{pattern:r,flags:o,value:u})},ae.readInt=function(e,t){for(var n=this.pos,i=0,a=0,r=null==t?1/0:t;a=97?s-97+10:s>=65?s-65+10:s>=48&&s<=57?s-48:1/0)>=e)break;++this.pos,i=i*e+o}return this.pos===n||null!=t&&this.pos-n!==t?null:i},ae.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)},ae.readNumber=function(e){var t=this.pos,n=!1,i=48===this.input.charCodeAt(this.pos);e||null!==this.readInt(10)||this.raise(t,"Invalid number"),i&&this.pos==t+1&&(i=!1);var a=this.input.charCodeAt(this.pos);46!==a||i||(++this.pos,this.readInt(10),n=!0,a=this.input.charCodeAt(this.pos)),69!==a&&101!==a||i||(43!==(a=this.input.charCodeAt(++this.pos))&&45!==a||++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):i&&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)},ae.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},ae.readString=function(e){for(var t="",n=++this.pos;;){this.pos>=this.input.length&&this.raise(this.start,"Unterminated string constant");var i=this.input.charCodeAt(this.pos);if(i===e)break;92===i?(t+=this.input.slice(n,this.pos),t+=this.readEscapedChar(!1),n=this.pos):(k(i)&&this.raise(this.start,"Unterminated string constant"),++this.pos)}return t+=this.input.slice(n,this.pos++),this.finishToken(b.string,t)},ae.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}},ae.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],i=parseInt(n,8);return i>255&&(n=n.slice(0,-1),i=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(i)}return String.fromCharCode(t)}},ae.readHexChar=function(e){var t=this.pos,n=this.readInt(16,e);return null===n&&this.raise(t,"Bad character escape sequence"),n},ae.readWord1=function(){this.containsEsc=!1;for(var e="",t=!0,n=this.pos,i=this.options.ecmaVersion>=6;this.posh()?1/0:t*a.CONSTANTS.BaseCostFor1GBOfRamServer*i.BitNodeMultipliers.PurchasedServerCost}function m(){return Math.round(a.CONSTANTS.PurchasedServerLimit*i.BitNodeMultipliers.PurchasedServerLimit)}function h(){const e=Math.round(a.CONSTANTS.PurchasedServerMaxRam*i.BitNodeMultipliers.PurchasedServerMaxRam);return 1<<31-Math.clz32(e)}function d(e){const t=p(e);if(r.a.money.lt(t))Object(s.dialogBoxCreate)("You don't have enough money to purchase this server!");else if(r.a.purchasedServers.length>=m())Object(s.dialogBoxCreate)("You have reached the maximum limit of "+m()+" 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(c.yesNoTxtInpBoxGetInput)();if(""!=n){var i=new o.d({ip:Object(l.a)(),hostname:n,organizationName:"",isConnectedTo:!1,adminRights:!0,purchasedByPlayer:!0,maxRam:e});Object(o.a)(i),r.a.purchasedServers.push(i.ip);var a=r.a.getHomeComputer();a.serversOnNetwork.push(i.ip),i.serversOnNetwork.push(a.ip),r.a.loseMoney(t),Object(s.dialogBoxCreate)("Server successfully purchased with hostname "+n)}else Object(s.dialogBoxCreate)("You must enter a hostname for your new server!")}}function g(e){if(r.a.money.lt(e))return void Object(s.dialogBoxCreate)("You do not have enough money to purchase additional RAM for your home computer");const t=r.a.getHomeComputer();t.maxRam>=a.CONSTANTS.HomeComputerMaxRam?Object(s.dialogBoxCreate)("You cannot upgrade your home computer RAM because it is at its maximum possible value"):(t.maxRam*=2,r.a.loseMoney(e),Object(s.dialogBoxCreate)("Purchased additional RAM for home computer! It now has "+t.maxRam+"GB of RAM."))}},function(e,t,n){"use strict";(function(e){n.d(t,"a",function(){return O}),n.d(t,"d",function(){return T}),n.d(t,"c",function(){return S}),n.d(t,"b",function(){return M});var i=n(163),a=n(162),r=n(10),o=n(63),s=n(15),l=n(51),c=n(3),u=n(9),p=n(14),m=n(29),h=n(90),d=n(2),g=n(38),_=n(12),y=n(4),f=n(40),b=n(16),E=n(27),v=n(67),k=n(23);e(document).keydown(function(e){if(_.routing.isOn(_.Page.Gang)&&e.altKey){if(null!=j.gangMemberFilter&&j.gangMemberFilter===document.activeElement)return;e.keyCode===m.KEY[1]?"block"===j.gangTerritorySubpage.style.display&&j.managementButton.click():e.keyCode===m.KEY[2]&&"block"===j.gangManagementSubpage.style.display&&j.territoryButton.click()}}),e(document).mousedown(function(t){j.gangMemberUpgradeBoxOpened&&null==e(t.target).closest("#gang-member-upgrade-popup-box-content").get(0)&&(Object(v.removeElement)(j.gangMemberUpgradeBox),j.gangMemberUpgradeBox=null,j.gangMemberUpgradeBoxContent=null,j.gangMemberUpgradeBoxOpened=!1,j.gangMemberUpgradeBoxElements=null)});let C=["Slum Snakes","Tetrads","The Syndicate","The Dark Army","Speakers for the Dead","NiteSec","The Black Hand"],O={"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 T(){O={"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){O=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,i=!1,a={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=i,this.baseRespect=a.baseRespect?a.baseRespect:0,this.baseWanted=a.baseWanted?a.baseWanted:0,this.baseMoney=a.baseMoney?a.baseMoney:0,this.hackWeight=a.hackWeight?a.hackWeight:0,this.strWeight=a.strWeight?a.strWeight:0,this.defWeight=a.defWeight?a.defWeight:0,this.dexWeight=a.dexWeight?a.dexWeight:0,this.agiWeight=a.agiWeight?a.agiWeight:0,this.chaWeight=a.chaWeight?a.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=a.difficulty?a.difficulty:1,this.territory=a.territory?a.territory:{money:1,respect:1,wanted:1}}M.prototype.getPower=function(){return O[this.facName].power},M.prototype.getTerritory=function(){return O[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 i=Math.min(this.storedCycles,5*n);try{this.processGains(i,t),this.processExperienceGains(i),this.processTerritoryAndPowerGains(i),this.storedCycles-=i}catch(e){Object(f.exceptionAlert)(`Exception caught when processing Gang: ${e}`)}},M.prototype.processGains=function(e=1,t){for(var n=0,i=0,a=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 O)if(O.hasOwnProperty(e))if(e==t)O[e].power+=this.calculatePower();else{const t=Math.random();if(t<.5){const t=.005*O[e].power;O[e].power+=Math.min(.85,t)}else{const n=.75*t*O[e].territory;O[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),i=Object(b.getRandomInt)(0,e.length-1),a=C[n],r=e[i];if(!(a!==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 i=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(f.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(B)},M.prototype.getUpgradeCost=function(e){return null==B[e]?1/0:B[e].getCost(this)},M.prototype.getUpgradeType=function(e){const t=B[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 i=Math.pow(100*O[e.facName].territory,t.territory.respect)/100;if(isNaN(i)||i<=0)return 0;var a=e.getWantedPenalty();return 11*t.baseRespect*n*i*a},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 i=Math.pow(100*O[e.facName].territory,t.territory.wanted)/100;return isNaN(i)||i<=0?0:t.baseWanted<0?.5*t.baseWanted*n*i:7*t.baseWanted/Math.pow(3*n*i,.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 i=Math.pow(100*O[e.facName].territory,t.territory.money)/100;if(isNaN(i)||i<=0)return 0;var a=e.getWantedPenalty();return 5*t.baseMoney*n*i*a},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,i=e.def,a=e.dex,r=e.agi,o=e.cha;this.hack_asc_mult+=t,this.str_asc_mult+=n,this.def_asc_mult+=i,this.dex_asc_mult+=a,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{x=e.name,R=e.desc,N=e.isHacking,I=e.isCombat,L=e.params,w[x]=new A(x,R,N,I,L)}),D.prototype.getCost=function(e){const t=e.getDiscount();return this.cost/t},D.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("
")},D.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)},D.prototype.toJSON=function(){return Object(p.Generic_toJSON)("GangMemberUpgrade",this)},D.fromJSON=function(e){return Object(p.Generic_fromJSON)(D,e.data)},p.Reviver.constructors.GangMemberUpgrade=D;const B={};a.gangMemberUpgradesMetadata.forEach(e=>{!function(e,t,n,i){B[e]=new D(e,t,n,i)}(e.name,e.cost,e.upgType,e.mults)}),M.prototype.createGangMemberUpgradeBox=function(e,t=""){const n="gang-member-upgrade-popup-box";if(j.gangMemberUpgradeBoxOpened){if(null==j.gangMemberUpgradeBoxElements||null==j.gangMemberUpgradeBox||null==j.gangMemberUpgradeBoxContent)return void console.error("Refreshing Gang member upgrade box throws error because required elements are null");for(var i=2;i-1||this.members[i].task.indexOf(a)>-1){var r=this.members[i].createGangMemberUpgradePanel(this,e);j.gangMemberUpgradeBoxContent.appendChild(r),j.gangMemberUpgradeBoxElements.push(r)}}else{j.gangMemberUpgradeBoxFilter=Object(d.createElement)("input",{type:"text",placeholder:"Filter gang members",value:t,onkeyup:()=>{var t=j.gangMemberUpgradeBoxFilter.value.toString();this.createGangMemberUpgradeBox(e,t)}}),j.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."}),j.gangMemberUpgradeBoxElements=[j.gangMemberUpgradeBoxFilter,j.gangMemberUpgradeBoxDiscount];for(a=j.gangMemberUpgradeBoxFilter.value.toString(),i=0;i-1||this.members[i].task.indexOf(a)>-1)&&j.gangMemberUpgradeBoxElements.push(this.members[i].createGangMemberUpgradePanel(this,e));j.gangMemberUpgradeBox=Object(g.createPopup)(n,j.gangMemberUpgradeBoxElements),j.gangMemberUpgradeBoxContent=document.getElementById(n+"-content"),j.gangMemberUpgradeBoxOpened=!0}},P.prototype.createGangMemberUpgradePanel=function(e,t){var n=Object(d.createElement)("div",{border:"1px solid white"}),i=Object(d.createElement)("h1",{innerText:this.name+" ("+this.task+")"});n.appendChild(i);var a=Object(d.createElement)("pre",{fontSize:"14px",display:"inline-block",width:"20%",innerText:"Hack: "+this.hack+" (x"+Object(y.formatNumber)(this.hack_mult*this.hack_asc_mult,2)+")\nStr: "+this.str+" (x"+Object(y.formatNumber)(this.str_mult*this.str_asc_mult,2)+")\nDef: "+this.def+" (x"+Object(y.formatNumber)(this.def_mult*this.def_asc_mult,2)+")\nDex: "+this.dex+" (x"+Object(y.formatNumber)(this.dex_mult*this.dex_asc_mult,2)+")\nAgi: "+this.agi+" (x"+Object(y.formatNumber)(this.agi_mult*this.agi_asc_mult,2)+")\nCha: "+this.cha+" (x"+Object(y.formatNumber)(this.cha_mult*this.cha_asc_mult,2)+")\n"});const r=[];function o(e){const t=B[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(a),n.appendChild(s),n.appendChild(Object(d.createElement)("br",{}));const l=[],u=[],p=[],m=[],h=[];for(let n in B)if(B.hasOwnProperty(n)){let i=B[n];if(t.money.lt(i.getCost(e)))continue;if(this.upgrades.includes(n)||this.augmentations.includes(n))continue;switch(i.type){case"w":l.push(i);break;case"a":u.push(i);break;case"v":p.push(i);break;case"r":m.push(i);break;case"g":h.push(i);break;default:console.error(`ERROR: Invalid Gang Member Upgrade Type: ${i.type}`)}}const g=Object(d.createElement)("div",{width:"20%",display:"inline-block"}),_=Object(d.createElement)("div",{width:"20%",display:"inline-block"}),f=Object(d.createElement)("div",{width:"20%",display:"inline-block"}),b=Object(d.createElement)("div",{width:"20%",display:"inline-block"}),E=Object(d.createElement)("div",{width:"20%",display:"inline-block"});g.appendChild(Object(d.createElement)("h2",{innerText:"Weapons"})),_.appendChild(Object(d.createElement)("h2",{innerText:"Armor"})),f.appendChild(Object(d.createElement)("h2",{innerText:"Vehicles"})),b.appendChild(Object(d.createElement)("h2",{innerText:"Rootkits"})),E.appendChild(Object(d.createElement)("h2",{innerText:"Augmentations"}));const v=[l,u,p,m,h],k=[g,_,f,b,E];for(let n=0;n(a.buyUpgrade(n,t,e),!1)};r>=3?s.tooltipleft=n.desc:s.tooltip=n.desc,i.appendChild(Object(d.createElement)("a",s))}(i[r],a,this,n,e)}}return n.appendChild(g),n.appendChild(_),n.appendChild(f),n.appendChild(b),n.appendChild(E),n};const j={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(!j.gangContentCreated||null==j.gangContainer){j.gangContentCreated=!0,j.gangContainer=Object(d.createElement)("div",{id:"gang-container",class:"generic-menupage-container"});var t=this.facName;this.members,this.wanted,this.respect;j.gangContainer.appendChild(Object(d.createElement)("a",{class:"a-link-button",display:"inline-block",innerText:"Back",clickListener:()=>(r.Engine.loadFactionContent(),Object(l.a)(t),!1)})),j.managementButton=Object(d.createElement)("a",{id:"gang-management-subpage-button",class:"a-link-button-inactive",display:"inline-block",innerHTML:"Gang Management (Alt+1)",clickListener:()=>(j.gangManagementSubpage.style.display="block",j.gangTerritorySubpage.style.display="none",j.managementButton.classList.toggle("a-link-button-inactive"),j.managementButton.classList.toggle("a-link-button"),j.territoryButton.classList.toggle("a-link-button-inactive"),j.territoryButton.classList.toggle("a-link-button"),this.updateGangContent(),!1)}),j.territoryButton=Object(d.createElement)("a",{id:"gang-territory-subpage-button",class:"a-link-button",display:"inline-block",innerHTML:"Gang Territory (Alt+2)",clickListener:()=>(j.gangManagementSubpage.style.display="none",j.gangTerritorySubpage.style.display="block",j.managementButton.classList.toggle("a-link-button-inactive"),j.managementButton.classList.toggle("a-link-button"),j.territoryButton.classList.toggle("a-link-button-inactive"),j.territoryButton.classList.toggle("a-link-button"),this.updateGangContent(),!1)}),j.gangContainer.appendChild(j.managementButton),j.gangContainer.appendChild(j.territoryButton),j.gangManagementSubpage=Object(d.createElement)("div",{display:"block",id:"gang-management-subpage"});var n="";n=this.isHackingGang?"Ethical Hacking":"Vigilante Justice",j.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"}),j.gangManagementSubpage.appendChild(j.gangDesc),j.gangInfo=Object(d.createElement)("p",{id:"gang-info",width:"70%"}),j.gangManagementSubpage.appendChild(j.gangInfo),j.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:"}),i=Object(d.createElement)("br"),a=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=a.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,i,a,t,r])}}),j.gangManagementSubpage.appendChild(j.gangRecruitMemberButton),j.gangRecruitRequirementText=Object(d.createElement)("p",{color:"red",id:"gang-recruit-requirement-text",margin:"10px"}),j.gangManagementSubpage.appendChild(j.gangRecruitRequirementText),j.gangManagementSubpage.appendChild(Object(d.createElement)("br",{})),j.gangExpandAllButton=Object(d.createElement)("a",{class:"a-link-button",display:"inline-block",innerHTML:"Expand All",clickListener:()=>{for(var e=j.gangManagementSubpage.getElementsByClassName("accordion-header"),t=0;t{for(var e=j.gangManagementSubpage.getElementsByClassName("accordion-header"),t=0;t{this.displayGangMemberList()}}),j.gangManageEquipmentButton=Object(d.createElement)("a",{class:"a-link-button",display:"inline-block",innerHTML:"Manage Equipment",clickListener:()=>{this.createGangMemberUpgradeBox(e)}}),j.gangManagementSubpage.appendChild(j.gangExpandAllButton),j.gangManagementSubpage.appendChild(j.gangCollapseAllButton),j.gangManagementSubpage.appendChild(j.gangMemberFilter),j.gangManagementSubpage.appendChild(j.gangManageEquipmentButton),j.gangMemberList=Object(d.createElement)("ul",{id:"gang-member-list"}),this.displayGangMemberList(),j.gangManagementSubpage.appendChild(j.gangMemberList),j.gangTerritorySubpage=Object(d.createElement)("div",{id:"gang-territory-subpage",display:"none"}),j.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.

"}),j.gangTerritorySubpage.appendChild(j.gangTerritoryDescText),j.gangTerritoryWarfareCheckbox=Object(d.createElement)("input",{display:"inline-block",id:"gang-management-territory-warfare-checkbox",changeListener:()=>{this.territoryWarfareEngaged=j.gangTerritoryWarfareCheckbox.checked},margin:"2px",type:"checkbox"}),j.gangTerritoryWarfareCheckbox.checked=this.territoryWarfareEngaged,j.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%"}),j.gangTerritorySubpage.appendChild(j.gangTerritoryWarfareCheckbox),j.gangTerritorySubpage.appendChild(j.gangTerritoryWarfareCheckboxLabel),j.gangTerritorySubpage.appendChild(Object(d.createElement)("br")),j.gangTerritoryWarfareClashChance=Object(d.createElement)("p",{display:"inline-block"}),j.gangTerritorySubpage.appendChild(j.gangTerritoryWarfareClashChance),j.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.")}})),j.gangTerritoryDeathNotifyCheckbox=Object(d.createElement)("input",{display:"inline-block",id:"gang-management-notify-member-death-checkbox",changeListener:()=>{this.notifyMemberDeath=j.gangTerritoryDeathNotifyCheckbox.checked},margin:"2px",type:"checkbox"}),j.gangTerritoryDeathNotifyCheckbox.checked=this.notifyMemberDeath,j.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."}),j.gangTerritorySubpage.appendChild(Object(d.createElement)("br")),j.gangTerritorySubpage.appendChild(j.gangTerritoryDeathNotifyCheckbox),j.gangTerritorySubpage.appendChild(j.gangTerritoryDeathNotifyCheckboxLabel),j.gangTerritorySubpage.appendChild(Object(d.createElement)("br"));var i=Object(d.createElement)("fieldset",{display:"block",margin:"6px",width:"50%"});j.gangTerritoryInfoText=Object(d.createElement)("p"),i.appendChild(j.gangTerritoryInfoText),j.gangTerritorySubpage.appendChild(i),j.gangContainer.appendChild(j.gangTerritorySubpage),j.gangContainer.appendChild(j.gangManagementSubpage),document.getElementById("entire-game-container").appendChild(j.gangContainer)}j.gangContainer.style.display="block",this.updateGangContent()},M.prototype.displayGangMemberList=function(){Object(E.removeChildrenFromElement)(j.gangMemberList),j.gangMemberPanels={};const e=this.members,t=j.gangMemberFilter.value.toString();for(var n=0;n-1||e[n].task.indexOf(t)>-1)&&this.createGangMemberDisplayElement(e[n])},M.prototype.updateGangContent=function(){if(j.gangContentCreated)if(j.gangMemberUpgradeBoxOpened&&(j.gangMemberUpgradeBoxDiscount.childNodes[0].nodeValue="Discount: -"+c.numeralWrapper.format(1-1/this.getDiscount(),"0.00%")),"block"===j.gangTerritorySubpage.style.display){j.gangTerritoryWarfareClashChance.innerText=`Territory Clash Chance: ${c.numeralWrapper.format(this.territoryClashChance,"0.000%")}`,j.gangTerritoryWarfareCheckbox.checked=this.territoryWarfareEngaged,j.gangTerritoryInfoText.innerHTML="";const e=O[this.facName].power;for(const t in O)if(O.hasOwnProperty(t)){const n=O[t];let i,a=100*n.territory;if(i=a<=0?Object(y.formatNumber)(0,2):a>=100?Object(y.formatNumber)(100,2):Object(y.formatNumber)(a,2),t===this.facName){let e=`${t}
Power: ${Object(y.formatNumber)(n.power,6)}
`;e+=`Territory: ${i}%

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

`,j.gangTerritoryInfoText.innerHTML+=r}}}else{if(j.gangInfo instanceof Element){var e,t=s.Factions[this.facName];e=t instanceof o.Faction?t.playerReputation:"ERROR",Object(E.removeChildrenFromElement)(j.gangInfo),j.gangInfo.appendChild(Object(d.createElement)("p",{display:"inline-block",innerText:"Respect: "+Object(y.formatNumber)(this.respect,6)+" ("+Object(y.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."})),j.gangInfo.appendChild(Object(d.createElement)("br")),j.gangInfo.appendChild(Object(d.createElement)("p",{display:"inline-block",innerText:"Wanted Level: "+Object(y.formatNumber)(this.wanted,6)+" ("+Object(y.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."})),j.gangInfo.appendChild(Object(d.createElement)("br"));var n=this.getWantedPenalty();n=100*(1-n),j.gangInfo.appendChild(Object(d.createElement)("p",{display:"inline-block",innerText:`Wanted Level Penalty: -${Object(y.formatNumber)(n,2)}%`,tooltip:"Penalty for respect and money gain rates due to Wanted Level"})),j.gangInfo.appendChild(Object(d.createElement)("br")),j.gangInfo.appendChild(Object(d.createElement)("p",{display:"inline-block",innerText:`Money gain rate: ${c.numeralWrapper.format(5*this.moneyGainRate,"$0.000a")} / sec`})),j.gangInfo.appendChild(Object(d.createElement)("br"));var i=100*O[this.facName].territory;let a;a=i<=0?Object(y.formatNumber)(0,2):i>=100?Object(y.formatNumber)(100,2):Object(y.formatNumber)(i,2),j.gangInfo.appendChild(Object(d.createElement)("p",{display:"inline-block",innerText:`Territory: ${Object(y.formatNumber)(a,3)}%`,tooltip:"The percentage of total territory your Gang controls"})),j.gangInfo.appendChild(Object(d.createElement)("br")),j.gangInfo.appendChild(Object(d.createElement)("p",{display:"inline-block",innerText:"Faction reputation: "+Object(y.formatNumber)(e,3)})),j.gangInfo.appendChild(Object(d.createElement)("br"));const l=1e3/r.Engine._idleSpeed;j.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"})),j.gangInfo.appendChild(Object(d.createElement)("br"))}else console.error("gang-info DOM element DNE");const a=this.members.length,l=this.getRespectNeededToRecruitMember(),u=j.gangRecruitMemberButton;a>=30?(u.className="a-link-button-inactive",j.gangRecruitRequirementText.style.display="inline-block",j.gangRecruitRequirementText.innerHTML="You have reached the maximum amount of gang members"):this.canRecruitMember()?(u.className="a-link-button",j.gangRecruitRequirementText.style.display="none"):(u.className="a-link-button-inactive",j.gangRecruitRequirementText.style.display="inline-block",j.gangRecruitRequirementText.innerHTML=`${Object(y.formatNumber)(l,2)} respect needed to recruit next member`);for(let e=0;e")});j.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(),i=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")}),a=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,[i,a,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",{id:t+"gang-member-task-selector"});let y=this.getAllTaskNames();y.unshift("---");for(var f=0;f{var t=_.options[_.selectedIndex].text;e.assignToTask(t),this.setGangMemberTaskDescription(e,t),this.updateGangContent()}),w.hasOwnProperty(e.task)){var E=e.task,v=0;for(let e=0;e"))}var a=document.getElementById(t+"gang-member-gain-info");a&&(a.innerHTML=[`Money: $ ${Object(y.formatNumber)(5*e.calculateMoneyGain(this),2)} / sec`,`Respect: ${Object(y.formatNumber)(5*e.calculateRespectGain(this),6)} / sec`,`Wanted Level: ${Object(y.formatNumber)(5*e.calculateWantedLevelGain(this),6)} / sec`,`Total Respect Earned: ${Object(y.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 i=0;for(let e=0;e["+(_Fconf__WEBPACK_IMPORTED_MODULE_7__.a.ENABLE_TIMESTAMPS?Object(_utils_helpers_getTimestamp__WEBPACK_IMPORTED_MODULE_29__.getTimestamp)()+" ":"")+_Player__WEBPACK_IMPORTED_MODULE_14__.a.getCurrentServer().hostname+" ~]> "+n),n.length>0&&(Terminal.resetTerminalInput(),Terminal.executeCommands(n))}if(e.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_25__.KEY.C&&e.ctrlKey&&(_engine__WEBPACK_IMPORTED_MODULE_6__.Engine._actionInProgress?(Object(_ui_postToTerminal__WEBPACK_IMPORTED_MODULE_32__.post)("Cancelling..."),_engine__WEBPACK_IMPORTED_MODULE_6__.Engine._actionInProgress=!1,Terminal.finishAction(!0)):_Fconf__WEBPACK_IMPORTED_MODULE_7__.a.ENABLE_BASH_HOTKEYS&&Terminal.resetTerminalInput()),e.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_25__.KEY.L&&e.ctrlKey&&(e.preventDefault(),Terminal.executeCommand("clear")),e.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_25__.KEY.UPARROW||_Fconf__WEBPACK_IMPORTED_MODULE_7__.a.ENABLE_BASH_HOTKEYS&&e.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_25__.KEY.P&&e.ctrlKey){if(_Fconf__WEBPACK_IMPORTED_MODULE_7__.a.ENABLE_BASH_HOTKEYS&&e.preventDefault(),null==t)return;var i=Terminal.commandHistoryIndex;if(0==(r=Terminal.commandHistory.length))return;(i<0||i>r)&&(Terminal.commandHistoryIndex=r),0!=i&&--Terminal.commandHistoryIndex;var a=Terminal.commandHistory[Terminal.commandHistoryIndex];t.value=a,Object(_utils_SetTimeoutRef__WEBPACK_IMPORTED_MODULE_21__.setTimeoutRef)(function(){t.selectionStart=t.selectionEnd=1e4},0)}if(e.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_25__.KEY.DOWNARROW||_Fconf__WEBPACK_IMPORTED_MODULE_7__.a.ENABLE_BASH_HOTKEYS&&e.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_25__.KEY.M&&e.ctrlKey){if(_Fconf__WEBPACK_IMPORTED_MODULE_7__.a.ENABLE_BASH_HOTKEYS&&e.preventDefault(),null==t)return;var r;i=Terminal.commandHistoryIndex;if(0==(r=Terminal.commandHistory.length))return;if((i<0||i>r)&&(Terminal.commandHistoryIndex=r),i==r||i==r-1)Terminal.commandHistoryIndex=r,t.value="";else{++Terminal.commandHistoryIndex;a=Terminal.commandHistory[Terminal.commandHistoryIndex];t.value=a}}if(e.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_25__.KEY.TAB){if(e.preventDefault(),null==t)return;var o=t.value;if(""==o)return;const i=o.lastIndexOf(";");-1!==i&&(o=o.slice(i+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__WEBPACK_IMPORTED_MODULE_7__.a.ENABLE_BASH_HOTKEYS&&(e.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_25__.KEY.A&&e.ctrlKey&&(e.preventDefault(),Terminal.moveTextCursor("home")),e.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_25__.KEY.E&&e.ctrlKey&&(e.preventDefault(),Terminal.moveTextCursor("end")),e.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_25__.KEY.B&&e.ctrlKey&&(e.preventDefault(),Terminal.moveTextCursor("prevchar")),e.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_25__.KEY.B&&e.altKey&&(e.preventDefault(),Terminal.moveTextCursor("prevword")),e.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_25__.KEY.F&&e.ctrlKey&&(e.preventDefault(),Terminal.moveTextCursor("nextchar")),e.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_25__.KEY.F&&e.altKey&&(e.preventDefault(),Terminal.moveTextCursor("nextword")),e.keyCode!==_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_25__.KEY.H&&e.keyCode!==_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_25__.KEY.D||!e.ctrlKey||(Terminal.modifyInput("backspace"),e.preventDefault()))}});let terminalCtrlPressed=!1,shiftKeyPressed=!1;function tabCompletion(e,t,n,i=0){if(n.constructor!==Array)return;if(!Object(_utils_StringHelperFunctions__WEBPACK_IMPORTED_MODULE_22__.containsAllStrings)(n))return;if(""==t)for(var a=n.length-1;a>=0;--a)n[a].toLowerCase().startsWith(e.toLowerCase())||n.splice(a,1);else for(a=n.length-1;a>=0;--a)n[a].toLowerCase().startsWith(t.toLowerCase())||n.splice(a,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_22__.longestCommonStart)(n),c="";for(a=0;a "+e),Object(_ui_postToTerminal__WEBPACK_IMPORTED_MODULE_32__.post)(c)):(r.value=-1===o?l:r.value.slice(0,o+1)+" "+l,r.focus()):l==t?(Object(_ui_postToTerminal__WEBPACK_IMPORTED_MODULE_32__.post)("> "+e+" "+t),Object(_ui_postToTerminal__WEBPACK_IMPORTED_MODULE_32__.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 i=_Player__WEBPACK_IMPORTED_MODULE_14__.a.getCurrentServer();if((e=e.toLowerCase()).startsWith("./")&&-1==t){for(var a=0;a["+_Player__WEBPACK_IMPORTED_MODULE_14__.a.getCurrentServer().hostname+' ~]$
",v.noCloneChecked=!!ye.cloneNode(!0).lastChild.defaultValue;var Ce=s.documentElement,ke=/^key/,Ae=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ee=/^([^.]*)(?:\.(.+)|)/;function _e(){return!0}function Se(){return!1}function Fe(){try{return s.activeElement}catch(e){}}function De(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)De(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=Se;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(Ce,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=Ee.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=Ee.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,Be=/\s*$/g;function Oe(e,t){return T(e,"table")&&T(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Re(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function je(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&&Le.test(p))return e.each(function(i){var o=e.eq(i);g&&(t[0]=p.call(this,i,o.html())),Ie(o,t,n,r)});if(d&&(o=(i=xe(t,e[0].ownerDocument,!1,e,r)).firstChild,1===i.childNodes.length&&(i=o),o||r)){for(a=(s=k.map(me(i,"script"),Pe)).length;h")},clone:function(e,t,n){var r,i,o,s,a,l,u,c=e.cloneNode(!0),h=k.contains(e.ownerDocument,e);if(!(v.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(s=me(c),r=0,i=(o=me(e)).length;r0&&ve(s,!h&&me(e,"script")),c},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 Ne(this,e,!0)},remove:function(e){return Ne(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 Ie(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||Oe(this,e).appendChild(e)})},prepend:function(){return Ie(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Oe(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return Ie(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return Ie(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&&!Be.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 et(e,t,n){var r=We(e),i=ze(e,t,r),o="border-box"===k.css(e,"boxSizing",!1,r),s=o;if($e.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)+Qe(e,t,n||(o?"border":"content"),s,r,i)+"px"}function tt(e,t,n,r,i){return new tt.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=Ge.test(t),u=e.style;if(l||(t=Ze(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 Ge.test(t)||(t=Ze(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 qe&&(i=qe[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!Ve.test(k.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?et(e,t,r):ae(e,Ke,function(){return et(e,t,r)})},set:function(e,n,r){var i,o=We(e),s="border-box"===k.css(e,"boxSizing",!1,o),a=r&&Qe(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])-Qe(e,t,"border",!1,o)-.5)),a&&(i=ie.exec(n))&&"px"!==(i[3]||"px")&&(e.style[t]=n,n=k.css(e,t)),Je(0,n,a)}}}),k.cssHooks.marginLeft=Ue(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=Je)}),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=We(e),i=t.length;s1)}}),k.Tween=tt,tt.prototype={constructor:tt,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=tt.propHooks[this.prop];return e&&e.get?e.get(this):tt.propHooks._default.get(this)},run:function(e){var t,n=tt.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):tt.propHooks._default.set(this),this}},tt.prototype.init.prototype=tt.prototype,tt.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)}}},tt.propHooks.scrollTop=tt.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=tt.prototype.init,k.fx.step={};var nt,rt,it=/^(?:toggle|show|hide)$/,ot=/queueHooks$/;function st(){rt&&(!1===s.hidden&&n.requestAnimationFrame?n.requestAnimationFrame(st):n.setTimeout(st,k.fx.interval),k.fx.tick())}function at(){return n.setTimeout(function(){nt=void 0}),nt=Date.now()}function lt(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 ut(e,t,n){for(var r,i=(ct.tweeners[t]||[]).concat(ct.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)?ht: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)}}),ht={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=dt[t]||k.find.attr;dt[t]=function(e,t,r){var i,o,s=t.toLowerCase();return r||(o=dt[s],dt[s]=i,i=null!=n(e,t,r)?s:null,dt[s]=o),i}});var ft=/^(?:input|select|textarea|button)$/i,pt=/^(?:a|area)$/i;function gt(e){return(e.match(I)||[]).join(" ")}function mt(e){return e.getAttribute&&e.getAttribute("class")||""}function vt(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):ft.test(e.nodeName)||pt.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,mt(this)))});if((t=vt(e)).length)for(;n=this[l++];)if(i=mt(n),r=1===n.nodeType&&" "+gt(i)+" "){for(s=0;o=t[s++];)r.indexOf(" "+o+" ")<0&&(r+=o+" ");i!==(a=gt(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,mt(this)))});if(!arguments.length)return this.attr("class","");if((t=vt(e)).length)for(;n=this[l++];)if(i=mt(n),r=1===n.nodeType&&" "+gt(i)+" "){for(s=0;o=t[s++];)for(;r.indexOf(" "+o+" ")>-1;)r=r.replace(" "+o+" "," ");i!==(a=gt(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,mt(this),t),t)}):this.each(function(){var t,i,o,s;if(r)for(i=0,o=k(this),s=vt(e);t=s[i++];)o.hasClass(t)?o.removeClass(t):o.addClass(t);else void 0!==e&&"boolean"!==n||((t=mt(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&&(" "+gt(mt(n))+" ").indexOf(t)>-1)return!0;return!1}});var yt=/\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(yt,""):null==n?"":n:void 0}}),k.extend({valHooks:{option:{get:function(e){var t=k.find.attr(e,"value");return null!=t?t:gt(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 bt=/^(?:focusinfocus|focusoutblur)$/,wt=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&&!bt.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,bt.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,wt),r[m](),e.isPropagationStopped()&&f.removeEventListener(m,wt),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 xt=n.location,Ct=Date.now(),kt=/\?/;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 At=/\[\]$/,Et=/\r?\n/g,_t=/^(?:submit|button|image|reset|file)$/i,St=/^(?:input|select|textarea|keygen)/i;function Ft(e,t,n,r){var i;if(Array.isArray(t))k.each(t,function(t,i){n||At.test(e)?r(e,i):Ft(e+"["+("object"==typeof i&&null!=i?t:"")+"]",i,n,r)});else if(n||"object"!==C(t))r(e,t);else for(i in t)Ft(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)Ft(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")&&St.test(this.nodeName)&&!_t.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(Et,"\r\n")}}):{name:t.name,value:n.replace(Et,"\r\n")}}).get()}});var Dt=/%20/g,Tt=/#.*$/,Bt=/([?&])_=[^&]*/,Lt=/^(.*?):[ \t]*([^\r\n]*)$/gm,Mt=/^(?:GET|HEAD)$/,Ot=/^\/\//,Pt={},Rt={},jt="*/".concat("*"),It=s.createElement("a");function Nt(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 $t(e,t,n,r){var i={},o=e===Rt;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 Wt(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}It.href=xt.href,k.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:xt.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(xt.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":jt,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?Wt(Wt(e,k.ajaxSettings),t):Wt(k.ajaxSettings,e)},ajaxPrefilter:Nt(Pt),ajaxTransport:Nt(Rt),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=Lt.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||xt.href)+"").replace(Ot,xt.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=It.protocol+"//"+It.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)),$t(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=!Mt.test(p.type),i=p.url.replace(Tt,""),p.hasContent?p.data&&p.processData&&0===(p.contentType||"").indexOf("application/x-www-form-urlencoded")&&(p.data=p.data.replace(Dt,"+")):(f=p.url.slice(i.length),p.data&&(p.processData||"string"==typeof p.data)&&(i+=(kt.test(i)?"&":"?")+p.data,delete p.data),!1===p.cache&&(i=i.replace(Bt,"$1"),f=(kt.test(i)?"&":"?")+"_="+Ct+++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]?", "+jt+"; 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=$t(Rt,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 Ht={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(Ht[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("