code:
/**
 * @returns {[DocumentFragment, number]}
 */
App.SF.AAR = function() {
	const endWeekCall = V.endweekFlag ? 1 : 0;
	const S = V.SF.Squad;
	const size = App.SF.upgrades.total();

	let profit = 0;
	let upkeep = 0;
	let income = 0;
	let incomeAdd = 0;
	const node = new DocumentFragment();
	if (V.SF.FS.Tension > 100 && endWeekCall > 0) {
		if (V.SF.FS.BadOutcome === undefined) {
			App.SF.fsIntegration.badOutcome();
		} else {
			App.UI.DOM.appendNewElement("div", node, `This week your arcology lost a bit of prosperity and large amount of reputation, due to the looming threat that The Colonel and her forces may resurface.`);
			V.arcologies[0].prosperity -= 25;
			V.rep = Math.clamp(V.rep, 0, 17500);
		}
	} else if (V.SF.FS.Tension < 100) {
		let Multiplier = {
			action: 1,
			troop: 1,
			unit: 1,
			depravity: 1
		};
		let FNG = 10 + (V.SF.ArmySize / 10);
		let unitCap = 2500;
		let Trade = 0.025;
		let cost = {a: 10, b: 10};
		let N0 = 1 + (0.01 * (size / 6));
		let N1 = 1 + (0.01 * (size / 3));

		let SFD = V.SF.Depravity;
		V.SF.ArmySize = Math.clamp(V.SF.ArmySize, 0, unitCap);
		if (endWeekCall > 0) {
			if (V.SF.ArmySize < 100) {
				V.SF.ArmySize += Math.ceil(jsRandom(2, 5));
			} else {
				if (V.SF.Target === "recruit") {
					V.SF.ArmySize -= Math.ceil(jsRandom(1 * V.SF.ArmySize / 1000, 0));
				} else if (V.SF.Target === "raiding") {
					V.SF.ArmySize -= Math.ceil(jsRandom(1.15 * V.SF.ArmySize / 1000, -1.20 * V.SF.ArmySize / 1000));
				} else {
					V.SF.ArmySize -= Math.ceil(jsRandom(1.10 * V.SF.ArmySize / 1000, -1.15 * V.SF.ArmySize / 1000));
				}
			}
		}

		if (V.SF.ArmySize > 200) {
			Trade += 0.05 * (V.SF.ArmySize / 200);
			Multiplier.troop += V.SF.ArmySize / 200;
			upkeep += V.SF.ArmySize * 33 * 1/N0;
			if (V.secExpEnabled > 0 && endWeekCall > 0) {
				App.SecExp.authorityX((25 * (Math.ceil(V.SF.ArmySize / 200))) + size * 10);
			}
		}

		if (S.Firebase > 0) {
			FNG += S.Firebase;
			Trade += 0.5 * S.Firebase;
			Multiplier.unit += 7.5 * S.Firebase + 2 * Math.pow(S.Firebase, 2) * cost.a;
			incomeAdd += (5000 * S.Firebase)/ Math.max(S.Firebase - 1, 1);
			upkeep += (95 * 10 + S.Firebase) * cost.b;
		}
		if (S.Armoury > 0) {
			FNG += 2 * S.Armoury;
			Trade += 0.25 * S.Armoury;
			Multiplier.unit += 7.5 * S.Armoury + 2 * Math.pow(S.Armoury, 2) * cost.a;
			incomeAdd += (3000 * S.Armoury)/Math.max(S.Armoury - 1, 1);
			upkeep += (55 * S.Armoury) * cost.b;
		}
		if (S.Drugs > 0) {
			FNG += S.Drugs;
			Trade += 0.25 * S.Drugs;
			Multiplier.unit += 7.5 * S.Drugs + 2 * Math.pow(S.Drugs, 2) * cost.a;
			incomeAdd += (3000 * S.Drugs)/Math.max(S.Drugs - 1, 1);
			upkeep += (35 * S.Drugs) * cost.b;
		}
		if (S.Firebase >= 1) {
			if (S.AV > 0) {
				FNG += S.AV;
				Trade += 0.25 * S.AV;
				Multiplier.unit += 7.5 * S.AV + 2 * Math.pow(S.AV, 2) * cost.a;
				upkeep += (89 * S.AV) * cost.b;
			}
			if (S.TV > 0) {
				FNG += S.TV;
				Trade += 0.25 * S.TV;
				Multiplier.unit += 7.5 * S.TV + 2 * Math.pow(S.TV, 2) * cost.a;
				upkeep += (89 * S.TV) * cost.b;
			}
			if (S.PGT > 0) {
				FNG += S.PGT;
				Trade += 0.25 * S.PGT;
				Multiplier.unit += 15 * S.PGT + 3 * Math.pow(S.PGT, 2) * cost.a;
				upkeep += (100 * S.PGT) * cost.b;
			}
		}

		if (S.Firebase >= 2 && S.Drones > 0) {
			FNG += S.Drones;
			Trade += 0.5 * S.Drones;
			Multiplier.unit += 7.5 * S.Drones + 2 * Math.pow(S.Drones, 2) * cost.a;
			upkeep += (50 * S.Drones) * cost.b;
		}

		if (S.Firebase >= 4) {
			if (S.AA > 0) {
				FNG += S.AA;
				Trade += 0.25 * S.AA;
				Multiplier.unit += 7.5 * S.AA + 2 * Math.pow(S.AA, 2) * cost.a;
				upkeep += (100 * S.AA) * cost.b;
			}
			if (S.TA > 0) {
				FNG += S.TA;
				Trade += 0.25 * S.TA;
				Multiplier.unit += 7.5 * S.TA + 2 * Math.pow(S.TA, 2) * cost.a;
				upkeep += (100 * S.TA) * cost.b;
			}
			if (S.SpacePlane > 0) {
				FNG += S.SpacePlane;
				Trade += 0.25 * S.SpacePlane;
				Multiplier.unit += 7.5 * S.SpacePlane + 2 * Math.pow(S.SpacePlane, 2) * cost.a;
				upkeep += (100 * S.SpacePlane) * cost.b;
			}
			if (S.GunS > 0) {
				FNG += S.GunS;
				Trade += 0.25 * S.GunS;
				Multiplier.unit += 12 * S.GunS + 3 * Math.pow(S.GunS, 2) * cost.a;
				upkeep += (70 * S.GunS) * cost.b;
			}
			if (S.Satellite > 0 && S.SatLaunched > 0) {
				FNG += S.Satellite;
				Trade += 0.25 * S.Satellite;
				Multiplier.unit += 15 * S.Satellite + 5 * Math.pow(S.Satellite, 2) * cost.a;
				upkeep += (85 * S.Satellite) * cost.b;
			}
			if (S.GiantRobot > 0) {
				FNG += S.GiantRobot;
				Trade += 0.25 * S.GiantRobot;
				Multiplier.unit += 15 * S.GiantRobot + 5 * Math.pow(S.GiantRobot, 2) * cost.a;
				upkeep += (95 * S.GiantRobot) * cost.b;
			}
			if (S.MissileSilo > 0) {
				FNG += S.MissileSilo;
				Trade += 0.25 * S.MissileSilo;
				Multiplier.unit += 15 * S.MissileSilo + 5 * Math.pow(S.MissileSilo, 2) * cost.a;
				upkeep += (100 * S.MissileSilo) * cost.b;
			}
		}

		if (S.AircraftCarrier > 0) {
			FNG += S.AircraftCarrier;
			Trade += 0.25 * S.AircraftCarrier;
			Multiplier.unit += 9 * S.AircraftCarrier + 3 * Math.pow(S.AircraftCarrier, 2) * cost.a;
			upkeep += (80 * S.AircraftCarrier) * cost.b;
		}
		if (S.Sub > 0) {
			FNG += S.Sub;
			Trade += 0.25 * S.Sub;
			Multiplier.unit += 7.5 * S.Sub + 2 * Math.pow(S.Sub, 2) * cost.a;
			upkeep += (90 * S.Sub) * cost.b;
		}
		if (S.HAT > 0) {
			FNG += S.HAT;
			Trade += 0.25 * S.HAT;
			Multiplier.unit += 7.5 * S.HAT + 2 * Math.pow(S.HAT, 2) * cost.a;
			upkeep += (70 * S.HAT) * cost.b;
		}

		switch (V.SF.Colonel.Core) {
			case "kind":
				FNG += 10;
				Trade += 0.15;
				SFD -= 0.15;
				break;
			case "cruel":
				Trade -= 0.15;
				SFD += 0.15;
				break;
			case "brazen":
				FNG += 15;
				Multiplier.unit += 0.5;
				break;
			case "jaded":
				Trade -= 0.05;
				SFD += 0.05;
				break;
			case "shell shocked":
				Trade += 0.05;
				SFD -= 0.05;
				Multiplier.unit -= 0.5;
				break;
		}

		if (V.SF.Target === "raiding") {
			SFD += 0.05;
			Multiplier.action += 0.5;
		} else if (V.SF.Target === "secure") {
			SFD -= 0.05;
			Multiplier.action += 0.2;
		} else {
			SFD -= 0.1;
			Multiplier.action -= 0.5;
		}
		if (V.SF.ROE === "free") {
			Multiplier.action *= 0.8;
			SFD += 0.05;
			Trade += Trade * 0.95;
		} else if (V.SF.ROE === "hold") {
			Multiplier.action *= 1.1;
			SFD -= 0.05;
			Trade += Trade * 1.05;
		}
		if (V.SF.Regs === "none") {
			Multiplier.action *= 0.8;
			SFD += 0.05;
			Trade += Trade * 0.95;
		} else if (V.SF.Regs === "strict") {
			Multiplier.action *= 1.1;
			SFD -= 0.05;
			Trade += Trade * 1.05;
			Multiplier.depravity = 1 + SFD;
		}
		if (SFD > -2) {
			Trade *= 1 + SFD / 2;
		}

		if (V.SF.Target === "recruit") {
			FNG += FNG * 0.95;
		} else {
			FNG += FNG * 0.25;
		}
		FNG = Math.ceil(FNG / 2);

		if (endWeekCall > 0) {
			if (V.SF.Target === "secure") {
				repX((Math.ceil(V.rep * ((Trade / 100) * 0.95))), "specialForces");
				V.arcologies[0].prosperity = Math.ceil((V.arcologies[0].prosperity + (Trade / 10) * 0.95));
			} else {
				repX((Math.ceil(V.rep * (Trade / 100) * 0.25)), "specialForces");
				V.arcologies[0].prosperity = Math.ceil(V.arcologies[0].prosperity + (Trade / 10) * 0.25);
			}
		}

		income += (1 + Multiplier.troop / N0) * (1 + Multiplier.unit / N0) * (1 + Multiplier.action / N0) * (1 + Multiplier.depravity / N0);
		upkeep += 30000 + (25000 * 1 / N1);
		if (V.SF.Target === "raiding") {
			income *= 1.25;
		} else if (V.SF.Target === "secure") {
			income *= 1.05;
		} else { // When recruiting, upkeep is lowered, effect dependent on amount of soldiers. At max capacity, multiplier back to 1.
			upkeep *= 0.75 + (V.SF.ArmySize/10000);
		}

		if (V.economy.isBetween(33, 100)) {
			let multiplier = (1.75 * Math.sqrt(Math.trunc(100000/V.economy-1000)/10)) + (0.2 * (Math.trunc(100000/V.economy-1000)/10));
			income *= (1 + multiplier/100);
		} else if (V.economy <= 33) { // There comes a point where a worse global economy no longer benefits your Special Forces.
			let multiplier = (1.75 * Math.sqrt(Math.trunc(100000/33-1000)/10)) + (0.2 * (Math.trunc(100000/33-1000)/10));
			income *= (1 + multiplier/100);
		}
		income = Math.ceil(income + incomeAdd);
		upkeep = Math.ceil(upkeep);
		profit = income - upkeep;

		if (endWeekCall > 0) {
			V.SF.ArmySize += FNG;
			if (V.debugMode > 0) {
				App.UI.DOM.appendNewElement("div", node, `income:${cashFormat(income)}, upkeep:${cashFormat(upkeep)}, profit:${cashFormat(profit)}, troop:${num((0.09+Multiplier.troop/N0).toFixed(2))}, unit:${num((0.09+Multiplier.unit/N0).toFixed(2))}, action:${num((0.09+Multiplier.action/N0).toFixed(2))}, depravity:${num((0.09+Multiplier.depravity/N0).toFixed(2))}, N0: ${N0} N1: ${N1}`);
			}

			cashX(income, "specialForces");
			// We run this in economyJS.js now.
			// cashX(forceNeg(upkeep), "specialForces");
			V.SF.ArmySize = Math.clamp(V.SF.ArmySize, 0, unitCap);
			V.arcologies[0].prosperity = Math.clamp(V.arcologies[0].prosperity, 0, V.AProsperityCap);

			if (V.SF.UC.Assign === 1 && V.SF.UC.Lock < 1) {
				V.SF.UC.Assign = 0;
			}
			V.SF.Upgrade = 0;

			const capSF = capFirstChar(V.SF.Lower || "the special force");
			App.UI.DOM.appendNewElement("h3", node, `${capSF} (AO: ${V.terrain}) operational report:`);
			App.UI.DOM.appendNewElement("span", node, ` ${capSF} focused their ${num(V.SF.ArmySize)} troops on`);

			if (V.SF.Target === "recruit") {
				App.UI.DOM.appendNewElement("span", node, ` recruiting and training more personnel. Smaller parties ventured out to protect the arcology's trade routes and strike targets of opportunity.`);
			} else if (V.SF.Target === "secure") {
				App.UI.DOM.appendNewElement("span", node, ` securing the trade routes between the arcology and the surrounding area. Smaller parties ventured out to strike targets of opportunity and process new recruits.`);
			} else {
				App.UI.DOM.appendNewElement("span", node, ` locating and striking targets of opportunity, capturing both material loot and new slaves. Smaller parties secured the most important of the arcology's trade routes and processed new recruits.`);
			}

			if (V.SF.UC.Assign > 0) {
				App.UI.DOM.appendNewElement("div", node, `A ${V.SF.UC.Assign < 2 ? 'small':'large'} portion of the force was assigned as ${V.SF.UC.Assign < 2 ? 'part':'full'} time undercover officers.`);
			}

			App.UI.DOM.appendNewElement("span", node, " These activities have, overall");
			App.UI.DOM.appendNewElement("span", node, " improved your arcology's prosperity.", "green");
			App.UI.DOM.appendNewElement("span", node, ` The goods procured by ${V.SF.Lower} after accounting for the spoils retained by individual soldiers were`);

			if (profit > 0) {
				App.UI.DOM.appendNewElement("span", node, " more than sufficient to cover expenses.", "green");
				App.UI.DOM.appendNewElement("span", node, " Excess material and human assets totaling");
				App.UI.DOM.appendNewElement("span", node, ` ${cashFormat(profit)}`, "yellowgreen");
				App.UI.DOM.appendNewElement("span", node, " (after liquidation) and paying expenses were transferred to your accounts.");
				if (V.economy < 100) {
					App.UI.DOM.appendNewElement("span", node, " The rapidly degrading global economy has one upside,");
					App.UI.DOM.appendNewElement("span", node, ` more 'persuasive' techniques were able to be implemented thus leading to an increase in profit.`, "green");
				}
			} else {
				App.UI.DOM.appendNewElement("span", node, " barely enough to cover expenses.", "red");
				App.UI.DOM.appendNewElement("span", node, " More growth will be needed to ensure profitability;");
				App.UI.DOM.appendNewElement("span", node, " purchasing more upgrades may help.", "yellow");
				App.UI.DOM.appendNewElement("span", node, " Per estimates provided, an additional");
				App.UI.DOM.appendNewElement("span", node, ` ${cashFormat(Math.abs(profit))}`, "yellowgreen");
				App.UI.DOM.appendNewElement("span", node, " is required for sufficient cover.");
			}
			App.UI.DOM.appendNewElement("span", node, ` This represents a difference of ${num(Math.abs(((profit/V.SF.lastWeeksProfit)*100).toFixed(2)))}% since last week's profit of ${cashFormat(V.SF.lastWeeksProfit)}.`);
			V.SF.lastWeeksProfit = profit;

			App.UI.DOM.appendNewElement("span", node, ` ${FNG} new soldiers were recruited this week, and your reputation has`);
			App.UI.DOM.appendNewElement("span", node, " increased through the improvement of trade security.", "green");
			App.UI.DOM.appendNewElement("p", node, weeklyActions());
			App.UI.DOM.appendNewElement("h3", node, `Operational choices:`);
			App.UI.DOM.appendNewElement("div", node, weeklyOptions());

			App.UI.DOM.appendNewElement("p", node, DeploymentFocus());
			App.UI.DOM.appendNewElement("p", node, ROE());
			App.UI.DOM.appendNewElement("p", node, Accountability());
			App.Events.addParagraph(node, ["Force depravity affects trade."]);

			if (V.SF.MercCon.CanAttend === 1) {
				V.SF.MercCon.Income = 0;
				V.SF.MercCon.Menials = 0;
				const tradeShowAttendes = 200;
				const menialGiftsPerAttendee = 5;
				const menialGifts = Math.ceil(jsRandom(1, ((tradeShowAttendes * menialGiftsPerAttendee) / 10)));
				const TSProfit = Math.ceil(500000 * (1 + (size / 1000)) * (1 + (V.arcologies[0].prosperity / 1000)) * App.SF.env());
				const NewMercs = jsRandom(1, (tradeShowAttendes / 10));

				V.SF.MercCon.Menials += menialGifts;
				V.SF.MercCon.TotalMenials += menialGifts;
				V.menials += menialGifts;
				V.SF.MercCon.History++;
				V.SF.MercCon.Income += TSProfit;
				V.SF.MercCon.Revenue += TSProfit;
				cashX(TSProfit, "specialForces");

				if (V.secExpEnabled > 0 && V.mercenaries > 0) {
					V.SF.MercCon.Mercs = 0;
					V.SecExp.units.mercs.free += NewMercs;
					V.SF.MercCon.TotalMercs += NewMercs;
					V.SF.MercCon.Mercs += NewMercs;
				}
				App.UI.DOM.appendNewElement("span", node, "TradeShow: ", "bold");
				App.UI.DOM.appendNewElement("span", node, `During a break, The Colonel managed to sell some generic schematics to the ${tradeShowAttendes} attendees, some of whom decided to also give a few menial slaves as a bonus.`);
			}

			V.SF.MercCon.CanAttend = -1;
		}
		return [node, upkeep];
	}

	function DeploymentFocus() {
		const text = new DocumentFragment();
		let focus = document.createElement("span");
		App.UI.DOM.appendNewElement("span", focus, mapping());

		App.UI.DOM.appendNewElement("span", text, "Deployment focus: ");
		App.UI.DOM.appendNewElement("span", text, focus, "bold");

		App.UI.DOM.appendNewElement("div", text, App.UI.DOM.link("Recruiting and Training",
			() => {
				V.SF.Target = "recruit";
				App.UI.DOM.replace(focus, "Recruiting and Training");
			}, [], "",
			"Increases the amount of FNGs at the cost of revenue."
		), "indent");

		App.UI.DOM.appendNewElement("div", text, App.UI.DOM.link("Securing Trade Routes",
			() => {
				V.SF.Target = "secure";
				App.UI.DOM.replace(focus, "Securing Trade Routes");
			}, [], "",
			"Increases trade and reputation at the cost of revenue."
		), "indent");

		App.UI.DOM.appendNewElement("div", text, App.UI.DOM.link("Raiding and Slaving",
			() => {
				V.SF.Target = "raiding";
				App.UI.DOM.replace(focus, "Raiding and Slaving");
			}, [], "",
			"Increases revenue at the cost of less FNGs and increased force depravity."
		), "indent");

		return text;

		function mapping() {
			switch (V.SF.Target) {
				case "recruit":
					return "Recruiting and Training";
				case "secure":
					return "Securing Trade Routes";
				case "raiding":
					return "Raiding and Slaving";
			}
		}
	}

	function ROE() {
		const text = new DocumentFragment();
		let focus = document.createElement("span");
		App.UI.DOM.appendNewElement("span", focus, mapping());

		App.UI.DOM.appendNewElement("span", text, "Rules of Engagements: ");
		App.UI.DOM.appendNewElement("span", text, focus, "bold");

		App.UI.DOM.appendNewElement("div", text, App.UI.DOM.link("Hold Fire",
			() => {
				V.SF.ROE = "hold";
				App.UI.DOM.replace(focus, mapping());
			}, [], "",
			"Reduces force depravity."
		), "indent");

		App.UI.DOM.appendNewElement("div", text, App.UI.DOM.link("limited Fire",
			() => {
				V.SF.ROE = "limited";
				App.UI.DOM.replace(focus, mapping());
			}, [], "",
			"Does not adjust force depravity."
		), "indent");

		App.UI.DOM.appendNewElement("div", text, App.UI.DOM.link("Free Fire",
			() => {
				V.SF.ROE = "free";
				App.UI.DOM.replace(focus, mapping());
			}, [], "",
			"Increases force depravity."
		), "indent");

		return text;

		function mapping() {
			switch (V.SF.ROE) {
				case "hold":
					return "Hold Fire";
				case "limited":
					return "limited Fire";
				case "free":
					return "Free Fire";
			}
		}
	}

	function Accountability() {
		const text = new DocumentFragment();
		let focus = document.createElement("span");
		App.UI.DOM.appendNewElement("span", focus, mapping());

		App.UI.DOM.appendNewElement("span", text, "Rules of Engagements: ");
		App.UI.DOM.appendNewElement("span", text, focus, "bold");

		App.UI.DOM.appendNewElement("div", text, App.UI.DOM.link("Strict Accountability",
			() => {
				V.SF.Regs = "strict";
				App.UI.DOM.replace(focus, mapping());
			}, [], "",
			"Reduces force depravity."
		), "indent");

		App.UI.DOM.appendNewElement("div", text, App.UI.DOM.link("Some Accountability",
			() => {
				V.SF.Regs = "some";
				App.UI.DOM.replace(focus, mapping());
			}, [], "",
			"Does not adjust force depravity."
		), "indent");

		App.UI.DOM.appendNewElement("div", text, App.UI.DOM.link("No Accountability",
			() => {
				V.SF.Regs = "none";
				App.UI.DOM.replace(focus, mapping());
			}, [], "",
			"Increases force depravity."
		), "indent");

		return text;

		function mapping() {
			switch (V.SF.Regs) {
				case "strict":
					return "Strict Accountability";
				case "some":
					return "Some Accountability";
				case "none":
					return "No Accountability";
			}
		}
	}

	function weeklyOptions() {
		const choices = document.createElement("span");
		App.UI.DOM.appendNewElement("div", choices, `The Colonel looks down a list on her tablet. "There's some things we can do to help you out, boss.`);
		App.UI.DOM.appendNewElement("div", choices, App.UI.DOM.link("Request cash",
			() => {
				weeklyGift(1);
				App.UI.DOM.replace(choices, "");
			}, [], "",
			"We've had some good prizes turn up, that's made us some extra money we could turn over."
		));

		if (V.rep < 20000) {
			App.UI.DOM.appendNewElement("div", choices, App.UI.DOM.link("military parade",
				() => {
					weeklyGift(2);
					App.UI.DOM.replace(choices, "");
				}, [], "",
				"If you want we could throw a quick military parade, get the people feeling extra patriotic."
			));
		}

		if (V.arcologies[0].prosperity < V.AProsperityCap) {
			App.UI.DOM.appendNewElement("div", choices, App.UI.DOM.link("Request sabotage",
				() => {
					weeklyGift(3);
					App.UI.DOM.replace(choices, "");
				}, [], "",
				`Or we could hit some businesses that rival the ones in ${V.arcologies[0].name} with some sabotage.`
			));
		}

		return choices;

		/**
			* @param {number} input
			*/
		function weeklyGift(input) {
			let value;
			let EnvProsp;
			const env = App.SF.env();
			const size = App.SF.upgrades.total();

			switch (input) {
				case 1: // Request cash
					cashX(Math.max(Math.ceil(25000 * (size/10) * env), 5000), "specialForcesCap");
					break;
				case 2: // Request military parade
					value = 50 * (Math.ceil(size * 0.03 * env));
					repX((Number(value) ? value : 500), "specialForces");
					break;
				case 3: // Request sabotage
					switch (env) {
						case 4: EnvProsp = 3; break;
						case 3: EnvProsp = 5; break;
						case 2: EnvProsp = 7; break;
					}
					value = EnvProsp + (Math.ceil(size/100 * env));
					if (V.arcologies[0].prosperity + value * 0.8 > V.AProsperityCap) {
						V.arcologies[0].prosperity = V.AProsperityCap;
					} else {
						V.arcologies[0].prosperity += Math.ceil(value * 0.8);
					}
			}
		}
	}

	function weeklyActions() {
		const colonelTalkTensionRuction = V.SF.FS.Tension !== -1 ? 5 : 0;
		const choices = document.createElement("span");

		if (V.SF.Colonel.Status >= 25) {
			App.UI.DOM.appendNewElement("div", choices, App.UI.DOM.link("Walk with The Colonel on the surface",
				() => {
					V.SF.Colonel.Status += 2;
					V.SF.FS.Tension -= colonelTalkTensionRuction;
					const Env = {};
					const text = document.createElement("span");
					switch (App.SF.env()) {
						case 4:
							Env.cash2 = 450;
							Env.cash3 = 200;
							Env.cash4 = 100;
							break;
						case 3:
							Env.cash2 = 500;
							Env.cash3 = 250;
							Env.cash4 = 150;
							break;
						case 2:
							Env.cash2 = 550;
							Env.cash3 = 300;
							Env.cash4 = 200;
					}
					let r = [];
					r.push("You ask The Colonel if she would like to stretch her legs up on the surface. It doesn't take much effort for her to agree.");
					if (V.PC.skill.warfare >= 100 && V.PC.career === "mercenary") {
						r.push(`Your mastery of wet work and prior experience in a PMC satisfies The Colonel that between you${S.Bodyguard ? `, ${S.Bodyguard.slaveName},` : ``} and her, there should be little threat to walking around the arcology.`);
						r.push(`Being able to see and interact with the arcology owner directly maintains the false idea that you're just like one of them while also giving them an increased opportunity to try gaining your favor.`);
						repX(10, "specialForces");
						cashX(Env.cash2, "specialForces");
					} else if (V.PC.skill.warfare >= 100) {
						r.push(`Your mastery of wet work satisfies The Colonel that you only need two soldiers ${S.Bodyguard ? `plus ${S.Bodyguard.slaveName}` : ``} to walk safely around the arcology.`);
						r.push(`Being able to see and interact with the arcology owner directly maintains the false idea that you're just like one of them while also giving them an increased opportunity to try gaining your favor.`);
						repX(5, "specialForces");
						cashX(Env.cash3, "specialForces");
					} else if (V.PC.skill.warfare >= 60) {
						r.push(`With some expertise in warfare, The Colonel believes ${S.Bodyguard ? `with ${S.Bodyguard.slaveName}` : ``} you only need a squad of armed soldiers for a walk through the arcology.`);
					} else if (V.PC.skill.warfare >= 30) {
						r.push(`As you have some skill in warfare, The Colonel believes ${S.Bodyguard ? `in addition to ${S.Bodyguard.slaveName}` : ``} you only need two full squads of armed soldiers for a walk around the arcology.`);
					} else if (V.PC.skill.warfare >= 10) {
						r.push(`Your minor skill in warfare convinces The Colonel that ${S.Bodyguard ? `in addition to ${S.Bodyguard.slaveName},` : ``} you need two full squads of armed soldiers and an armored car escort for a simple walk around the arcology.`);
					} else {
						r.push(`Your complete lack of combat skill convinces The Colonel that ${S.Bodyguard ? `in addition to ${S.Bodyguard.slaveName},` : ``} you need two full squads of armed soldiers, an armored car escort, and a sniper overwatch for a simple walk around the arcology.`);
					}
					App.UI.DOM.appendNewElement("div", text, r.join(" "));

					r = [];
					r.push("As you make your way through the arcology you stop at a");
					if (V.arcologies[0].FSPaternalist !== "unset") {
						r.push(`paternalist shop, ${V.SF.Colonel.Core === "cruel" ? "earning a sneer from The Colonel" : "helping The Colonel select some luxurious and relaxing slave treatments"}.`);
					} else if (V.arcologies[0].FSPastoralist !== "unset") {
						r.push(`pastoralist shop, helping The Colonel select a more comfortable breast pump.`);
					} else {
						r.push(`shop that catches The Colonel's eye.`);
					}
					if (V.PC.skill.slaving >= 100 && V.PC.career === "slaver") {
						r.push(`Your mastery and extensive history of slaving allows you to assist The Colonel greatly. The shop owner is so impressed by your understanding of slavery that she asks you for some advice. Before you leave, you manage to pass on a few tips, helping the business with future customers.`);
						if (V.arcologies[0].prosperity < V.AProsperityCap) {
							V.arcologies[0].prosperity += 2;
						}
					} else if (V.PC.skill.slaving >= 100) {
						r.push(`Your mastery of slaving allows you to assist The Colonel greatly. The shop owner is so impressed by your understanding of slavery that she asks you for some advice. Before you leave, you manage to pass on a few tips, helping the business with future customers.`);
						if (V.arcologies[0].prosperity < V.AProsperityCap) {
							V.arcologies[0].prosperity++;
						}
					} else if (V.PC.skill.slaving >= 60) {
						r.push(`Your expertise in slavery allows you to help The Colonel decide what to buy for her main slave.`);
					} else if (V.PC.skill.slaving >= 30) {
						r.push(`Your moderate skill in slavery makes you somewhat helpful to The Colonel in deciding what to buy for her main slave.`);
					} else if (V.PC.skill.slaving >= 10) {
						r.push(`Your basic skill level of slavery doesn't allow you to help The Colonel at all.`);
					} else if (V.PC.skill.slaving < 10) {
						r.push(`Your total lack of slavery skill (which is very unusual and very concerning for an arcology owner) means that you are of little to no help or even a hindrance. The shopkeeper notices your complete ineptitude, and as soon as you've left the rumor mill begins.`);
						repX(-20, "PCactions");
					}
					App.UI.DOM.appendNewElement("div", text, r.join(" "));

					r = [];
					r.push(`Soon the entourage heads back to the HQ of ${V.SF.Lower}.`);
					if (random(1, 100) > 50) {
						r.push(`Along the route you see a homeless citizen with a serious injury begging for help.`);
						if (V.PC.skill.medicine >= 100 && V.PC.career === "medicine") {
							r.push(`Your expertise in surgery ensures that the citizen receives the best care they'll ever experience in their life. They are so grateful that they are more than happy to try and compensate your time. Word quickly spreads of the kindly medically trained arcology owner who took the time to heal a citizen, providing confidence to the rest of the citizens.`);
							repX(10, "specialForces");
							cashX(Env.cash4, "specialForces");
						} else if (V.PC.skill.medicine >= 100) {
							r.push(`Your expertise in surgery ensures that the citizen receives the best care they'll ever experience in their life. Word quickly spreads of the kindly arcology owner who took the time to heal a citizen.`);
							repX(5, "specialForces");
						} else if (V.PC.skill.medicine >= 60) {
							r.push(`Your proficiency in surgery allows you to properly close their wound with minimal trauma to the patient.`);
						} else if (V.PC.skill.medicine >= 30) {
							r.push(`Your moderate surgical skill ensures that you can close the citizen's wound, though not without likely scarring.`);
						} else if (V.PC.skill.medicine >= 10) {
							r.push(`Your basic surgical skill in medicine is sufficient only to stabilize the citizen's wounds before medical assistance arrives.`);
						} else {
							r.push(`Your total lack of surgical skill causes the death of the citizen through repeated medical blunders.`);
							V.arcologies[0].prosperity -= 0.25;
						}
					}
					App.UI.DOM.appendNewElement("div", text, r.join(" "));

					App.UI.DOM.replace(choices, text);
				}
			));
		}

		App.UI.DOM.appendNewElement("div", choices, App.UI.DOM.link(`Talk in ${V.SF.Lower}'s HQ`,
			() => {
				const option = document.createElement("span");
				App.UI.DOM.appendNewElement("div", option, "What do you want to do with The Colonel in the HQ?");

				App.UI.DOM.appendNewElement("div", option, App.UI.DOM.link("Talk",
					() => {
						V.SF.Colonel.Status += 3;
						V.SF.FS.Tension -= colonelTalkTensionRuction;
						switch (random(1, 6)) {
							case 1:
								IncreasePCSkills(['medicine', 'trading', 'slaving'], 1);
								break;
							case 2:
								IncreasePCSkills(['trading', 'slaving', 'engineering'], 1);
								break;
							case 3:
								IncreasePCSkills(['slaving', 'engineering', 'hacking'], 1);
								break;
							case 4:
								IncreasePCSkills(['engineering', 'hacking', 'warfare'], 1);
								break;
							case 5:
								IncreasePCSkills(['hacking', 'warfare', 'medicine'], 1);
								break;
							case 6:
								IncreasePCSkills(['warfare', 'medicine', 'trading'], 1);
						}
						App.UI.DOM.replace(option, `You and The Colonel talk over some ${V.PC.refreshment}, where she ends up talking about her past. You learn a little more about her.`);
					}
				));

				App.UI.DOM.appendNewElement("div", option, App.UI.DOM.link("Learn",
					() => {
						V.SF.Colonel.Status++;
						V.SF.FS.Tension -= colonelTalkTensionRuction;
						let r = [`"Sure boss, I can use a break from all of this," she laughs. The Colonel tells a story about one time when she`];
						switch (random(1, 6)) {
							case 1:
								r.push(`used field medicine to save another merc's life, teaching you some medical procedures in the process.`);
								IncreasePCSkills('medicine', 5);
								break;
							case 2:
								r.push(`haggled for necessary gear with a stingy quartermaster, teaching you how to get what you want from traders.`);
								IncreasePCSkills('trading', 5);
								break;
							case 3:
								r.push(`found a load of human chattel in a raid and had to manage them before they could later be unloaded, teaching you how to better care for your slaves.`);
								IncreasePCSkills('slaving', 5);
								break;
							case 4:
								r.push(`was responsible for rebuilding a fort she had seized, teaching you how to better manage construction in your arcology.`);
								IncreasePCSkills('engineering', 5);
								break;
							case 5:
								r.push(`was forced to hack her way out of a trap, teaching you how to better penetrate digital security.`);
								IncreasePCSkills('hacking', 5);
								break;
							case 6:
								r.push(`fought off an entire battalion with only a small squad, teaching you how to think tactically in battle.`);
								IncreasePCSkills('warfare', 5);
						}
						App.UI.DOM.replace(option, r.join(" "));
					}
				));

				if (V.SF.Colonel.Status >= 45) {
					App.UI.DOM.appendNewElement("div", option, App.UI.DOM.link("Have some fun",
						() => {
							V.SF.Colonel.Status += 3;
							V.SF.FS.Tension -= colonelTalkTensionRuction;

							const choice = document.createElement("span");
							App.UI.DOM.appendNewElement("div", choice, "Where should this fun take place?");

							App.UI.DOM.appendNewElement("div", choice, App.UI.DOM.link("In private",
								() => {
									App.UI.DOM.replace(choice, sexOptions());
								}
							));

							App.UI.DOM.appendNewElement("div", choice, App.UI.DOM.link("On The Colonel's throne",
								() => {
									App.UI.DOM.replace(choice, sexOptions());
								}
							));

							App.UI.DOM.replace(option, choice);
						}
					));
				}

				function sexOptions() {
					const options = document.createElement("span");
					App.UI.DOM.appendNewElement("div", options, "Which orifice do you wish to target?");
					App.UI.DOM.appendNewElement("div", options, App.UI.DOM.link("Pussy",
						() => {
							App.UI.DOM.replace(options, ColonelSexDec());
						}
					));

					App.UI.DOM.appendNewElement("div", options, App.UI.DOM.link("Ass",
						() => {
							App.UI.DOM.replace(options, ColonelSexDec());
						}
					));

					App.UI.DOM.appendNewElement("div", options, App.UI.DOM.link("Both pussy and ass",
						() => {
							App.UI.DOM.replace(options, ColonelSexDec());
						}
					));

					App.UI.DOM.appendNewElement("div", options, App.UI.DOM.link("Mouth",
						() => {
							App.UI.DOM.replace(options, ColonelSexDec());
						}
					));

					App.UI.DOM.appendNewElement("div", options, App.UI.DOM.link("All three holes",
						() => {
							App.UI.DOM.replace(options, ColonelSexDec());
						}
					));
					return options;
				}

				App.UI.DOM.replace(choices, option);
			}
		));

		return choices;
	}

	function ColonelSexDec() {
		const description = document.createElement("span");
		switch (V.SF.Colonel.Core) {
			case "shell shocked":
				App.UI.DOM.appendNewElement("div", description, "The entire time it is obvious that The Colonel is reliving a horrible event.");
				App.UI.DOM.appendNewElement("div", description, App.UI.DOM.link("Try to bring her back",
					() => {
						App.UI.DOM.replace(description, "You made an attempt to try to bring her back to the present.");
					}
				));
				App.UI.DOM.appendNewElement("div", description, App.UI.DOM.link("Leave her be",
					() => {
						App.UI.DOM.replace(description, "It is probably better that she tries to deal with her demons alone.");
					}
				));
				break;
			default:
				App.UI.DOM.appendNewElement("div", description, "Inset sex noises here.");
		}
		return description;
	}
};


