let CONSTANTS = { Version: "0.33.0", //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 //the player will have this level assuming no multipliers. Multipliers can cause skills to go above this. MaxSkillLevel: 975, //How much reputation is needed to join a megacorporation's faction CorpFactionRepRequirement: 250000, /* Base costs */ BaseCostFor1GBOfRamHome: 30000, BaseCostFor1GBOfRamServer: 50000, //1 GB of RAM BaseCostFor1GBOfRamHacknetNode: 30000, BaseCostForHacknetNode: 1000, BaseCostForHacknetNodeCore: 500000, /* Hacknet Node constants */ HacknetNodeMoneyGainPerLevel: 1.6, HacknetNodePurchaseNextMult: 1.85, //Multiplier when purchasing an additional hacknet node HacknetNodeUpgradeLevelMult: 1.04, //Multiplier for cost when upgrading level HacknetNodeUpgradeRamMult: 1.28, //Multiplier for cost when upgrading RAM HacknetNodeUpgradeCoreMult: 1.48, //Multiplier for cost when buying another core HacknetNodeMaxLevel: 200, HacknetNodeMaxRam: 64, HacknetNodeMaxCores: 16, /* Faction and Company favor */ FactionReputationToFavorBase: 500, FactionReputationToFavorMult: 1.02, CompanyReputationToFavorBase: 500, CompanyReputationToFavorMult: 1.02, /* Augmentation */ //NeuroFlux Governor cost multiplier as you level up NeuroFluxGovernorLevelMult: 1.14, //RAM Costs for different commands ScriptWhileRamCost: 0.2, ScriptForRamCost: 0.2, ScriptIfRamCost: 0.1, ScriptHackRamCost: 0.1, ScriptGrowRamCost: 0.15, ScriptWeakenRamCost: 0.15, ScriptScanRamCost: 0.2, ScriptNukeRamCost: 0.05, ScriptBrutesshRamCost: 0.05, ScriptFtpcrackRamCost: 0.05, ScriptRelaysmtpRamCost: 0.05, ScriptHttpwormRamCost: 0.05, ScriptSqlinjectRamCost: 0.05, ScriptRunRamCost: 0.8, ScriptExecRamCost: 1.1, ScriptScpRamCost: 0.5, ScriptKillRamCost: 0.5, //Kill and killall ScriptHasRootAccessRamCost: 0.05, ScriptGetHostnameRamCost: 0.05, //getHostname() and getIp() ScriptGetHackingLevelRamCost: 0.05, //getHackingLevel() ScriptGetMultipliersRamCost: 4.0, //getHackingMultipliers() and getBitNodeMultipliers() ScriptGetServerCost: 0.1, ScriptFileExistsRamCost: 0.1, ScriptIsRunningRamCost: 0.1, ScriptOperatorRamCost: 0.01, ScriptPurchaseHacknetRamCost: 1.5, ScriptHacknetNodesRamCost: 1.0, //Base cost for accessing hacknet nodes array ScriptHNUpgLevelRamCost: 0.4, ScriptHNUpgRamRamCost: 0.6, ScriptHNUpgCoreRamCost: 0.8, ScriptGetStockRamCost: 2.0, ScriptBuySellStockRamCost: 2.5, ScriptPurchaseServerRamCost: 2.0, ScriptRoundRamCost: 0.05, ScriptReadWriteRamCost: 1.0, ScriptArbScriptRamCost: 1.0, //Functions that apply to all scripts regardless of args ScriptGetScriptRamCost: 0.1, ScriptGetHackTimeRamCost: 0.05, ScriptSingularityFn1RamCost: 1, ScriptSingularityFn2RamCost: 2, ScriptSingularityFn3RamCost: 3, MultithreadingRAMCost: 1, //Server constants ServerBaseGrowthRate: 1.03, //Unadjusted Growth rate ServerMaxGrowthRate: 1.0035, //Maximum possible growth rate (max rate accounting for server security) ServerFortifyAmount: 0.002, //Amount by which server's security increases when its hacked/grown ServerWeakenAmount: 0.05, //Amount by which server's security decreases when weakened PurchasedServerLimit: 25, //Augmentation Constants AugmentationCostMultiplier: 5, //Used for balancing costs without having to readjust every Augmentation cost AugmentationRepMultiplier: 2.5, //Used for balancing rep cost without having to readjust every value MultipleAugMultiplier: 1.9, //How much a TOR router costs TorRouterCost: 200000, //Infiltration constants InfiltrationBribeBaseAmount: 100000, //Amount per clearance level InfiltrationMoneyValue: 2500, //Convert "secret" value to money InfiltrationRepValue: 1.4, //Convert "secret" value to faction reputation //Stock market constants WSEAccountCost: 200e6, TIXAPICost: 5e9, StockMarketCommission: 100e3, //Hospital/Health HospitalCostPerHp: 100e3, //Intelligence-related constants IntelligenceCrimeWeight: 0.05, //Weight for how much int affects crime success rates IntelligenceInfiltrationWeight: 0.1, //Weight for how much int affects infiltration success rates IntelligenceCrimeBaseExpGain: 0.001, IntelligenceProgramBaseExpGain: 500, //Program required hack level divided by this to determine int exp gain IntelligenceTerminalHackBaseExpGain: 200, //Hacking exp divided by this to determine int exp gain IntelligenceSingFnBaseExpGain: 0.002, IntelligenceClassBaseExpGain: 0.000001, IntelligenceHackingMissionBaseExpGain: 0.03, //Hacking Mission difficulty multiplied by this to get exp gain //Hacking Missions HackingMissionRepToDiffConversion: 10000, //Faction rep is divided by this to get mission difficulty HackingMissionRepToRewardConversion: 7, //Faction rep divided byt his to get mission rep reward HackingMissionSpamTimeIncrease: 25000, //How much time limit increase is gained when conquering a Spam Node (ms) HackingMissionTransferAttackIncrease: 1.05, //Multiplier by which the attack for all Core Nodes is increased when conquering a Transfer Node HackingMissionMiscDefenseIncrease: 1.05, //The amount by which every misc node's defense is multiplied when one is conquered HackingMissionDifficultyToHacking: 150, //Difficulty is multiplied by this to determine enemy's "hacking" level (to determine effects of scan/attack, etc) 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 cannot capture all of the enemy's database nodes in the time limit, 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 cannot perform any actions
" + "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 cannot perform any actions

" + "To assign an action to a Node, you must first select one of your Nodes. This can be done by simply clicking on it. Only " + "one Node can be selected at a time, and it will be denoted with a white highlight. After selecting the Node, " + "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 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.", //Gang constants GangRespectToReputationRatio: 2, //Respect is divided by this to get rep gain MaximumGangMembers: 20, GangRecruitCostMultiplier: 2, GangTerritoryUpdateTimer: 150, MillisecondsPer20Hours: 72000000, GameCyclesPer20Hours: 72000000 / 200, MillisecondsPer10Hours: 36000000, GameCyclesPer10Hours: 36000000 / 200, MillisecondsPer8Hours: 28800000, GameCyclesPer8Hours: 28800000 / 200, MillisecondsPer4Hours: 14400000, GameCyclesPer4Hours: 14400000 / 200, MillisecondsPer2Hours: 7200000, GameCyclesPer2Hours: 7200000 / 200, MillisecondsPerHour: 3600000, GameCyclesPerHour: 3600000 / 200, MillisecondsPerHalfHour: 1800000, GameCyclesPerHalfHour: 1800000 / 200, MillisecondsPerQuarterHour: 900000, GameCyclesPerQuarterHour: 900000 / 200, MillisecondsPerFiveMinutes: 300000, GameCyclesPerFiveMinutes: 300000 / 200, 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, CrimeSingFnDivider: 2, //Factor by which exp/profit is reduced when commiting crime through Sing Fn 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", /* 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. The language has " + "your basic programming constructs and several built-in commands that are used to hack.

" + "

Official Wiki and Documentation


" + "Check out Bitburner's wiki for the official Netscript documentation" + ". The wiki documentation will contain more details and " + "code examples than this documentation page. Also, it can be opened up in another tab/window for convenience!

" + "

Variables and data types


" + "The following data types are supported by Netscript:
" + "numeric - Integers and floats (eg. 6, 10.4999)
" + "string - Encapsulated by single or double quotes (eg. 'this is a string')
" + "boolean - true or false

" + "Strings are fully functional Javascript strings, " + "which means that all of the member functions of Javascript strings such as toLowerCase() and includes() are also " + "available in Netscript!

" + "To create a variable, use the assign (=) operator. The language is not strongly typed. Examples:
" + "i = 5;
" + "s = 'this game is awesome!';

" + "In the first example above, we are creating the variable i and assigning it a value of 5. In the second, " + "we are creating the variable s and assigning it the value of a string. Note that all expressions must be " + "ended with a semicolon.

" + "

Operators


" + "The following operators are supported by Netscript:
" + " +
" + " -
" + " *
" + " /
" + " %
" + " &&
" + " ||
" + " <
" + " >
" + " <=
" + " >=
" + " ==
" + " !=
" + " ++ (Note: This ONLY pre-increments. Post-increment does not work)
" + " -- (Note: This ONLY pre-decrements. Post-decrement does not work)
" + " - (Negation operator)
" + " !

" + "

Arrays


" + "Netscript arrays have the same properties and functions as javascript arrays. For information see javascripts array documentation.

"+ "

Script Arguments


" + "Arguments passed into a script can be accessed using a special array called 'args'. The arguments can be accessed like a normal array using the [] " + "operator. (args[0], args[1], args[2]...)

" + "For example, let's say we want to make a generic script 'generic-run.script' and we plan to pass two arguments into that script. The first argument will be the name of " + "another script, and the second argument will be a number. This generic script will run the script specified in the first argument " + "with the amount of threads specified in the second element. The code would look like:

" + "run(args[0], args[1]);

" + "It is also possible to get the number of arguments that was passed into a script using:

" + "args.length

" + "Note that none of the other functions that typically work with arrays, such as remove(), insert(), clear(), etc., will work on the " + "args array.

" + "

Javascript Modules


" + "Netscript supports the following Javascript Modules:

" + "Math
Date (static functions only)

" + "

Functions


" + "You can NOT define you own functions in Netscript (yet), but there are several built in functions that " + "you may use:

" + "hack(hostname/ip)
Core function that is used to try and hack servers to steal money and gain hacking experience. The argument passed in must be a string with " + "either the IP or hostname of the server you want to hack. The runtime for this command depends on your hacking level and the target server's security 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. Returns true if the hack is successful and " + "false otherwise.
" + "Examples: hack('foodnstuff'); or hack('148.192.0.12');

" + "sleep(n, log=true)
Suspends the script for n milliseconds. The second argument is an optional boolean that indicates " + "whether or not the function should log the sleep action. If this argument is true, then calling this function will write " + "'Sleeping for N milliseconds' to the script's logs. If it's false, then this function will not log anything. " + "If this argument is not specified then it will be true by default.
Example: sleep(5000);

" + "grow(hostname/ip)
Use your hacking skills to increase the amount of money available on a server. The argument passed in " + "must be a string with either the IP or hostname of the target 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 server's growth rate and varies between servers. Generally, higher-level servers have higher growth rates.

" + "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. " + "Returns the number by which the money on the server was multiplied for the growth. " + "Works offline at a slower rate.
Example: grow('foodnstuff');

" + "weaken(hostname/ip)
Use your hacking skills to attack a server's security, lowering the server's security level. The argument passed " + "in must be a string with either the IP or hostname of the target server. 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. Returns " + "0.1. Works offline at a slower rate
Example: weaken('foodnstuff');

" + "print(x)
Prints a value or a variable to the scripts logs (which can be viewed with the 'tail [script]' terminal command ).

" + "tprint(x)
Prints a value or a variable to the Terminal

" + "clearLog()
Clears the script's logs.

" + "scan(hostname/ip, [hostnames=true])
Returns an array containing the hostnames or IPs of all servers that are one node away from the specified server. " + "The argument must be a string containing the IP or hostname of the target server. The second argument is a boolean that specifies whether " + "the hostnames or IPs of the scanned servers should be output. If it is true then hostnames will be returned, and if false then IP addresses will. " + "This second argument is optional and, if ommitted, the function will output " + "the hostnames of the scanned servers. The hostnames/IPs in the returned array are strings.

" + "nuke(hostname/ip)
Run NUKE.exe on the target server. NUKE.exe must exist on your home computer.
Example: nuke('foodnstuff');

" + "brutessh(hostname/ip)
Run BruteSSH.exe on the target server. BruteSSH.exe must exist on your home computer.
Example: brutessh('foodnstuff');

" + "ftpcrack(hostname/ip)
Run FTPCrack.exe on the target server. FTPCrack.exe must exist on your home computer.
Example: ftpcrack('foodnstuff');

" + "relaysmtp(hostname/ip)
Run relaySMTP.exe on the target server. relaySMTP.exe must exist on your home computer.
Example: relaysmtp('foodnstuff');

" + "httpworm(hostname/ip)
Run HTTPWorm.exe on the target server. HTTPWorm.exe must exist on your home computer.
Example: httpworm('foodnstuff');

" + "sqlinject(hostname/ip)
Run SQLInject.exe on the target server. SQLInject.exe must exist on your home computer.
Example: sqlinject('foodnstuff');

" + "run(script, [numThreads], [args...])
Run a script as a separate process. The first argument that is passed in is the name of the script as a string. This function can only " + "be used to run scripts located on the current server (the server running the script that calls this function). The second argument " + "is optional, and it specifies how many threads to run the script with. This argument must be a number greater than 0. If it is omitted, then the script will be run single-threaded. Any additional arguments will specify " + "arguments to pass into the new script that is being run. If arguments are specified for the new script, then the second argument numThreads argument must be filled in with a value.

" + "Returns true if the script is successfully started, and false otherwise. Requires a significant amount " + "of RAM to run this command.

" + "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);

" + "The following 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(script, hostname/ip, [numThreads], [args...])
Run a script as a separate process on another server. The first argument is the name of the script as a string. The " + "second argument is a string with the hostname or IP of the 'target server' on which to run the script. The specified script must exist on the target server. " + "The third argument is optional, and it specifies how many threads to run the script with. If it is omitted, then the script will be run single-threaded. " + "This argument must be a number that is greater than 0. Any additional arguments will specify arguments to pass into the new script that is being run. If " + "arguments are specified for the new script, then the third argument numThreads must be filled in with a value.

Returns " + "true if the script is successfully started, and false otherwise.

" + "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);

" + "The following 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');

" + "kill(script, hostname/ip, [args...])
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.

" + "The first argument must be a string with the name of the script. The name is case-sensitive. " + "The second argument must be a string with the hostname or IP of the target server. Any additional arguments to the function will specify the arguments passed " + "into the script that should be killed.

The function will try to kill the specified script on the target server. " + "If the script is found on the specified server and is running, then it will be killed and this function " + "will return true. Otherwise, this function will return false.

" + "Examples:
" + "If you are trying to kill a script named 'foo.script' on the 'foodnstuff' server that was ran with no arguments, use this:

" + "kill('foo.script', 'foodnstuff');

" + "If you are trying to kill a script named 'foo.script' on the current server that was ran with no arguments, use this:

" + "kill('foo.script', getHostname());

" + "If you are trying to kill a script named 'foo.script' on the current server that was ran with the arguments 1 and 'foodnstuff', use this:

" + "kill('foo.script', getHostname(), 1, 'foodnstuff');

" + "killall(hostname/ip)
Kills all running scripts on the specified server. This function takes a single argument which " + "must be a string containing the hostname or IP of the target server. This function will always return true.

" + "scp(script, [source], destination)
Copies a script or literature (.lit) file to another server. The first argument is a string with " + "the filename of the script or literature file " + "to be copied, or an array of filenames to be copied. The next two arguments are strings containing the hostname/IPs of the source and target server. " + "The source refers to the server from which the script/literature file will be copied, while the destination " + "refers to the server to which it will be copied. The source server argument is optional, and if ommitted the source " + "will be the current server (the server on which the script is running). Returns true if the script/literature file is " + "successfully copied over and false otherwise. If the first argument passed in is an array, then the function " + "will return if at least one of the files in the array is successfully copied over.

" + "Example: scp('hack-template.script', 'foodnstuff'); //Copies hack-template.script from the current server to foodnstuff
" + "Example: scp('foo.lit', 'helios', 'home'); //Copies foo.lit from the helios server to the home computer

" + "ls(hostname/ip)
Returns an array containing the names of all files on the specified server. The argument must be a " + "string with the hostname or IP of the target server.

" + "hasRootAccess(hostname/ip)
Returns a boolean (true or false) indicating whether or not the Player has root access to a server. " + "The argument passed in must be a string with either the hostname or IP of the target server.
" + "Example:
if (hasRootAccess('foodnstuff') == false) {
    nuke('foodnstuff');
}

" + "getIp()
Returns a string with the IP Address of the server that the script is running on

" + "getHostname()
Returns a string with the hostname of the server that the script is running on

" + "getHackingLevel()
Returns the Player's current hacking level.

" + "getHackingMultipliers()
Returns an object containing the Player's hacking related multipliers. " + "These multipliers are returned in integer 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:

" + "mults = getHackingMultipliers();
" + "print(mults.chance);
" + "print(mults.growth);

" + "getBitNodeMultipliers()
Returns an object containing the current BitNode multipliers. " + "This function requires Source-File 5 in order to run. The multipliers are returned in integer forms, not percentages " + "(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 object has the following structure (subject to change in the future):

" + "{
" + "ServerMaxMoney: 1,
" + "ServerStartingMoney: 1,
" + "ServerGrowthRate: 1,
" + "ServerWeakenRate: 1,
" + "ServerStartingSecurity: 1,
" + "ManualHackMoney: 1,
" + "ScriptHackMoney: 1,
" + "CompanyWorkMoney: 1,
" + "CrimeMoney: 1,
" + "HacknetNodeMoney: 1,
" + "CompanyWorkExpGain: 1,
" + "ClassGymExpGain: 1,
" + "FactionWorkExpGain: 1,
" + "HackExpGain: 1,
" + "CrimeExpGain: 1,
" + "FactionWorkRepGain: 1,
" + "FactionPassiveRepGain: 1,
" + "AugmentationRepCost: 1,
" + "AugmentationMoneyCost: 1,
" + "}

Example:

" + "mults = getBitNodeMultipliers();
" + "print(mults.ServerMaxMoney);
" + "print(mults.HackExpGain);

" + "getServerMoneyAvailable(hostname/ip)
Returns the amount of money available on a server. The argument passed in must be a string with either the " + "hostname or IP of the target server.
Example: getServerMoneyAvailable('foodnstuff');

" + "getServerMaxMoney(hostname/ip)
Returns the maximum amount of money that can be available on a server. The argument passed in must be a string with " + "the hostname or IP of the target server.
Example: getServerMaxMoney('foodnstuff');

" + "getServerGrowth(hostname/ip)
Returns the server's intrinsic '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 this server's " + "money is increased when using the grow() function. A higher growth parameter will result in a higher percentage from grow().

" + "The argument passed in must be a string with the hostname or IP of the target server.

" + "getServerSecurityLevel(hostname/ip)
Returns the security level of a server. The argument passed in must be a string with either the " + "hostname or IP of the target server. A server's security is denoted by a number, typically between 1 and 100.

" + "getServerBaseSecurityLevel(hostname/ip)
Returns the base security level of a 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.

" + "The argument passed in must be a string with either the hostname or IP of the target server. A server's base security is denoted by a number, typically between 1 and 100. " + "

" + "getServerMinSecurityLevel(hostname/ip)Returns the minimum security level of a server. The argument passed in must be a string with " + "either the hostname or IP of the target server.

" + "getServerRequiredHackingLevel(hostname/ip)
Returns the required hacking level of a server. The argument passed in must be a string with either the " + "hostname or IP or the target server.

" + "getServerNumPortsRequired(hostname/ip)
Returns the number of open ports required to successfully run NUKE.exe on a server. The argument " + "passed in must be a string with either the hostname or IP of the target server.

" + "getServerRam(hostname/ip)
Returns an array with two elements that gives information about the target server's RAM. The first " + "element in the array is the amount of RAM that the server has (in GB). The second element in the array is the amount of RAM that " + "is currently being used on the server.

" + "serverExists(hostname/ip)
Returns a boolean denoting whether or not the specified server exists. The argument " + "must be a string with the hostname or IP of the target server.

" + "fileExists(filename, [hostname/ip])
Returns a boolean (true or false) indicating whether the specified file exists on a server. " + "The first argument must be a string with the name of the file. A file can either be a script, program, or literature file. A script name is case-sensitive, but a " + "program/literature file is not. For example, fileExists('brutessh.exe') will work fine, even though the actual program is named BruteSSH.exe.

" + "The second argument is a string with the hostname or IP of the server on which to search for the program. This second argument is optional. " + "If it is omitted, then the function will search through the current server (the server running the script that calls this function) for the file.
" + "Example: fileExists('foo.script', 'foodnstuff');
" + "Example: 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 (the server on which this function runs) contains the FTPCrack.exe program, and false otherwise.

" + "isRunning(filename, hostname/ip, [args...])
Returns a boolean (true or false) indicating whether the specified script is running on a server. " + "Remember that a script is uniquely identified by both its name and its arguments.

" + "The first argument must be a string with the name of the script. The script name is case sensitive. The second argument is a string with the " + "hostname or IP of the target server. Any additional arguments passed to the function will specify the arguments passed into the target script. " + "The function will check whether the script is running on that target server.
" + "Example: isRunning('foo.script', 'foodnstuff');
" + "Example: isRunning('foo.script', getHostname());
" + "Example: isRunning('foo.script', 'joesguns', 1, 5, 'test');

" + "The first example above will return true if there is a script named 'foo.script' with no arguments running on the 'foodnstuff' server, and false otherwise. The second " + "example above will return true if there is a script named 'foo.script' with no arguments running on the current server, and false otherwise. " + "The third example above will return true if there is a script named 'foo.script' with the arguments 1, 5, and 'test' running on the 'joesguns' server, and " + "false otherwise.

" + "getNextHacknetNodeCost()
Returns the cost of purchasing a new Hacknet Node

" + "purchaseHacknetNode()
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 false. Does NOT work offline

" + "purchaseServer(hostname, ram)
Purchases a server with the specified hostname and amount of RAM. The first argument can be any data type, " + "but it will be converted to a string using Javascript's String function. Anything that resolves to an empty string will cause the function to fail. " + "The second argument specified the amount of RAM (in GB) for the server. This argument must resolve to a numeric and it must be a power of 2 " + "(2, 4, 8, etc...).

" + "This function 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 or if the player does not have enough money to purchase the specified server.

" + "deleteServer(hostname)
Deletes one of the servers you've purchased with the specified hostname. The function will fail if " + "there are any scripts running on the specified server. Returns true if successful and false otherwise

" + "getPurchasedServers([hostname=true])
Returns an array with either the hostname or IPs of all of the servers you " + "have purchased. It takes an optional parameter specifying whether the hostname or IP addresses will be returned. If this " + "parameter is not specified, it is true by default and hostnames will be returned

" + "round(n)
Rounds the number n to the nearest integer. If the argument passed in is not a number, then the function will return 0.

" + "write(port, data='', mode='a')
This function can be used to either write data to a port or to a text file (.txt).

" + "If the first argument is a number between 1 and 10, then it specifies a port and this function will write data to a port. If the second " + "argument is not specified then it will write an empty string to the port. The third argument, mode, is not used when writing data to a port.

" + "If the first argument is a string, then it specifies the name of a text file (.txt) and this function will write data to a text file. " + "The second argument defines the data to be written to the text file. If it is not specified then it is an empty string by default. " + "This third argument, mode, defines how the data will be written to the text file. If mode is set to 'w', then the data is written in 'write' " + "mode which means that it will overwrite the existing data on the file, or it will create a new file if it does not already exist. Otherwise, " + "the data will be written in 'append' mode which means that the data will be added at the end of the existing file, or it will create a new file if it " + "does not already exist. If mode isn't specified then it will be 'a' for 'append' mode by default.

" + "read(port)
This function is used to read data from a port or from a text file (.txt).

" + "This function takes a single argument. If this argument is a number between 1 and 10, then it specifies a port and it will read data from " + "a port. A port is a serialized queue. This function will remove the first element from the queue and return it. If the queue is empty, " + "then the string 'NULL PORT DATA' will be returned.

" + "If the first argument is a string, then it specifies the name of a text file and this function will return the data in the " + "specified text file. If the text file does not exist, an empty string will be returned

" + "scriptRunning(scriptname, hostname/ip)
Returns a boolean indicating whether any instance of the specified script is running " + "on a 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.

" + "The first argument must be a string with the name of the script. The script name is case sensitive. The second argument is " + "a string with the hostname or IP of the target server. Both arguments are required.

" + "scriptKill(scriptname, hostname/ip)
Kills all scripts with the specified filename that are running on the server specified by the " + "hostname/ip, regardless of arguments. Returns true if one or more scripts were successfully killed, and false if there were none.

" + "The first argument must be a string with the name of the script. The script name is case sensitive. The second argument is " + "a string with the hostname or IP of the target server. Both arguments are required.

" + "getScriptRam(scriptname, hostname/ip)
Returns the amount of RAM required to run the specified script on the " + "target server. The first argument must be a string with the name of the script. The script name is case sensitive. " + "The second argument is a string with the hostname or IP of the server where that script is. Both arguments are required.

" + "getHackTime(hostname/ip)
Returns the amount of time in seconds it takes to execute the hack() Netscript function " + "on the server specified by the hostname/ip. The argument must be a string with the hostname/ip of the target server.

" + "getGrowTime(hostname/ip)
Returns the amount of time in seconds it takes to execute the grow() Netscript function " + "on the server specified by the hostname/ip. The argument must be a string with the hostname/ip of the target server.

" + "getWeakenTime(hostname/ip)
Returns the amount of time in seconds it takes to execute the weaken() Netscript function " + "on the server specified by the hostname/ip. The argument must be a string with the hostname/ip of the target server.

" + "getScriptIncome([scriptname], [hostname/ip], [args...])
" + "Returns the amount of income the specified script generates while online (when the game is open, does not apply for " + "offline income). 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 ($/sec) of all of your active scripts (currently running). " + "The second value is the total income ($/sec) from scripts since you last installed Augmentations (or destroyed a BitNode).

" + "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 arguments in this function call.

" + "The first argument, if specified, must be a string with the name of the script (including the .script extension). " + "The second argument must be a string with the hostname/IP of the target server. If the first argument is specified " + "then the second argument must be specified as well. Any additional arguments passed to the function will specify " + "the arguments passed into the target script.

" + "getScriptExpGain([scriptname], [hostname/ip], [args...])
" + "Returns the amount of hacking experience the specified script generates while online (when the game is open, does not apply for " + "offline experience gains). This function can also return the total experience gain rate of all of your active scripts by running the function " + "with no arguments.

" + "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 arguments in this function call.

" + "The first argument, if specified, must be a string with the name of the script (including the .script extension). " + "The second argument must be a string with the hostname/IP of the target server. If the first argument is specified " + "then the second argument must be specified as well. Any additional arguments passed to the function will specify " + "the arguments passed into the target script.

" + "getTimeSinceLastAug()
" + "Returns the amount of time in milliseconds that have passed since you last installed Augmentations (or destroyed a BitNode).

" + "sprintf()/vsprintf()
" + "See this link for details

" + "prompt(message)
" + "Prompts the player with a dialog box with two options: 'Yes' and 'No'. This function will returns true if " + "the player clicks 'Yes' and false if the player click's 'No'. The script's execution is halted until the " + "player selects 'Yes' or 'No'. The function takes a single string as an argument which specifies the text " + "that appears on the dialog box.

" + "

Hacknet Nodes API


" + "Netscript provides the following API for accessing and upgrading your Hacknet Nodes through scripts. This API does NOT work offline.

" + "hacknetnodes
A special variable. This is an array that maps to the Player's Hacknet Nodes. The Hacknet Nodes are accessed through " + "indexes. These indexes correspond to the number at the end of the name of the Hacknet Node. For example, the first Hacknet Node you purchase " + "will have the same 'hacknet-node-0' and can be accessed with hacknetnodes[0]. The fourth Hacknet Node you purchase will have the name " + "'hacknet-node-3' and can be accessed with hacknetnodes[3].

" + "hacknetnodes.length
Returns the number of Hacknet Nodes that the player owns

" + "hacknetnodes[i].level
Returns the level of the corresponding Hacknet Node

" + "hacknetnodes[i].ram
Returns the amount of RAM on the corresponding Hacknet Node

" + "hacknetnodes[i].cores
Returns the number of cores on the corresponding Hacknet Node

" + "hacknetnodes[i].totalMoneyGenerated
Returns the total amount of money that the corresponding Hacknet Node has earned

" + "hacknetnodes[i].onlineTimeSeconds
Returns the total amount of time that the corresponding Hacknet Node has existed

" + "hacknetnodes[i].moneyGainRatePerSecond
Returns the income ($ / sec) that the corresponding Hacknet Node earns

" + "hacknetnodes[i].upgradeLevel(n)
Tries to upgrade the level of the corresponding Hacknet Node n times. The argument n must be a " + "positive integer. Returns true if the Hacknet Node's level is successfully upgraded n times or up to the max level (200), and false otherwise.

" + "hacknetnodes[i].upgradeRam()
Tries to upgrade the amount of RAM on the corresponding Hacknet Node. Returns true if the " + "RAM is successfully upgraded, and false otherwise.

" + "hacknetnodes[i].upgradeCore()
Attempts to purchase an additional core for the corresponding Hacknet Node. Returns true if the " + "additional core is successfully purchase, and false otherwise.

" + "Example: The following is an example of one way a script can be used to automate the purchasing and upgrading of Hacknet Nodes. " + "This script purchases new Hacknet Nodes until the player has four. Then, it iteratively upgrades each of those four Hacknet Nodes " + "to a level of at least 75, RAM to at least 8GB, and number of cores to at least 2.

" + "while(hacknetnodes.length < 4) {
" + "    purchaseHacknetNode();
" + "}
" + "for (i = 0; i < 4; i = i++) {
" + "    while (hacknetnodes[i].level <= 75) {
" + "        hacknetnodes[i].upgradeLevel(5);
" + "        sleep(10000);
" + "    }
" + "}
" + "for (i = 0; i < 4; i = i++) {
" + "    while (hacknetnodes[i].ram < 8) {
" + "        hacknetnodes[i].upgradeRam();
" + "        sleep(10000);
" + "    }
" + "}
" + "for (i = 0; i < 4; i = i++) {
" + "    while (hacknetnodes[i].cores < 2) {
" + "        hacknetnodes[i].upgradeCore();
" + "        sleep(10000);
" + "    }
" + "}

" + "

Trade Information eXchange (TIX) API


" + "getStockPrice(sym)
Returns the price of a stock. The argument passed in must be the stock's symbol (NOT THE COMPANY NAME!). The symbol " + "is a sequence of two to four capital letters. The symbol argument must be a string.

" + "Example: getStockPrice('FSIG');

" + "getStockPosition(sym)
Returns an array of two elements that represents the player's position in a stock. The first element " + "in the array is the number of shares the player owns of the specified stock. The second element in the array is the average price of the player's " + "shares. Both elements are numbers. The argument passed in must be the stock's symbol, which is a sequence of two to four capital letters.

" + "Example:

pos = getStockPosition('ECP');
shares = pos[0];
avgPx = pos[1];

"+ "buyStock(sym, shares)
Attempts to purchase shares of a stock using a Market Order. The first argument must be a string with the stock's symbol. The second argument " + "must be the number of shares to purchase.

" + "If the player does not have enough money to purchase specified number of shares, then no shares will be purchased (it will not purchase the most you can afford). " + "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(sym, shares)
Attempts to sell shares of a stock using a Market Order. The first argument must be a string with the stock's symbol. The second argument " + "must be the number of shares to sell.

" + "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(sym, shares)
" + "Attempts to purchase a short position of a stock using a Market Order. The first argument must be a string with the stock's symbol. The second argument " + "must be the number of shares to purchase.

" + "In order to use this function the player must be in BitNode-8 or must have Level 2 of Source-File 8.

" + "If the player does not have enough money to purchase the specified number of shares, then no shares will be purchased. Remember that every " + "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(sym, shares)
" + "Attempts to sell a short position of a stock using a Market Order. The first argument must be a string with the stock's symbol. The second argument must be the " + "number of shares to sell.

" + "In order to use this function the player must be in BitNode-8 or must have Level 2 of Source-File 8.

" + "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 was successful, this function will return the stock price at which each sale was sold. Otherwise, it will return 0.

" + "placeOrder(sym, shares, price, type, pos)
" + "Places an order on the stock market. This function only works for Limit and Stop Orders. Use the buyStock/sellStock/shortStock/sellShort functions " + "to place Market Orders. In order to use this function the player must be in BitNode-8 or must have Level 3 of Source-File 8.

" + "The 'sym' argument must be a string with the symbol of the stock. The 'shares' and 'price' arguments " + "specify the number of shares and the execution price for the order. They must be numeric.

" + "The 'type' argument is a string that specifies the type of order. It must specify either 'limit' or 'stop', and must " + "also specify 'buy' or 'sell'. This argument is NOT case-sensitive. Here are four examples that will work:

" + "limitbuy, limitsell, stopbuy, stopsell

" + "The last argument, 'pos', is a string that specifies whether the order is a 'Long' or 'Short' position. The values 'L' and " + "'S' can also be used. This argument is NOT case-sensitive.

" + "Returns true if the order is successfully placed, and false otherwise.

" + "cancelOrder(sym, shares, price, type, pos)
" + "Cancels an oustanding order on the stock market. In order to use this function the player must be in BitNode-8 or must have " + "Level 3 of Source-File 8. This function uses the same arguments as placeOrder()

" + "

While loops


" + "A while loop is a control flow statement that repeatedly executes code as long as a condition is met.

" + "while ([cond]) {
    [code]
}


" + "As long as [cond] remains true, the code block [code] will continuously execute. Example:

" + "i = 0;
while (i < 10) {
    hack('foodnstuff');
    i = i + 1;
}


" + "This code above repeats the 'hack('foodnstuff')' command 10 times before it stops and exits.

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


" + "This while loop above is an infinite loop (continuously runs until the script is manually stopped) that repeatedly runs the 'hack('foodnstuff')' command. " + "Note that a semicolon is needed at closing bracket of the while loop, UNLESS it is at the end of the code

" + "

For loops


" + "A for loop is another control flow statement that allows code to be repeated by iterations. The structure is:

" + "for ([init]; [cond]; [post]) {
    code
}


" + "The [init] expression evaluates before the for loop begins. The for loop will continue to execute " + "as long as [cond] is met. The [post] expression will evaluate at the end of every iteration " + "of the for loop. The following example shows code that will run the 'hack('foodnstuff');' command 10 times " + " using a for loop:

" + "for (i = 0; i < 10; i = i++) {
    hack('foodnstuff');
}


" + "

If statements


" + "If/Else if/Else statements are conditional statements used to perform different actions based on different conditions:

" + "if (condition1) {
    code1
} else if (condition2) {
    code2
} else {
" + "    code3
}


" + "In the code above, first condition1 will be checked. If this condition is true, then code1 will execute and the " + "rest of the if/else if/else statement will be skipped. If condition1 is NOT true, then the code will then go on to check " + "condition2. If condition2 is true, then code2 will be executed, and the rest of the if/else if/else statement " + "will be skipped. If none of the conditions are true, then the code within the else block (code3) will be executed. " + "Note that a conditional statement can have any number of 'else if' statements.

" + "Example:

" + "if(getServerMoneyAvailable('foodnstuff') > 200000) {
    hack('foodnstuff');
" + "} else {
    grow('foodnstuff');
}

" + "The code above will use the getServerMoneyAvailable() function to check how much money there is on the 'foodnstuff' server. " + "If there is more than $200,000, then it will try to hack that server. If there is $200,000 or less on the server, " + "then the code will call grow('foodnstuff') instead and add more money to the server.

", TutorialSingularityFunctionsText: "

Singularity Functions


" + "The Singularity Functions are a special set of Netscript functions that are unlocked in BitNode-4. " + "These functions allow you to control many additional aspects of the game through scripts, such as " + "working for factions/companies, purchasing/installing Augmentations, and creating programs.

" + "If you are in BitNode-4, then you will automatically have access to all of these functions. " + "You can use the Singularity Functions in other BitNodes if and only if you have the Source-File " + "for BitNode-4 (aka Source-File 4). Each level of Source-File 4 will open up additional Singularity " + "Functions that you can use in other BitNodes. If your Source-File 4 is upgraded all the way to level 3, " + "then you will be able to access all of the Singularity Functions.

" + "Note that Singularity Functions require a lot of RAM outside of BitNode-4 (their RAM costs are multiplied by " + "10 if you are not in BitNode-4).

" + "universityCourse(universityName, courseName)
" + "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 first argument must be a string with the name of the university. The names are NOT case-sensitive. " + "Note that you must be in the correct city for whatever university you specify. The three universities are:

" + "Summit University
Rothman University
ZB Institute of Technology

" + "The second argument must be a string with the name of the course you are taking. These names are NOT case-sensitive. " + "The available courses are:

" + "Study Computer Science
Data Structures
Networks
Algorithms
Management
Leadership

" + "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(gymName, stat)
" + "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 first argument must be a string with the name of the gym. The names are NOT case-sensitive. Note that you must " + "be in the correct city for whatever gym you specify. The available gyms are:

" + "Crush Fitness Gym
Snap Fitness Gym
Iron Gym
Powerhouse Gym
Millenium Fitness Gym

" + "The second argument must be a string with the stat you want to work out. These are NOT case-sensitive. " + "The valid stats are:

strength OR str
defense OR def
dexterity OR dex
agility OR agi

" + "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(cityname)
" + "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.

" + "The argument passed into this must be a string with the name of the city to travel to. Note that this argument IS CASE SENSITIVE. The valid cities are:

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

" + "This function will return true if you successfully travel to the specified city and false otherwise.

" + "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(programName)
" + "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 argument passed in must be a string with the name of the program (including the '.exe' extension). This argument is " + "NOT case-sensitive.

Example: " + "purchaseProgram('brutessh.exe');

" + "The cost of purchasing programs using this function is the same as if you were purchasing them through the Dark Web (using " + "the buy Terminal command).

" + "This function will return true if the specified program is purchased, and false otherwise.

" + "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:

" + "Player.hacking
Player.strength
Player.defense
Player.dexterity
Player.agility
Player.charisma
Player.intelligence

" + "Example:

" + "res = getStats();
print('My charisma level is: ' + res.charisma);

" + "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.

" + "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()
" + "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()
" + "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.

" + "applyToCompany(companyName, field)
" + "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.

" + "The first argument must be a string with the name of the company. This argument IS CASE-SENSITIVE. The second argument must " + "be a string representing the 'field' to which you want to apply. This second argument is NOT case-sensitive. Valid values for " + "the second argument are:

" + "software
software consultant
it
security engineer
network engineer
business
business consultant
" + "security
agent
employee
part-time employee
waiter
part-time waiter

" + "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(companyName)
" + "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.

" + "The argument passed in must be a string with the name of the company. This argument IS CASE-SENSITIVE.

" + "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(name)
" + "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.

" + "The argument must be a string with the name of the faction. This name IS CASE-SENSITIVE.

" + "workForFaction(factionName, workType)
" + "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.

" + "The first argument must be a string with the name of the faction. This argument IS CASE-SENSITIVE. The second argument " + "must be a string with the type of work you want to perform for the faction. The valid values for this argument are:

" + "
hacking/hacking contracts/hackingcontracts
field/fieldwork/field work
security/securitywork/security work

" + "This function will return true if you successfully start working for the specified faction, and false otherwise.

" + "getFactionRep(factionName)
" + "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. The argument must be a " + "string with the name of the Faction. The argument IS CASE-SENSITIVE.

" + "createProgram(programName)
" + "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.

" + "The argument passed in must be a string designating the name of the program. This argument is NOT case-sensitive.

" + "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(crime)
" + "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.

" + "The function takes a string that specifies what crime to attempt. This argument is not case-sensitive and 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

" + "Crimes committed using this function will have all of their earnings halved (this applies for both money and experience!)

" + "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(crime)
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). The argument for this function is a string. It is not case-sensitive and is fairly " + "lenient in terms of what inputs it accepts. Check the documentation for the commitCrime() Singularity Function to see " + "examples of valid inputs.

" + "getOwnedAugmentations(purchased=false)
" + "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 of the names of all Augmentations you own as strings. It takes a single optional " + "boolean argument that specifies whether the returned array should include Augmentations you have purchased " + "but not yet installed. If it is true, then the returned array will include these Augmentations. By default, " + "this argument is false.

" + "getAugmentationsFromFaction(facName)
" + "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. " + "The argument must be a string with the faction's name. This argument is case-sensitive.

" + "getAugmentationCost(augName)
" + "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.

" + "The argument passed in must be a string with the name of the Augmentation. This argument IS CASE-SENSITIVE. " + "If an invalid Augmentation name is passed in, this function will return the array [-1, -1].

" + "purchaseAugmentation(factionName, augName)
" + "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.

" + "The two arguments must be strings specifying the name of the Faction and Augmentation, respectively. These arguments are both CASE-SENSITIVE.

" + "This function will return true if the Augmentation is successfully purchased, and false otherwise.

" + "installAugmentations(cbScript)
" + "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.

" + "This function takes a single optional parameter that specifies a 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. This argument, if used, " + "must be a string with the name of the script.", 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.34.0
" + "-Slightly increased experience gain from Infiltration
" + "-buyStock(), sellStock(), shortStock(), and sellShort() Netscript function now return the stock price at which the transaction occurred, rather than a boolean. " + "If the function fails for some reason, 0 will be returned.
" + "-Hacking Mission Changes:
" + "---Shield and Firewall Nodes can now fortify
" + "---The effects of Fortifying are now ~30% lower
" + "---Conquering a Spam Node now increases your time limit by 25 secs instead of 15
" + "---Damage dealt by Attacking was slightly reduced
" + "---The effect of Scanning was slightly reduced
" + "" } export {CONSTANTS};