code:
App.UI.FireBase = function() {
	const max = App.SF.upgrades.max();
	const size = App.SF.upgrades.total();
	const isBrazen = V.SF.Colonel.Core === "brazen";
	const node = document.createElement("span");
	let r = [];

	if (V.SF.FS.Tension > 100) {
		node.append(App.SF.fsIntegration.badOutcome());
	} else {
		if (V.cheatMode > 0 || V.debugMode > 0) {
			App.UI.DOM.appendNewElement("div", node, App.UI.DOM.passageLink("Edit", "editSF"));
		}

		node.append(
			`The firebase of ${V.arcologies[0].name}'s `,
			App.UI.DOM.makeTextBox(V.SF.Lower, str => { V.SF.Lower = str; }),
			` is located in the lower levels, occupying unneeded warehouse space. It is not accessible to the general citizenry, but your personal elevator has express service to it. As you step off, two soldiers in combat armor manning the entry checkpoint tense before recognizing their Marshal and stepping aside with a sharp salute.`
		);
	}

	r.push("You make your way to the operations center. The Colonel is");
	if (random(1, 100) > 25) {
		r.push("glancing between her tablet and the large wallscreen, occasionally taking notes or barking orders.");
	} else if (random(1, 100) > 50) {
		r.push("handling a minor issue.");
	} else {
		r.push("examining a table with a map of the surrounding area, planning maneuvers in the event of an attack.");
	}
	r.push("She notices your entrance and turns her attention to you.");
	if (isBrazen) {
		r.push(`She gives a textbook salute. "${properTitle()}, how can I help you?"`);
	} else {
		r.push(`"Hey boss, what do you need?"`);
	}
	App.UI.DOM.appendNewElement("div", node, r.join(" "));

	App.UI.DOM.appendNewElement("p", node, App.UI.DOM.passageLink("Tour the firebase", "FirebaseTour"));
	if (size === max) {
		App.UI.DOM.appendNewElement("div", node, "There are no more upgrades available.");
		delete V.SF.Upgrade;
	}
	if (V.SF.FS.Tension !== -1) {
		App.UI.DOM.appendNewElement("div", node, `The Colonel's current Tension: ${V.SF.FS.Tension}`);
	}

	const tabBar = new App.UI.Tabs.TabBar("SpecialForceBase");
	if (size !== max) {
		tabBar.addTab("Upgrades", "Upgrades", upgrades());
	}
	tabBar.addTab("Actions", "Actions", actions());
	tabBar.addTab("Future Societies", "FS", App.SF.fsIntegration.menu());
	node.append(tabBar.render());
	return node;

	function upgrades() {
		const cost = forceNeg(Math.ceil(10000 + ((0.03 - (size/max)/100) * V.SF.CreditsInvested)));
		const node = document.createElement("span");
		node.append(`Total upgrade progress:`);
		$(node).wiki(App.SF.progress(size, max));
		node.append(`${size}/${max}(${(size/max).toFixed(2)*100}%)`);
		if (size < 30) {
			App.UI.DOM.appendNewElement("div", node, `${(30 - size)} more upgrades is needed until the next tier unlocks.`, "note");
		}
		if (V.SF.Upgrade > 0) {
			App.UI.DOM.appendNewElement("div", node, App.UI.DOM.combineNodes(
				App.UI.DOM.appendNewElement("span", node, `Spend ${cashFormat(cost)} `, ["cash", "dec"]),
				App.UI.DOM.link("to re-unlock upgrading.",
					() => {
						V.SF.Upgrade = 0;
						cashX(cost, "specialForcesCap");
						App.UI.reload();
					}
				))
			);
		} else if (size < 30 || size !== max) {
			App.UI.DOM.appendNewElement("div", node, App.SF.upgrades.menu());
		}
		return node;
	}

	function actions() {
		const r = [];
		const repeatTrigger = (Math.trunc(V.week/24) === (V.week/24)) && V.SF.MercCon.CanAttend === -1;
		const node = document.createElement("span");
		/**
			* @param {string} text
			* @param {number} value
			*/
		const choiceLink = (text, value) => App.UI.DOM.link(text, () => { V.SF.MercCon.CanAttend = value; App.UI.reload(); });
		/**
			* @param {string} text
			* @param {string} target
			* @param {number} value
			*/
		const assignTroopsLink = (text, target, value) => App.UI.DOM.link(text, () => { V.SF.UC[target] = value; App.UI.reload(); });

		if (V.SF.MercCon.CanAttend === 0 || V.SF.MercCon.History >= 1 && repeatTrigger) {
			r.push(`Her expression changes as something jogs her memory. "Before we begin, ${isBrazen ? `${properTitle()}` : 'boss'},`);
			if (V.SF.MercCon.CanAttend === 0) {
				r.push(`back when I was a merc me and a couple of my old friends would have a meetup every several months. Drinking, fucking, drugs... a little poker. It eventually grew into a whole thing, and now we bring our latest and greatest toys to show off, maybe make some money off selling the schematics. I'd like to continue going, for old times' sake."`);
			} else if (V.SF.MercCon.History >= 1 && repeatTrigger) {
				r.push(`that biannual merc meetup has come around again. You've already given me leave to attend, but I just wanted to be sure I'm still clear to go."`);
			}
			App.UI.DOM.appendNewElement("div", node, r.join(" "));
			App.UI.DOM.appendNewElement("div", node, choiceLink("Grant leave", 1));
			App.UI.DOM.appendNewElement("div", node, choiceLink("Request she remain on site", -2));
		}

		const report = document.createElement("span");
		if (V.SF.MercCon.History >= 1) {
			App.UI.DOM.appendNewElement("div", report, App.UI.DOM.link("Mercenary meetup report",
				() => {
					App.UI.DOM.replace(report,
						App.UI.DOM.combineNodes(
							`While at the recent merc meetup, The Colonel made`,
							App.UI.DOM.makeElement("span", ` ${cashFormat(Math.ceil(V.SF.MercCon.Income))}`, "yellowgreen"),
							` selling generic schematics to her friends,`,
							` ${num(V.SF.MercCon.Menials)} menial slaves were won in a poker game, and`,
							` ${num(V.SF.MercCon.Mercs)} mercenaries were persuaded to join ${V.SF.Lower}.`,
							App.UI.DOM.makeElement("div",
								App.UI.DOM.combineNodes(
									"Total earnings thus far:",
									App.UI.DOM.makeElement("span",
										` ${cashFormat(Math.ceil(V.SF.MercCon.Revenue))}`, "yellowgreen"),
									` in income, ${num(V.SF.MercCon.TotalMenials)} menial slaves and ${num(V.SF.MercCon.TotalMercs)} mercenaries joined across ${V.SF.MercCon.History} meetups.`
								)
							)
						)
					);
				}));
		}
		App.UI.DOM.appendNewElement("p", node, report);

		const ratio = function() {
			if (V.SF.UC.Assign === 0) {
				return (V.SF.UC.Lock < 1 ? "No" : "Zero of");
			} else if (V.SF.UC.Assign === 1) {
				return "A small section of";
			} else if (V.SF.UC.Assign === 2) {
				return "A large section of";
			}
		};

		if (V.SF.UC.Lock < 1) {
			if (V.SF.UC.Assign >= 0) {
				App.UI.DOM.appendNewElement("div", node, `${ratio()} soldiers are working undercover, which would primarily advance your cultural goals while also slightly boosting your reputation.`);
				App.UI.DOM.appendNewElement("div", node, assignTroopsLink("Full time assignment", "Lock", 1));
				App.UI.DOM.appendNewElement("div", node, assignTroopsLink("Reassign soldiers", "Assign", -1));
			} else {
				App.UI.DOM.appendNewElement("div", node, "Would you like to assign soldiers to undercover duty, which will primarily advance your cultural goals while also slightly boosting your reputation?");
				App.UI.DOM.appendNewElement("div", node, assignTroopsLink("Do not assign soldiers to work undercover", "Assign", 0));
				App.UI.DOM.appendNewElement("div", node, assignTroopsLink("Assign a small section of soldiers to work undercover", "Assign", 1));
				App.UI.DOM.appendNewElement("div", node, assignTroopsLink("Assign a large section of soldiers to work undercover", "Assign", 2));
			}
		} else {
			App.UI.DOM.appendNewElement("span", node,
				App.UI.DOM.combineNodes(
					App.UI.DOM.makeElement("span", `${ratio()}`, "bold"),
					" the special force is assigned to undercover work, which will primarily advance your cultural goals while also slightly boosting your reputation."
				)
			);
			App.UI.DOM.appendNewElement("span", node, assignTroopsLink(" Re-allocate the units", "Lock", 0));
		}

		return node;
	}
};

repo_name: Pecanus/fc

license: mit


code:
// T=SugarCube.State.temporary;
App.SF.Init = function() {
	if (passage() === "Alpha disclaimer" || passage() === "New Game Plus") {
		V.SF = {Active: -1, Toggle: 0};
	}
	V.SF.FS = V.SF.FS || {};
	V.SF.FS.Tension = V.SF.FS.Tension || -1;

	if (V.SF.Toggle && V.SF.Active >= 1) {
		Object.assign(V.SF, {
			UC: {Assign: 0, lock: 0},
			Depravity: 0,
			Size: 0,
			Upgrade: 0,
			CreditsInvested: 0,
			Gift: 0,
			ROE: "hold",
			Target: "recruit",
			Regs: "strict",
			Lower: "the special force",
			ArmySize: 40,
			SatLaunched: 0,
			Squad: {},
			Colonel: {
				Core: "",
				Talk: 0,
				Fun: 0,
				Status: 0
			},
			MercCon: {
				History: 0,
				CanAttend: 0,
				Income: 0,
				Revenue: 0,
				Mercs: 0,
				Menials: 0,
				TotalMenials: 0,
				TotalMercs: 0
			}
		});

		for (const upgrade of App.SF.upgrades.list('all')) {
			V.SF.Squad[upgrade] = 0;
		}

		for (const currentFS of App.SF.fsIntegration.list().all) {
			V.SF.FS[currentFS] = {lv: 0, gift: 0};
		}
	}
	// V.arcologies[0].SFRaid = 1; V.arcologies[0].SFRaidTarget = -1;
};

App.SF.env = function() {
	if (V.economy > 100) {
		return 4;
	} else if (V.economy > 67) {
		return 3;
	} else {
		return 2;
	}
};

App.SF.SFC = function() {
	return `The Colonel`;
};

App.SF.ColonelStatus = function() {
	if (V.SF.Colonel.Status <= 19) {
		return `boss`;
	} else if (V.SF.Colonel.Status <= 39) {
		return `friend`;
	} else {
		return `fuckbuddy`;
	}
};

App.SF.totalNetWorth = function() {
	let value = 0;
	if (V.SF.Toggle && V.SF.Active >= 1) {
		value += V.SF.CreditsInvested;
		value += V.SF.MercCon.Revenue;
		value -= App.SF.AAR()[1];
	}
	return value;
};


code:
// @ts-nocheck
/* no-usedOnce */
App.SF.BC = function() {
	function InitClean() {
		delete V.SFMODToggle;
		delete V.securityForceActive;
		delete V.securityForceCreate;
		delete V.securityForceEventSeen;
	}

	function MainClean() {
		delete V.securityForceActive;
		delete V.securityForceRecruit;
		delete V.securityForceTrade;
		delete V.securityForceBooty;
		delete V.securityForceIncome;
		delete V.securityForceMissionEfficiency;
		delete V.securityForceProfitable;
		delete V.TierTwoUnlock;
		delete V.securityForceDepravity;
		delete V.SFAO;
		delete V.securityForceUpgradeTokenReset;
		delete V.securityForceUpgradeToken;
		delete V.securityForceGiftToken;
		delete V.securityForceRulesOfEngagement;
		delete V.securityForceFocus;
		delete V.securityForceAccountability;
		delete V.securityForceName;
		delete V.SubsidyActive;
		delete V.securityForceSubsidyActive;
	}

	function ColonelClean() {
		delete V.ColonelCore;
		delete V.securityForceColonelToken;
		delete V.securityForceColonelSexed;
		delete V.ColonelRelationship;
		delete V.securityForceSexedColonelToken;
	}

	function TradeShowClean() {
		delete V.OverallTradeShowAttendance;
		delete V.CurrentTradeShowAttendance;
		delete V.TradeShowIncome;
		delete V.TotalTradeShowIncome;
		delete V.TradeShowHelots;
		delete V.TotalTradeShowHelots;
	}

	function UnitsClean() {
		delete V.securityForceInfantryPower;
		delete V.securityForceArcologyUpgrades;
		delete V.securityForceVehiclePower;
		delete V.securityForceDronePower;
		delete V.securityForceStimulantPower;
		delete V.securityForceHeavyBattleTank;
		delete V.securityForceAircraftPower;
		delete V.securityForceSpacePlanePower;
		delete V.securityForceAC130;
		delete V.securityForceSatellitePower;
		delete V.securityForceGiantRobot;
		delete V.securityForceMissileSilo;
		delete V.securityForceAircraftCarrier;
		delete V.securityForceSubmarine;
		delete V.securityForceHeavyAmphibiousTransport;
		delete V.securityForcePersonnel;
		delete V.securityForceFortressZeppelin;
		delete V.securityForceHeavyTransport;
	}

	if (typeof V.SF !== "object") {
		if (V.securityForceEventSeen < 1) {
			V.securityForceActive = -1;
		} else {
			V.securityForceActive = 2;
		}
		V.SF = {Toggle: V.SFMODToggle, Active: V.securityForceActive};
		InitClean();
		if (V.securityForceName === undefined) {
			V.securityForceName = "the special force";
		}
		if (V.SF.Active >= 1) {
			Object.assign(V.SF, {
				Depravity: V.securityForceDepravity,
				Upgrade: V.securityForceUpgradeToken,
				Gift: V.securityForceGiftToken,
				UC: {Assign: V.SF.SpecOps, Lock: V.SF.SpecOpsLock},
				ROE: V.securityForceRulesOfEngagement,
				Target: V.securityForceFocus,
				Regs: V.securityForceAccountability,
				Lower: V.securityForceName,
			});
			MainClean();

			if (V.ColonelCore === undefined) {
				V.ColonelCore = "";
			}
			if (V.ColonelDiscussion === undefined) {
				V.ColonelDiscussion = 0;
			}
			if (V.ColonelSexed === undefined) {
				V.ColonelSexed = 0;
			}
			V.SF.Colonel = {
				Core: V.ColonelCore,
				Talk: V.securityForceColonelToken,
				Fun: V.securityForceColonelSexed,
				Status: V.ColonelRelationship
			};
			ColonelClean();

			if (V.TradeShowIncome === undefined) {
				V.TradeShowIncome = 0;
			}
			if (V.TotalTradeShowIncome === undefined) {
				V.TotalTradeShowIncome = 0;
			}
			if (V.TradeShowHelots === undefined) {
				V.TradeShowHelots = 0;
			}
			if (V.TotalTradeShowHelots === undefined) {
				V.TotalTradeShowHelots = 0;
			}
			V.SF.MercCon = {
				History: V.OverallTradeShowAttendance,
				CanAttend: V.CurrentTradeShowAttendance,
				Income: V.TradeShowIncome,
				Revenue: V.TotalTradeShowIncome,
				Menials: V.TradeShowHelots,
				TotalMenials: V.TotalTradeShowHelots,
				Mercs: 0,
				TotalMercs: 0
			};
			TradeShowClean();
			if (V.SF.MercCon.History > 0) {
				V.SF.MercCon.CanAttend = 1;
			}

			if (V.securityForceHeavyBattleTank === undefined) {
				V.securityForceHeavyBattleTank = 0;
			}
			if (V.securityForceSpacePlanePower === undefined) {
				V.securityForceSpacePlanePower = 0;
			}
			if (V.securityForceAC130 === undefined) {
				V.securityForceAC130 = 0;
			}
			if (V.securityForceSatellitePower === undefined) {
				V.securityForceSatellitePower = 0;
			}
			if (V.securityForceGiantRobot === undefined) {
				V.securityForceGiantRobot = 0;
			}
			if (V.securityForceMissileSilo === undefined) {
				V.securityForceMissileSilo = 0;
			}
			if (V.securityForceAircraftCarrier === undefined) {
				V.securityForceAircraftCarrier = 0;
			}
			if (V.securityForceSubmarine === undefined) {
				V.securityForceSubmarine = 0;
			}
			if (V.securityForceHeavyAmphibiousTransport === undefined) {
				V.securityForceHeavyAmphibiousTransport = 0;
			}

			V.SF.ArmySize = V.securityForcePersonnel;

			V.SF.SatLaunched = 0;

			V.SF.Squad = {
				Armoury: V.securityForceInfantryPower,
				Firebase: V.securityForceArcologyUpgrades,
				AV: V.securityForceVehiclePower,
				TV: V.securityForceVehiclePower,
				Drones: V.securityForceDronePower,
				Drugs: V.securityForceStimulantPower,
				PGT: V.securityForceHeavyBattleTank,
				AA: V.securityForceAircraftPower,
				TA: V.securityForceAircraftPower,
				SpacePlane: V.securityForceSpacePlanePower,
				GunS: V.securityForceAC130,
				Satellite: V.securityForceSatellitePower,
				GiantRobot: V.securityForceGiantRobot,
				MissileSilo: V.securityForceMissileSilo,
				AircraftCarrier: V.securityForceAircraftCarrier,
				Sub: V.securityForceSubmarine,
				HAT: V.securityForceHeavyAmphibiousTransport
			};
			UnitsClean();
		} else {
			App.SF.Init();
		}
	} else if (typeof V.SF === "object") {
		V.SF.FS = V.SF.FS || {};
		V.SF.FS.Tension = V.SF.FS.Tension || -1;

		if (V.SF.Toggle && V.SF.Active >= 1) {
			for (const currentFS of App.SF.fsIntegration.list().all) {
				if (typeof V.SF.FS[currentFS] === "number") {
					V.SF.FS[currentFS] = {lv: V.SF.FS[currentFS]};
				}
				V.SF.FS[currentFS] = V.SF.FS[currentFS] || {};
				V.SF.FS[currentFS].lv = V.SF.FS[currentFS].lv || 0;
				V.SF.FS[currentFS].gift = V.SF.FS[currentFS].gift || 0;
				delete V.SF.FS[currentFS].validOption;
				delete V.SF.FS[currentFS].vaildOption;
			}

			V.SF.UC = V.SF.UC || {};
			V.SF.Depravity = V.SF.Depravity || 0;
			V.SF.Upgrade = V.SF.Upgrade || 0;
			V.SF.CreditsInvested = V.SF.CreditsInvested || 0;
			V.SF.UC.Assign = V.SF.UC.Assign || 0;
			V.SF.UC.Lock = V.SF.UC.Lock || 0;
			V.SF.ROE = V.SF.ROE || "hold";
			V.SF.Target = V.SF.Target || "recruit";
			V.SF.Regs = V.SF.Regs || "strict";
			V.SF.Lower = V.SF.Lower || "the special force";

			V.SF.ArmySize = V.SF.ArmySize || 40;

			V.SF.Squad = V.SF.Squad || {};
			for (const upgrade of App.SF.upgrades.list('all')) {
				V.SF.Squad[upgrade] = V.SF.Squad[upgrade] || 0;
			}

			V.SF.SatLaunched = V.SF.SatLaunched || 0;

			V.SF.Colonel = V.SF.Colonel || {};
			V.SF.Colonel.Core = V.SF.Colonel.Core || "";
			V.SF.Colonel.Status = V.SF.Colonel.Status || 0;

			V.SF.MercCon = V.SF.MercCon || {};
			V.SF.MercCon.History = V.SF.MercCon.History || 0;
			V.SF.MercCon.CanAttend = V.SF.MercCon.CanAttend || 0;
			if (V.SF.MercCon.History >= 1) {
				V.SF.MercCon.CanAttend = -1;
			}
			V.SF.MercCon.Income = V.SF.MercCon.Income || 0;
			V.SF.MercCon.Revenue = V.SF.MercCon.Revenue || 0;
			V.SF.MercCon.Mercs = V.SF.MercCon.Mercs || 0;
			V.SF.MercCon.Menials = V.SF.MercCon.Menials || 0;
			V.SF.MercCon.TotalMenials = V.SF.MercCon.TotalMenials || 0;
			V.SF.MercCon.TotalMercs = V.SF.MercCon.TotalMercs || 0;

			if (typeof V.SF.Squad.Satellite === "object") {
				if (V.SF.Squad.Satellite.InOrbit > 0) {
					V.SF.SatLaunched = V.SF.Squad.Satellite.InOrbit; delete V.SF.Squad.Satellite.InOrbit;
				}
				V.SF.Squad.Satellite = V.SF.Squad.Satellite.lv;
			}

			delete V.SF.FS.upgrade; delete V.SF.UC.num;
			delete V.SF.Gift;

			if (V.Tour !== undefined) {
				V.SF.tour = V.Tour || 0;
			}

			if (V.SF.Squad.Troops) {
				V.SF.ArmySize = V.SF.Squad.Troops;
				delete V.SF.Squad.Troops;
			}

			if (V.SFUnit !== undefined) {
				if (V.SFUnit.AT !== undefined) {
					V.SFUnitTA = 0;
				}
			}

			if (V.SF.Squad !== undefined && V.SF.Squad.Satellite !== undefined && V.SatLaunched !== undefined) {
				V.SF.Squad.Sat = {lv: V.SF.Squad.Satellite, InOrbit: V.SatLaunched};
				V.SF.Squad.Satellite = V.SF.Squad.Sat;
				delete V.SF.Squad.Sat;
				delete V.SatLaunched;
			}

			if (V.SFTradeShow !== undefined) {
				V.SF.MercCon = V.SFTradeShow;
			}
			delete V.SFTradeShow;

			if (V.SF.MercCon !== undefined) {
				if (V.SF.MercCon.View !== undefined) {
					delete V.SF.MercCon.View;
				}
				if (V.SF.MercCon.Helots !== undefined) {
					V.SF.MercCon.Menials = V.SF.MercCon.Helots;
					delete V.SF.MercCon.Helots;
				}
				if (V.SF.MercCon.TotalHelots !== undefined) {
					V.SF.MercCon.TotalMenials = V.SF.MercCon.TotalHelots;
					delete V.SF.MercCon.TotalHelots;
				}
			}

			if (V.SFColonel !== undefined) {
				V.SF.Colonel = V.SFColonel;
			}
			delete V.SF.Colonel.Fun; delete V.SF.Colonel.Talk;

			if (V.SF.SpecOps !== undefined && V.SF.SpecOpsLock !== undefined) {
				V.SF.UC = {Assign: V.SF.SpecOps, Lock: V.SF.SpecOpsLock};
			}

			if (V.SFUC !== undefined) {
				V.SF.UC.num = V.SFUC || 0;
			}

			if (V.SpecOpsLock !== undefined) {
				V.SF.SpecOpsLock = V.SpecOpsLock;
			}

			if (V.SF.U !== undefined) {
				V.SF.Upgrade = V.SF.U || 0;
			}

			if (V.SF.Depravity < 0) {
				V.SF.Depravity = 0;
			}
		} // closes: V.SF.Toggle && V.SF.Active >= 1
	}

	delete V.Tour; delete V.SFColonel; delete V.SFUnit;
	delete V.SF.tour; delete V.SF.Caps; delete V.SF.Size; delete V.choice;
	delete V.SF.Units; delete V.SpecOpsLock; delete V.SF.U; delete V.SF.WG;
	delete V.SF.Subsidy; delete V.SF.SpecOps; delete V.SF.SpecOpsLock; delete V.SFUC;

	if (V.SF.BadOutcome !== undefined) {
		delete V.SF.BadOutcome;
	}
	if (V.arcologies[0].SFRaid !== undefined) {
		delete V.arcologies[0].SFRaid;
	}
	if (V.arcologies[0].SFRaidTarget !== undefined) {
		delete V.arcologies[0].SFRaidTarget;
	}
	if (V.SF.Facility !== undefined) {
		delete V.SF.Facility;
	}

	if (V.SF.MWU !== undefined) {
		delete V.SF.MWU;
	}
	if (V.SF.Bonus !== undefined) {
		delete V.SF.Bonus;
	}

	InitClean();
	MainClean();
	ColonelClean();
	TradeShowClean();
	UnitsClean();

	if (V.week < 72 && V.SF.Active !== -1) { V.SF.Active = -1; }
};


code:
App.UI.editSF = function() {
	const node = new DocumentFragment();

	for (let i in V.SF.Squad) {
		const v = String([i]);
		if (V.SF.Squad[i] > App.SF.upgrades.currentUnitMax(v)) {
			V.SF.Squad[i] = App.SF.upgrades.currentUnitMax(v);
		}
	}

	const max = App.SF.upgrades.max();
	const T1 = App.SF.unlocked.secondTier();
	const size = App.SF.upgrades.total();

	let options = new App.UI.OptionsGroup();

	App.UI.DOM.appendNewElement("h2", node, `Upgrades: ${size}/${max} (${(100 * size / max).toFixed(2)}%)`);

	options.addOption(`Firebase`, "Firebase", V.SF.Squad).showTextBox()
		.addComment(`current max ${App.SF.upgrades.currentUnitMax('Firebase')}`);
	options.addOption(`Armoury`, "Armoury", V.SF.Squad).showTextBox()
		.addComment(`current max ${App.SF.upgrades.currentUnitMax('Armoury')}`);
	options.addOption(`Drugs`, "Drugs", V.SF.Squad).showTextBox()
		.addComment(`current max ${App.SF.upgrades.currentUnitMax('Drugs')}`);

	if (V.SF.Squad.Firebase >= 2) {
		options.addOption(`Drones`, "Drones", V.SF.Squad).showTextBox()
			.addComment(`current max ${App.SF.upgrades.currentUnitMax('Drones')}`);
	}

	if (App.SF.unlocked.garage()) {
		options.addCustom(App.UI.DOM.makeElement("h2", `Garage`));
		options.addOption(`Attack Vehicles`, "AV", V.SF.Squad).showTextBox()
			.addComment(`current max ${App.SF.upgrades.currentUnitMax('AV')}`);
		options.addOption(`Transport Vehicles`, "TV", V.SF.Squad).showTextBox()
			.addComment(`current max ${App.SF.upgrades.currentUnitMax('TV')}`);
		if (T1) {
			options.addOption(`Prototype Goliath Tank`, "PGT", V.SF.Squad).showTextBox()
				.addComment(`current max ${App.SF.upgrades.currentUnitMax('PGT')}`);
		}
	}

	if (App.SF.unlocked.hangar()) {
		options.addCustom(App.UI.DOM.makeElement("h2", `Hangar`));
		options.addOption(`Attack Planes`, "AA", V.SF.Squad).showTextBox()
			.addComment(`current max ${App.SF.upgrades.currentUnitMax('AA')}`);
		options.addOption(`Transport Planes`, "TA", V.SF.Squad).showTextBox()
			.addComment(`current max ${App.SF.upgrades.currentUnitMax('TA')}`);
		if (T1) {
			options.addOption(`Spaceplane`, "SpacePlane", V.SF.Squad).showTextBox()
				.addComment(`current max ${App.SF.upgrades.currentUnitMax('SpacePlane')}`);
			options.addOption(`Gunship`, "GunS", V.SF.Squad).showTextBox()
				.addComment(`current max ${App.SF.upgrades.currentUnitMax('GunS')}`);
		}
	}

	if (App.SF.unlocked.launchBay()) {
		options.addCustom(App.UI.DOM.makeElement("h2", `Launch Bay`));
		options.addOption(`Satellite`, "Satellite", V.SF.Squad).showTextBox()
			.addComment(`current max ${App.SF.upgrades.currentUnitMax('Satellite')}`);
		if (V.terrain !== "oceanic") {
			options.addOption(`Giant Robot`, "GiantRobot", V.SF.Squad).showTextBox()
				.addComment(`current max ${App.SF.upgrades.currentUnitMax('GiantRobot')}`);
				options.addOption(`Cruise Missile`, "MissileSilo", V.SF.Squad).showTextBox()
				.addComment(`current max ${App.SF.upgrades.currentUnitMax('MissileSilo')}`);
		}
	}

	if (App.SF.unlocked.navalYard()) {
		options.addCustom(App.UI.DOM.makeElement("h2", `Naval Yard`));
		options.addOption(`Aircraft Carrier`, "AircraftCarrier", V.SF.Squad).showTextBox()
			.addComment(`current max ${App.SF.upgrades.currentUnitMax('AircraftCarrier')}`);
		options.addOption(`Submarine`, "Sub", V.SF.Squad).showTextBox()
			.addComment(`current max ${App.SF.upgrades.currentUnitMax('Sub')}`);
		options.addOption(`Amphibious Transport`, "HAT", V.SF.Squad).showTextBox()
			.addComment(`current max ${App.SF.upgrades.currentUnitMax('HAT')}`);
	}

	node.append(options.render());

	if (V.SF.FS.Tension !== -1) {
		App.Events.addParagraph(node, [
			`The Colonel's current Tension:`,
			App.UI.DOM.makeTextBox(V.SF.FS.Tension, (v) => {
				V.SF.FS.Tension = v;
				App.UI.reload();
			})
		]);
	}

	return node;
};


code:
App.Events.TrickShotNight = class TrickShotNight extends App.Events.BaseEvent {
	eventPrerequisites() {
		return [
			() => V.SF.Toggle,
			() => V.SF.Active >= 1
		];
	}

	execute(node) {
		let r = [];
		const buyIn = 50000;
		const {
			HeA
		} = getPronouns(assistant.pronouns().main).appendSuffix("A");
		const shootChance = Math.max(25 + V.PC.skill.warfare * 0.2, 25 + V.PC.skill.warfare * 0.65); // Odds increase slowly up to 0 skill, then greatly after. Always some odds to succeed or fail.

		App.Events.addParagraph(node, [`Despite your direct elevator, interaction with the majority of your security force is relatively scarce. Aside from mutually exchanged nods in the firebase and the occasional briefing, your ${V.SF.Lower} enjoy a degree of autonomy.`]);

		r.push(`On a particularly lackadaisical evening, you find yourself alerted to a message alert by ${V.assistant.name}.`);
		if (V.assistant.personality > 0) {
			r.push(`"${properMaster()}, a message from ${V.SF.Lower}." ${HeA} pauses before continuing. "It seems they're asking if you'd like to join their trick shot night."`);
		} else {
			r.push(`It informs you that ${V.SF.Lower} have sent a message asking you to join them at their trick shot night.`);
		}
		App.Events.addParagraph(node, r);

		const choices = [];
		choices.push(new App.Events.Result(`Politely decline`, decline));
		if (V.cash < buyIn) {
			choices.push(new App.Events.Result(null, null, "You lack the necessary funds to attend."));
		} else {
			choices.push(new App.Events.Result(`Attend the trick shot night`, attend, `It will cost ${cashFormat(buyIn)} to participate in the trick shot night.`));
		}
		App.Events.addResponses(node, choices);

		function decline() {
			return `You inform ${V.SF.Lower} that you aren't planning to attend. A short while later, you receive a message from them stating that their invitation is an open one and that you're welcome to join in another night.`;
		}

		function attend() {
			const frag = new DocumentFragment();
			App.Events.addParagraph(frag, [`You instruct ${V.assistant.name} to inform ${V.SF.Lower} that you will be attending their trick shot night, and after settling your affairs in the penthouse you head down to the firebase. The atmosphere in the firebase is casual, especially in comparison to the usual situations you meet them, though your security force still maintain some measure of decorum towards you as their employer. Eventually, you settle in at the table with a handful of ${V.SF.Lower} officers and turn your ${cashFormat(buyIn)} into bullets. All that remains is to decide your strategy for the night.`]);

			const choices = [];
			choices.push(new App.Events.Result(`Play it safe`, safe));
			if (random(1, 100) < shootChance) {
				choices.push(new App.Events.Result(`Up the ante`, ante));
			}
			App.Events.addResponses(frag, choices);
			return frag;

			function safe() {
				if (random(1, 100) > shootChance) {
					repX(5000, "event");
					cashX(-25000, "event");
					return `Despite your attempts to mitigate risk and play the safest shots possible, it seems lady luck has conspired against you this evening. However, even when your last bullet is shot, your security force pitch you a few bullets to keep you in the game for the rest of the night. You may have lost most of your ¤, but it seems you've made some friends.`;
				} else {
					const winnings = buyIn * 2;
					repX(5000, "event");
					cashX(winnings, "event");
					return `While a careful eye for accuracy has buoyed you through the evening, ultimately lady luck is the decider in handing you the win in a number of close shots. Unfortunately your meticulous play limited your chance at a larger payout, and you only come away from the evening with ${cashFormat(winnings)} more than you arrived with and the respect of your security force.`;
				}
			}

			function ante() {
				const frag = new DocumentFragment();
				let r = [];
				const genParam = {
					minAge: 25, maxAge: 35, ageOverridesPedoMode: 1, race: "nonslave", disableDisability: 1
				};
				const soldier = GenerateNewSlave(V.seeDicks !== 100 ? "XX" : "XY", genParam);
				soldier.origin = "$He put $himself up as collateral at a trick shot game, and lost.";
				soldier.career = "a soldier";
				soldier.indentureRestrictions = 2;
				soldier.indenture = 52;
				soldier.devotion = random(45, 60);
				soldier.trust = random(55, 65);
				setHealth(soldier, jsRandom(60, 80), 0, undefined, 0, jsRandom(10, 30));
				soldier.muscles = 60;
				if (soldier.weight > 130) {
					soldier.weight -= 100;
					soldier.waist = random(-10, 50);
				}
				soldier.anus = 0;
				soldier.skill.anal = 0;
				soldier.skill.whoring = 0;
				soldier.skill.combat = 1;
				soldier.accent = random(0, 1);
				soldier.behavioralFlaw = "arrogant";
				soldier.hLength = 1;
				soldier.hStyle = "buzzcut";
				soldier.clothes = "a military uniform";
				App.Events.drawEventArt(frag, soldier);

				const {
					He,
					he, his
				} = getPronouns(soldier);

				r.push(`Some aggressive play and an eye for riling up your fellow players has resulted in an immense payout, and all but one of your adversaries have folded as the situation has escalated. The only player still in contention is a wily old mercenary, the veteran of ${his} fair share of battles on the battlefield and at the firing range. ${He}'s short on bullets, however, and ${he}'ll have to buy in with something else as collateral.`);
				App.Events.addParagraph(frag, r);

				App.Events.addResponses(frag, [
					new App.Events.Result(`A year of servitude`, serve),
					new App.Events.Result(`Dock ${his} wages`, wages)
				]);
				return frag;

				function serve() {
					const frag = new DocumentFragment();
					let r = [];
					if (random(1, 100) > shootChance) {
						r.push(`For all your skillful maneuvering to reach this position, ultimately the win comes down to chance. This time, however, luck was not on your side. As the victor sweeps up ${his} spoils, the other security force clap you on the back and offer their condolences for your defeat. Though you may have lost your ¤, it seems you've made some friends.`);
						repX(5000, "event");
						cashX(-buyIn, "event");
					} else {
						soldier.clothes = "no clothing";
						App.Events.refreshEventArt(soldier);
						r.push(`For all your skillful maneuvering to reach this position, ultimately the win comes down to chance. This time, however, luck has rendered you the victor. A silence falls over the room as the result is declared, but after some time your opponent breaks the hush by joking that life as your slave is probably easier than fighting for ${V.arcologies[0].name}. After some awkward laughter the night continues, and at the end your former mercenary joins you on your trip back to the penthouse to submit to processing and to begin ${his} new life as your sexual servant. ${He}'s not young, but ${he}'s tough and not distrusting of you due to ${his} service in ${V.SF.Lower}.`);
						r.push(App.UI.newSlaveIntro(soldier));
					}
					IncreasePCSkills('warfare', 1);
					App.Events.addParagraph(frag, r);
					return frag;
				}

				function wages() {
					IncreasePCSkills('warfare', 1);
					if (random(1, 100) > shootChance) {
						repX(5000, "event");
						cashX(-buyIn, "event");
						return `For all your skillful maneuvering to reach this position, ultimately the win comes down to chance. This time, however, luck was not on your side. As the victor sweeps up ${his} spoils, the other security force members clap you on the back and offer their condolences for your defeat. Though you may have lost your ¤, it seems you've made some friends.`;
					} else {
						repX(10000, "event");
						cashX(buyIn, "event");
						return `For all your skillful maneuvering to reach this position, ultimately the win comes down to chance. This time, however, luck has rendered you the victor. Your opponent accepts ${his} defeat with grace and jokes to ${his} comrades that ${he}'ll be fighting in ${his} underwear for the next few months, and their uproar of laughter fills the room. Though you take the lion's share of the ¤, your security force also had a good time fraternizing with you.`;
					}
				}
			}
		}
	}
};


code:
App.SF.unlocked = (function() {
	return {
		secondTier,
		garage,
		hangar,
		launchBay,
		navalYard
	};

	function secondTier() {
		return V.SF.Squad.Firebase + V.SF.Squad.Armoury + V.SF.Squad.Drugs + V.SF.Squad.Drones +
			(V.terrain !== "oceanic" ? V.SF.Squad.AV + V.SF.Squad.TV : 0) + V.SF.Squad.AA + V.SF.Squad.TA >= 30;
	}

	function garage() {
		return V.SF.Squad.Firebase >= 1 && V.terrain !== "oceanic";
	}

	function hangar() {
		return V.SF.Squad.Firebase >= 4;
	}

	function launchBay() {
		return secondTier();
	}

	function navalYard() {
		return secondTier() && (V.terrain === "oceanic" || V.terrain === "marine");
	}
})();

App.SF.upgrades = (function() {
	return {
		total,
		list,
		max,
		currentUnitMax,
		menu
	};

	function total() {
		return V.SF.Toggle === 1 && V.SF.Active >= 1 ? Object.values(V.SF.Squad).reduce((a, b) => a + b) : 0;
	}

	function list(completeView = '') {
		let array = ['Armoury', 'Firebase', 'Drugs'];
		const T1 = App.SF.unlocked.secondTier();

		if (V.SF.Squad.Firebase >= 2 || completeView === 'all') {
			array.push('Drones');
		}

		if (V.terrain !== "oceanic" && (V.SF.Squad.Firebase >= 1 || completeView === 'all')) { // Garage
			array.push('AV', 'TV');
			if (completeView === 'all' || T1) {
				array.push('PGT');
			}
		}

		if (V.SF.Squad.Firebase >= 4 || completeView === 'all') { // Hangar
			array.push('AA', 'TA');
			if (completeView === 'all' || T1) {
				array.push('SpacePlane', 'GunS');
			}
		}

		if (completeView === 'all' || T1) { // Launch Bay
			array.push('Satellite');
			if (V.terrain !== "oceanic" && V.terrain !== "marine") {
				array.push('GiantRobot', 'MissileSilo');
			} else if (V.terrain === "oceanic" || V.terrain === "marine") { // Naval Yard
				array.push('AircraftCarrier', 'Sub', 'HAT');
			}
		}

		return array;
	}

	function max() {
		return list('all').length * 10;
	}

	function currentUnitMax(input) {
		const T1 = App.SF.unlocked.secondTier();

		if (!T1) {
			if (['Armoury', 'Firebase', 'Drugs', 'Drones', 'AV', 'TV', 'AA', 'TA'].includes(input)) {
				return 5;
			} else {
				return 0;
			}
		} else {
			if (!['SpacePlane', 'GunS', 'Satellite', 'GiantRobot', 'MissileSilo', 'AircraftCarrier', 'Sub', 'HAT'].includes(input)) {
				return 10;
			} else {
				if (V.PC.skill.warfare >= 75) {
					return 10;
				} else if (V.PC.skill.warfare >= 50) {
					return 9;
				} else {
					return 8;
				}
			}
		}
	}

	function menu() {
		const fullyUpgraded = [];
		const node = document.createElement("span");
		App.UI.DOM.appendNewElement("p", node, "Which facility or equipment do you wish to upgrade this week?");

		App.UI.DOM.appendNewElement("div", node, checkUnit("Firebase"));
		App.UI.DOM.appendNewElement("div", node, checkUnit("Armoury"));
		App.UI.DOM.appendNewElement("div", node, checkUnit("Drugs"));
		if (V.SF.Squad.Firebase >= 2) {
			App.UI.DOM.appendNewElement("div", node, checkUnit("Drones"));
		}

		if (App.SF.unlocked.garage()) {
			App.UI.DOM.appendNewElement("div", node, "Garage", "bold");
			App.UI.DOM.appendNewElement("div", node, checkUnit("AV"));
			App.UI.DOM.appendNewElement("div", node, checkUnit("TV"));
			App.UI.DOM.appendNewElement("div", node, checkUnit("PGT"));
		}
		if (App.SF.unlocked.hangar()) {
			App.UI.DOM.appendNewElement("div", node, "Hangar", "bold");
			App.UI.DOM.appendNewElement("div", node, checkUnit("AA"));
			App.UI.DOM.appendNewElement("div", node, checkUnit("TA"));
			App.UI.DOM.appendNewElement("div", node, checkUnit("SpacePlane"));
			App.UI.DOM.appendNewElement("div", node, checkUnit("GunS"));
		}
		if (App.SF.unlocked.launchBay()) {
			App.UI.DOM.appendNewElement("div", node, "Launch Bay", "bold");
			App.UI.DOM.appendNewElement("div", node, checkUnit("Satellite"));
			if (V.terrain !== "oceanic") {
				App.UI.DOM.appendNewElement("div", node, checkUnit("GiantRobot"));
				App.UI.DOM.appendNewElement("div", node, checkUnit("MissileSilo"));
			}
		}
		if (App.SF.unlocked.navalYard()) {
			App.UI.DOM.appendNewElement("div", node, "Naval Yard", "bold");
			App.UI.DOM.appendNewElement("div", node, checkUnit("AircraftCarrier"));
			App.UI.DOM.appendNewElement("div", node, checkUnit("Sub"));
			App.UI.DOM.appendNewElement("div", node, checkUnit("HAT"));
		}

		if (fullyUpgraded.length > 0) {
			App.UI.DOM.appendNewElement("div", node, `The following units are fully upgraded: ${toSentence(fullyUpgraded)}.`, "note");
		}
		return node;

		/**
		 * @param {string} unit
		 * @returns {DocumentFragment}
		 */
		function checkUnit(unit) {
			const node = new DocumentFragment();
			const max = App.SF.upgrades.currentUnitMax(unit);
			let cost;
			let text = unit;
			switch (unit) {
				case "Firebase":
					cost = 125000;
					break;
				case "Armoury":
					cost = 40000;
					break;
				case "Drugs":
					cost = 40000;
					text = "Drug Lab";
					break;
				case "Drones":
					cost = 45000;
					text = "Drone Bay";
					break;
				case "AV":
					cost = 60000;
					text = "Attack Vehicle Fleet";
					break;
				case "TV":
					cost = 60000;
					text = "Transport Vehicle Fleet";
					break;
				case "PGT":
					cost = 60000;
					text = "Prototype Goliath Tank";
					break;
				case "AA":
					cost = 70000;
					text = "Attack Aircraft Fleet";
					break;
				case "TA":
					cost = 70000;
					text = "Transport Aircraft Fleet";
					break;
				case "SpacePlane":
					cost = 250000;
					text = "Spaceplane";
					break;
				case "GunS":
					cost = 350000;
					text = "Gunship";
					break;
				case "Satellite":
					cost = 525000;
					break;
				case "GiantRobot":
					cost = 550000;
					text = 'Giant Robot';
					break;
				case "MissileSilo":
					cost = 565000;
					text = 'Cruise Missile';
					break;
				case "AircraftCarrier":
					cost = 650000;
					text = 'Aircraft Carrier';
					break;
				case "Sub":
					cost = 700000;
					text = 'Submarine';
					break;
				case "HAT":
					cost = 665000;
					text = 'Amphibious Transport';
					break;
			}

			if (V.SF.Squad[unit] < max) {
				const price = getPrice(cost);
				const multiplier = [1, 2, 3, 4, 5];
				if (V.cash >= price) {
					node.append(`Upgrade ${text}, one level costs`);
					App.UI.DOM.appendNewElement("span", node, ` ${cashFormat(cost)}. `, ["cash", "dec"]);
					for (const number of multiplier) {
						if (V.cash >= price * number) {
							App.UI.DOM.appendNewElement("span", node, App.UI.DOM.link(` ,x${number}`, () => {
								V.SF.Upgrade = 1;
								V.SF.Squad[unit] += number;
								V.SF.CreditsInvested += price * number;
								cashX(forceNeg(price * number), "specialForcesCap");
								App.UI.reload();
							}));
						}
					}
				} else {
					App.UI.DOM.appendNewElement("span", node, `Cannot afford to upgrade the ${text}.`, "note");
				}
				$(node).wiki(App.SF.progress(V.SF.Squad[unit]));
			} else if (["PGT", "SpacePlane", "GunS", "Satellite", "GiantRobot", "MissileSilo", "AircraftCarrier", "Sub", "HAT"].includes(unit) && V.SF.Squad[unit] === max && V.PC.skill.warfare < 75) {
				App.UI.DOM.appendNewElement("span", node, "Your warfare skill is not high enough unlock the next upgrade.", "note");
				$(node).wiki(App.SF.progress(V.SF.Squad[unit]));
			} else if (V.SF.Squad[unit] === max && max > 0) {
				fullyUpgraded.push(text);
			}
			return node;
			/**
			 * @param {number} cost
			 * @returns {number}
	*/
			function getPrice(cost) {
				const upgradeDiv = 1.65;
				const S = V.SF.Squad;
				let value = (cost / upgradeDiv) * App.SF.env() * Math.pow(1.15, V.SF.Squad[unit] + 1);
				if ([S.AircraftCarrier, S.Drones, S.GiantRobot, S.GunS, S.MissileSilo, S.Satellite, S.SpacePlane, S.Sub].includes(unit)) {
					value *= V.HackingSkillMultiplier;
				}
				return Math.ceil(value);
			}
		}
	}
})();
/**
 * @param {number} x
 * @param {number} [max]
 * @returns {string}
 */
App.SF.progress = function(x, max) {
	let out = `⏐`;
	let z;
	let i;
	if (max === undefined) {
		x = Math.clamp(x, 0, 10);
		if (App.SF.unlocked.secondTier() === false) {
			z = 5 - x;
			for (i = 0; i < x; i++) {
				out += `█⏐`;
			}
			for (i = 0; i < z; i++) {
				out += `<span style='opacity: 0;'>█</span>⏐`;
			}
			for (i = 0; i < 5; i++) {
				out += `░⏐`;
			}
		} else {
			z = 10 - x;
			for (i = 0; i < x; i++) {
				out += `█⏐`;
			}
			for (i = 0; i < z; i++) {
				out += `<span style='opacity: 0;'>█</span>⏐`;
			}
		}
	} else {
		x = Math.clamp(x, 0, max);
		x = Math.floor(10 * x / max);
		z = 10 - x;
		for (i = 0; i < x; i++) {
			out += `█⏐`;
		}
		for (i = 0; i < z; i++) {
			out += `<span style='opacity: 0;'>█</span>⏐`;
		}
	}
	return ` ${out} `;
};