code:
App.Mods.SecExp.BC = (function() {
	return {
		propHub,
		riotCenter,
		barracks,
		weaponsManufacturing,
		transportHub,
		secHub
	};

	function propHub() {
		if (V.SecExp.buildings.pr === null) {
			delete V.SecExp.buildings.pr;
		}
		if (V.SecExp.buildings.pr) {
			V.SecExp.buildings.propHub = V.SecExp.buildings.pr;
			delete V.SecExp.buildings.pr;
		}

		if (V.SecExp.buildings.propHub) {
			delete V.SecExp.buildings.propHub.active;
		}
		if (V.SecExp.buildings.propHub && Object.entries(V.SecExp.buildings.propHub).length === 0) {
			delete V.SecExp.buildings.propHub;
		} else if (V.propHub || (V.SecExp.buildings.propHub && Object.entries(V.SecExp.buildings.propHub).length > 0)) {
			V.SecExp.buildings.propHub = V.SecExp.buildings.propHub || {};
			V.SecExp.buildings.propHub.upgrades = V.SecExp.buildings.propHub.upgrades || {};
			V.SecExp.buildings.propHub.recruiterOffice = V.SecExp.buildings.propHub.recruiterOffice || V.SecExp.buildings.propHub.recuriterOffice || V.recuriterOffice || V.RecuriterOffice || 0;
			delete V.SecExp.buildings.propHub.recuriterOffice;

			V.SecExp.buildings.propHub.upgrades.campaign = V.SecExp.buildings.propHub.upgrades.campaign || V.SecExp.buildings.propHub.campaign || V.propCampaign || 0;
			delete V.SecExp.buildings.propHub.campaign;
			V.SecExp.buildings.propHub.upgrades.miniTruth = V.SecExp.buildings.propHub.upgrades.miniTruth || V.SecExp.buildings.propHub.miniTruth || V.miniTruth || 0;
			delete V.SecExp.buildings.propHub.miniTruth;

			V.SecExp.buildings.propHub.upgrades.secretService = V.SecExp.buildings.propHub.upgrades.secretService || V.SecExp.buildings.propHub.secretService || V.SecExp.buildings.propHub.SS || V.secretService || 0;
			delete V.SecExp.buildings.propHub.secretService;
			delete V.SecExp.buildings.propHub.SS;

			V.SecExp.buildings.propHub.focus = V.SecExp.buildings.propHub.focus || "social engineering";
			if (V.propFocus && V.propFocus !== "none") {
				V.SecExp.buildings.propHub.focus = V.propFocus;
			}

			V.SecExp.buildings.propHub.upgrades.fakeNews = V.SecExp.buildings.propHub.upgrades.fakeNews || V.SecExp.buildings.propHub.fakeNews || V.fakeNews || 0;
			delete V.SecExp.buildings.propHub.fakeNews;

			V.SecExp.buildings.propHub.upgrades.controlLeaks = V.SecExp.buildings.propHub.upgrades.controlLeaks || V.SecExp.buildings.propHub.controlLeaks || V.controlLeaks || 0;
			delete V.SecExp.buildings.propHub.controlLeaks;

			V.SecExp.buildings.propHub.upgrades.marketInfiltration = V.SecExp.buildings.propHub.upgrades.marketInfiltration || V.SecExp.buildings.propHub.marketInfiltration || V.marketInfiltration || 0;
			delete V.SecExp.buildings.propHub.marketInfiltration;

			V.SecExp.buildings.propHub.upgrades.blackOps = V.SecExp.buildings.propHub.upgrades.blackOps || V.SecExp.buildings.propHub.blackOps || V.blackOps || 0;
			delete V.SecExp.buildings.propHub.blackOps;
		}
	}

	function riotCenter() {
		if (V.riotCenter || (V.SecExp.buildings.riotCenter && Object.entries(V.SecExp.buildings.riotCenter).length > 0)) {
			V.SecExp.buildings.riotCenter = V.SecExp.buildings.riotCenter || {};
			V.SecExp.buildings.riotCenter.upgrades = V.SecExp.buildings.riotCenter.upgrades || V.riotUpgrades || {};
			V.SecExp.buildings.riotCenter.fort = V.SecExp.buildings.riotCenter.fort || V.fort || {};

			V.SecExp.buildings.riotCenter.upgrades.freeMedia = V.SecExp.buildings.riotCenter.upgrades.freeMedia || 0;
			V.SecExp.buildings.riotCenter.upgrades.rapidUnit = V.SecExp.buildings.riotCenter.upgrades.rapidUnit || 0;
			V.SecExp.buildings.riotCenter.upgrades.rapidUnitSpeed = V.SecExp.buildings.riotCenter.upgrades.rapidUnitSpeed || 0;

			V.SecExp.buildings.riotCenter.fort.reactor = V.SecExp.buildings.riotCenter.fort.reactor || 0;
			V.SecExp.buildings.riotCenter.fort.waterway = V.SecExp.buildings.riotCenter.fort.waterway || 0;
			V.SecExp.buildings.riotCenter.fort.assistant = V.SecExp.buildings.riotCenter.fort.assistant || 0;

			V.SecExp.buildings.riotCenter.sentUnitCooldown = V.SecExp.buildings.riotCenter.sentUnitCooldown || V.sentUnitCooldown || 0;
			V.SecExp.buildings.riotCenter.advancedRiotEquip = V.SecExp.buildings.riotCenter.advancedRiotEquip || V.advancedRiotEquip || 0;
			V.SecExp.buildings.riotCenter.brainImplant = V.SecExp.buildings.riotCenter.brainImplant || -1;
			if (jsDef(V.brainImplant)) {
				V.SecExp.buildings.riotCenter.brainImplant = V.brainImplant;
			}
			V.SecExp.buildings.riotCenter.brainImplantProject = V.SecExp.buildings.riotCenter.brainImplantProject || V.brainImplantProject || 0;
		}
	}

	function barracks() {
		if (V.SecExp.buildings.barracks) {
			delete V.SecExp.buildings.barracks.active;
		}
		if (V.SecExp.buildings.barracks && Object.entries(V.SecExp.buildings.barracks).length === 0) {
			delete V.SecExp.buildings.barracks;
		} else if (V.secBarracks || (V.SecExp.buildings.barracks && Object.entries(V.SecExp.buildings.barracks).length > 0)) {
			V.SecExp.buildings.barracks = V.SecExp.buildings.barracks || V.secBarracksUpgrades || {};
			V.SecExp.buildings.barracks.size = V.SecExp.buildings.barracks.size || 0;
			V.SecExp.buildings.barracks.luxury = V.SecExp.buildings.barracks.luxury || 0;
			V.SecExp.buildings.barracks.training = V.SecExp.buildings.barracks.training || 0;
			V.SecExp.buildings.barracks.loyaltyMod = V.SecExp.buildings.barracks.loyaltyMod || 0;
			if (V.SecExp.buildings.barracks.upgrades) {
				V.SecExp.buildings.barracks.size = V.SecExp.buildings.barracks.upgrades.size;
				V.SecExp.buildings.barracks.luxury = V.SecExp.buildings.barracks.upgrades.luxury;
				V.SecExp.buildings.barracks.training = V.SecExp.buildings.barracks.upgrades.training;
				V.SecExp.buildings.barracks.loyaltyMod = V.SecExp.buildings.barracks.upgrades.loyaltyMod;
				delete V.SecExp.buildings.barracks.upgrades;
			}
		}
	}

	function weaponsManufacturing() {
		if (V.weapManu || (V.SecExp.buildings.weapManu && Object.entries(V.SecExp.buildings.weapManu).length > 0)) {
			V.SecExp.buildings.weapManu = V.SecExp.buildings.weapManu || {};
			V.SecExp.buildings.weapManu.space = V.SecExp.buildings.weapManu.space || 500;
			V.SecExp.buildings.weapManu.menials = V.SecExp.buildings.weapManu.menials || V.weapMenials || V.weapHelots || 0;
			V.SecExp.buildings.weapManu.productivity = V.SecExp.buildings.weapManu.productivity || V.weapProductivity || 1;
			V.SecExp.buildings.weapManu.lab = V.SecExp.buildings.weapManu.lab || V.weapLab || 1;
			V.SecExp.buildings.weapManu.sellTo = V.SecExp.buildings.weapManu.sellTo || V.sellTo || {};
			if (!jsDef(V.SecExp.buildings.weapManu.sellTo.citizen)) {
				V.SecExp.buildings.weapManu.sellTo.citizen = 1;
			}
			if (!jsDef(V.SecExp.buildings.weapManu.sellTo.raiders)) {
				V.SecExp.buildings.weapManu.sellTo.raiders = 1;
			}
			if (!jsDef(V.SecExp.buildings.weapManu.sellTo.oldWorld)) {
				V.SecExp.buildings.weapManu.sellTo.oldWorld = 1;
			}
			if (!jsDef(V.SecExp.buildings.weapManu.sellTo.FC)) {
				V.SecExp.buildings.weapManu.sellTo.FC = 1;
			}

			V.SecExp.buildings.weapManu.upgrades = V.SecExp.buildings.weapManu.upgrades || {};
			V.SecExp.buildings.weapManu.upgrades.completed = V.SecExp.buildings.weapManu.upgrades.completed || V.completedUpgrades || [];
			if (!App.Mods.SecExp.weapManu.completed()) {
				V.SecExp.buildings.weapManu.upgrades.queue = V.SecExp.buildings.weapManu.upgrades.queue || [];
				if (jsDef(V.currentUpgrade)) {
					if (!jsDef(V.currentUpgrade.ID)) {
						if (V.currentUpgrade.name === "magnetic based ballistic weaponry") {
							V.currentUpgrade.ID = 0;
						} else if (V.currentUpgrade.name === "ceramo-metallic alloys") {
							V.currentUpgrade.ID = 1;
						} else if (V.currentUpgrade.name === "rapid action stimulants") {
							V.currentUpgrade.ID = 2;
						} else if (V.currentUpgrade.name === "fast response neural stimulant") {
							V.currentUpgrade.ID = 3;
						} else if (V.currentUpgrade.name === "universal cyber enhancements") {
							V.currentUpgrade.ID = 4;
						} else if (V.currentUpgrade.name === "remote neural links") {
							V.currentUpgrade.ID = 5;
						} else if (V.currentUpgrade.name === "combined training regimens with the special force") {
							V.currentUpgrade.ID = 6;
						} else if (V.currentUpgrade.name === "a variant of the stimulant cocktail that the special force created") {
							V.currentUpgrade.ID = 7;
						} else if (V.currentUpgrade.name === "a mesh network based off the custom network of the special force") {
							V.currentUpgrade.ID = 8;
						} else if (V.currentUpgrade.name === "dynamic battle aware AI") {
							V.currentUpgrade.ID = -1;
						} else if (V.currentUpgrade.name === "adaptive armored frames") {
							V.currentUpgrade.ID = -2;
						} else if (V.currentUpgrade.name === "advanced synthetic alloys") {
							V.currentUpgrade.ID = -3;
						}
					}
					V.SecExp.buildings.weapManu.upgrades.queue.push({ID: V.currentUpgrade.ID, time: V.currentUpgrade.time});
				}

				if (jsDef(V.SecExp.buildings.weapManu.upgrades.current)) {
					if (V.SecExp.buildings.weapManu.upgrades.current.time > 0) {
						V.SecExp.buildings.weapManu.upgrades.queue.push(V.SecExp.buildings.weapManu.upgrades.current);
					}
					delete V.SecExp.buildings.weapManu.upgrades.current;
				}
			} else {
				delete V.SecExp.buildings.weapManu.upgrades.queue;
			}
		}
	}

	function transportHub() {
		if (V.transportHub || (V.SecExp.buildings.transportHub && Object.entries(V.SecExp.buildings.transportHub).length > 0)) {
			V.SecExp.buildings.transportHub = V.SecExp.buildings.transportHub || {};
			V.SecExp.buildings.transportHub.airport = V.SecExp.buildings.transportHub.airport || V.airport || 1;
			V.SecExp.buildings.transportHub.security = V.SecExp.buildings.transportHub.security || V.hubSecurity || 1;
			V.SecExp.buildings.transportHub.surfaceTransport = V.SecExp.buildings.transportHub.surfaceTransport || 1;
			if (V.releaseID < 1093) {
				if (V.terrain !== "oceanic" && V.terrain !== "marine") {
					V.SecExp.buildings.transportHub.surfaceTransport = V.railway || 1;
				} else {
					V.SecExp.buildings.transportHub.surfaceTransport = V.docks || 1;
				}
			}
		}
	}

	function secHub() {
		if (V.secHQ || (V.SecExp.buildings.secHub && Object.entries(V.SecExp.buildings.secHub).length > 0)) {
			V.SecExp.buildings.secHub = V.SecExp.buildings.secHub || {};
			V.SecExp.buildings.secHub.menials = V.SecExp.buildings.secHub.menials || V.secMenials || V.secHelots || 0;
			V.SecExp.buildings.secHub.coldstorage = V.SecExp.buildings.secHub.coldstorage || 0;

			V.SecExp.buildings.secHub.upgrades = V.SecExp.buildings.secHub.upgrades || {};
			V.SecExp.buildings.secHub.upgrades.security = V.SecExp.buildings.secHub.upgrades.security || {};
			if (V.secUpgrades) {
				V.SecExp.buildings.secHub.coldstorage = V.secUpgrades.coldstorage;
				V.SecExp.buildings.secHub.upgrades.security = {
					nanoCams: V.secUpgrades.nanoCams,
					cyberBots: V.secUpgrades.cyberBots,
					eyeScan: V.secUpgrades.eyeScan,
					cryptoAnalyzer: V.secUpgrades.cryptoAnalyzer,
				};
			}
			V.SecExp.buildings.secHub.upgrades.crime = V.SecExp.buildings.secHub.upgrades.crime || V.crimeUpgrades || {};
			V.SecExp.buildings.secHub.upgrades.intel = V.SecExp.buildings.secHub.upgrades.intel || V.intelUpgrades || {};
			V.SecExp.buildings.secHub.upgrades.readiness = V.SecExp.buildings.secHub.upgrades.readiness || V.readinessUpgrades || {};

			V.SecExp.buildings.secHub.upgrades.security.nanoCams = V.SecExp.buildings.secHub.upgrades.security.nanoCams || 0;
			V.SecExp.buildings.secHub.upgrades.security.cyberBots = V.SecExp.buildings.secHub.upgrades.security.cyberBots || 0;
			V.SecExp.buildings.secHub.upgrades.security.eyeScan = V.SecExp.buildings.secHub.upgrades.security.eyeScan || 0;
			V.SecExp.buildings.secHub.upgrades.security.cryptoAnalyzer = V.SecExp.buildings.secHub.upgrades.security.cryptoAnalyzer || 0;

			V.SecExp.buildings.secHub.upgrades.crime.autoTrial = V.SecExp.buildings.secHub.upgrades.crime.autoTrial || 0;
			V.SecExp.buildings.secHub.upgrades.crime.autoArchive = V.SecExp.buildings.secHub.upgrades.crime.autoArchive || 0;
			V.SecExp.buildings.secHub.upgrades.crime.worldProfiler = V.SecExp.buildings.secHub.upgrades.crime.worldProfiler || 0;
			V.SecExp.buildings.secHub.upgrades.crime.advForensic = V.SecExp.buildings.secHub.upgrades.crime.advForensic || 0;

			V.SecExp.buildings.secHub.upgrades.intel.sensors = V.SecExp.buildings.secHub.upgrades.intel.sensors || 0;
			V.SecExp.buildings.secHub.upgrades.intel.radar = V.SecExp.buildings.secHub.upgrades.intel.radar || 0;
			V.SecExp.buildings.secHub.upgrades.intel.signalIntercept = V.SecExp.buildings.secHub.upgrades.intel.signalIntercept || 0;

			V.SecExp.buildings.secHub.upgrades.readiness.earlyWarn = V.SecExp.buildings.secHub.upgrades.readiness.earlyWarn || 0;
			V.SecExp.buildings.secHub.upgrades.readiness.rapidPlatforms = V.SecExp.buildings.secHub.upgrades.readiness.rapidPlatforms || 0;
			V.SecExp.buildings.secHub.upgrades.readiness.pathways = V.SecExp.buildings.secHub.upgrades.readiness.pathways || 0;
			V.SecExp.buildings.secHub.upgrades.readiness.rapidVehicles = V.SecExp.buildings.secHub.upgrades.readiness.rapidVehicles || 0;
		}
	}
})();


code:
App.Mods.SecExp.propHub = (function() {
	return {
		init,
		GUI
	};

	function init() {
		V.SecExp.buildings.propHub = {
			recruiterOffice: 0,
			upgrades: {
				campaign: 0,
				miniTruth: 0,
				fakeNews: 0,
				controlLeaks: 0,
				secretService: 0,
				blackOps: 0,
				marketInfiltration: 0,
			},
			focus: "social engineering",
		};
	}

	function GUI() {
		const node = new DocumentFragment();
		V.nextButton = "Back";
		V.nextLink = "Main";
		let r = [];

		node.append("The propaganda hub is a surprisingly inconspicuous building, dimly lit from the outside. You are well aware however of its role and its importance. You confidently enter its unassuming doorway and calmly review the work being done here.");
		if (V.RecruiterID !== 0) {
			App.Events.addParagraph(node, []);
			const hasOffice = V.SecExp.buildings.propHub.recruiterOffice === 1;
			node.append(App.UI.DOM.link(
				`${hasOffice ? "Revoke" : "Grant"} ${SlaveFullName(S.Recruiter)} office privileges.`,
				() => {
					V.SecExp.buildings.propHub.recruiterOffice = (hasOffice ? 0 : 1);
					App.UI.reload();
				}
			));
			App.UI.DOM.appendNewElement("div", node, "Providing them with an office will help boost your chosen campaign. This also stacks with the campaign boost edict.", "note");
		}
		App.Events.addParagraph(node, []);

		if (V.SecExp.buildings.propHub.upgrades.campaign === 0) {
			node.append(makeLink(
				"Set up a propaganda campaign to align your citizens with your goals",
				5000,
				"Will provide the focused resource each week, but will cost reputation in upkeep.",
				"campaign"
			));
		} else {
			const focusOptions = ["social engineering", "immigration", "enslavement"];
			App.UI.DOM.appendNewElement("div", node, "You have set up a team of trained slaves and expert propagandists, ready to spread the message of your choosing to the population.");
			if (V.SecExp.edicts.defense.militia >= 1) {
				focusOptions.push("recruitment");
			}

			for (const focus of focusOptions) {
				if (V.SecExp.buildings.propHub.focus === focus) {
					r.push(focus);
				} else {
					r.push(App.UI.DOM.link(
						`${focus}`,
						() => {
							V.SecExp.buildings.propHub.focus = focus;
							App.UI.reload();
						}
					));
				}
			}
			node.append("Focus on: ", App.UI.DOM.generateLinksStrip(r));

			r = ["You are concentrating your propaganda efforts towards"];
			switch(V.SecExp.buildings.propHub.focus) {
				case "social engineering":
					r.push("increasing the acceptance of your chosen future societies.");
					break;
				case "immigration":
					r.push("convincing more people to immigrate to your arcology.");
					break;
				case "enslavement":
					r.push("convincing more people to voluntarily enslave themselves.");
					break;
				case "recruitment":
					r.push("convincing more citizens to enter the militia.");
					break;
			}
			App.UI.DOM.appendNewElement("div", node, r.join(" "));

			if (V.SecExp.buildings.propHub.upgrades.campaign < 5) {
				App.UI.DOM.appendNewElement("div", node, makeLink(
					"Invest more resources into the project to increase its effectiveness",
					5000,
					"Will provide more of the focused resource each week but increase reputation upkeep.",
					"campaign",
					true
				));
			} else {
				App.UI.DOM.appendNewElement("div", node, "You upgraded your propaganda machine to its limits.");
			}
		}
		App.Events.addParagraph(node, []);

		if (V.SecExp.buildings.propHub.upgrades.miniTruth === 0) {
			node.append(makeLink(
				"Set up the authenticity department",
				5000,
				"Will provide authority and unlock special upgrades, but will increase upkeep.",
				"miniTruth",
				false,
				"Set up a department tasked with guaranteeing the authenticity of all information available in the arcology. Of course if reality is against what is best for the arcology, then it should be redacted as well"
			));
		} else {
			if (V.SecExp.buildings.propHub.upgrades.miniTruth < 5) {
				node.append(makeLink(
					"Enlarge the authenticity department",
					5000,
					"Will provide more authority each week, but increases upkeep.",
					"miniTruth",
					false,
					"Invest more resources into the project to increase its effectiveness.",
				));
			} else {
				node.append("You have upgraded the authenticity department to its maximum.");
			}

			if (V.SecExp.buildings.propHub.upgrades.fakeNews === 0) {
				App.UI.DOM.appendNewElement("div", node, makeLink(
					"Install a news generator",
					10000,
					"The authenticity dept. now provides a small amount of reputation as well as authority, but increases upkeep.",
					"fakeNews",
					false,
					"Install an automatic news generator, able to fabricate thousands of plausible sounding news every day."
				));
			} else {
				App.UI.DOM.appendNewElement("div", node);
				node.append(
					"You have installed an automatic news generator. ",
					App.UI.DOM.link(
						"Remove news generator",
						() => {
							V.SecExp.buildings.propHub.upgrades.fakeNews = 0;
							App.UI.reload();
						}
					)
				);
			}

			if (V.SecExp.buildings.propHub.upgrades.controlLeaks === 0) {
				App.UI.DOM.appendNewElement("div", node, makeLink(
					"Institute controlled leaks protocols",
					10000,
					"The authenticity dept. now provides a small amount of reputation as well as authority, but increases upkeep.",
					"controlLeaks",
					true,
					"Institute a system able to release erroneous, but plausible, information about your business, leading your competitors to prepared financial traps. "
				));
			} else {
				App.UI.DOM.appendNewElement("div", node);
				node.append(
					"You have instituted controlled leaks protocols, able to create fabricated leaks of sensible information. ",
					App.UI.DOM.link(
						"Shut down leak protocols",
						() => {
							V.SecExp.buildings.propHub.upgrades.controlLeaks = 0;
							App.UI.reload();
						}
					)
				);
			}
		}
		App.Events.addParagraph(node, []);

		if (V.SecExp.buildings.propHub.upgrades.secretService === 0) {
			node.append(makeLink(
				"Set up personal secret service",
				10000,
				"Will provide authority and unlock special upgrades, but will increase upkeep.",
				"secretService",
				false,
				"Set up a department tasked with the protection of your person, as well as operations requiring a delicate approach."
			));
		} else {
			if (V.SecExp.buildings.propHub.upgrades.secretService < 5 && V.rep >= (V.SecExp.buildings.propHub.upgrades.secretService * 1000) + 5000) {
				node.append(makeLink(
					"Expand the secret service",
					5000,
					"Will provide more authority each week, but increases upkeep.",
					"secretService",
					false,
					"Invest more resources into the project to increase its effectiveness."
				));
			} else if (V.SecExp.buildings.propHub.upgrades.secretService < 5) {
				node.append("You lack the reputation to further expand operations.");
			} else {
				node.append("You have upgraded the secret service to its maximum.");
			}

			if (V.SecExp.buildings.propHub.upgrades.blackOps === 0) {
				App.UI.DOM.appendNewElement("div", node, makeLink(
					"Create a black ops team",
					10000,
					"The secret services now provides security as well as authority, but increases upkeep.",
					"blackOps",
					false,
					"Create a black ops team, ready to carry out corporate sabotage and sensitive operations to further your goals."
				));
			} else {
				App.UI.DOM.appendNewElement("div", node, "You have created a black ops team.");
			}

			if (V.SecExp.buildings.propHub.upgrades.marketInfiltration === 0) {
				App.UI.DOM.appendNewElement("div", node, makeLink(
					"Infiltrate the black market in order to manipulate it",
					10000,
					"The secret services now provides cash as well as authority each week, but will increase crime growth",
					"marketInfiltration"
				));
			} else {
				App.UI.DOM.appendNewElement("div", node);
				node.append(
					"You have infiltrated the black market and are now in partial control of it. ",
					App.UI.DOM.link(
						"Withdraw from the black market",
						() => {
							V.SecExp.buildings.propHub.upgrades.marketInfiltration = 0;
							App.UI.reload();
						}
					)
				);
			}
		}

		return node;

		function makeLink(text, price, note, type, applyHacking=true, message=null) {
			const r = new DocumentFragment();
			r.append(App.UI.DOM.link(text,
				() => {
					cashX(forceNeg(getCost()), "capEx");
					if (applyHacking) {
						V.PC.skill.hacking++;
					}
					V.SecExp.buildings.propHub.upgrades[type]++;
					if (V.SecExp.buildings.propHub.upgrades.campaign === 1) {
						V.SecExp.buildings.propHub.focus = "social engineering";
					}
					App.UI.reload();
				},
			));
			if (message) {
				App.UI.DOM.appendNewElement("div", r, `${message}`);
			}
			App.UI.DOM.appendNewElement("div", r, `Costs ${cashFormat(getCost())}. ${note}`, "note");
			return r;

			function getCost() {
				const HistoryDiscount = ["capitalist", "celebrity", "wealth"].includes(V.PC.career) ? 0.5 : 1;
				return Math.trunc(price * V.upgradeMultiplierArcology * (V.SecExp.buildings.propHub.upgrades[type] + 1) * HistoryDiscount * (applyHacking ? V.HackingSkillMultiplier : 1));
			}
		}
	}
})();

repo_name: Mirarara/fc

license: mit


code:
App.Mods.SecExp.riotCenter = (function() {
	return {
		init,
		GUI
	};

	function init() {
		V.SecExp.buildings.riotCenter = {
			upgrades: {
				freeMedia: 0,
				rapidUnit: 0,
				rapidUnitSpeed: 0,
			},
			fort: {
				reactor: 0,
				waterway: 0,
				assistant: 0,
			},
			sentUnitCooldown: 0,
			advancedRiotEquip: 0,
			brainImplant: -1,
			brainImplantProject: 0,
		};
	}

	function GUI() {
		const node = new DocumentFragment();
		V.nextButton = "Back";
		V.nextLink = "Main";
		node.append("The riot control center opens its guarded doors to you. The great chamber inside is dominated by massive screens filled with vital information and propaganda being tested.");
		App.Events.addParagraph(node, []);

		if (V.SecExp.rebellions.tension <= 33) {
			node.append("Tensions in the arcology are low. Political and ideological opposition against the arcology owner is almost unheard of.");
		} else if (V.SecExp.rebellions.tension <= 66) {
			node.append("Tensions in the arcology are rising; political and ideological opposition against the arcology owner are becoming a part of the daily life of the arcology.");
		} else {
			node.append("Tensions are high. Opposition to the arcology owner is a sentiment shared by many and armed resistance is on the rise.");
		}

		if (V.SecExp.buildings.riotCenter.upgrades.freeMedia === 0) {
			App.UI.DOM.appendNewElement("div", node,
				makeLink(
					"Provide free media access in all the arcology",
					5000,
					"Will slowly lower tensions in the arcology, but will incur in upkeep costs.",
					"freeMedia"
				)
			);
		} else {
			App.UI.DOM.appendNewElement("div", node, "You are providing free access to many mass media in the arcology.");
			if (V.SecExp.buildings.riotCenter.upgrades.freeMedia < 5) {
				App.UI.DOM.appendNewElement("div", node,
					makeLink(
						"Invest more resources in the free media project to increase its effectiveness",
						5000,
						"Will accelerate the tension decay, but will increase upkeep costs.",
						"freeMedia",
						true
					)
				);
			} else {
				App.UI.DOM.appendNewElement("div", node, "You upgraded your free media scheme to its limits.");
			}
		}
		App.Events.addParagraph(node, []);

		node.append(progressReport("slave"));
		App.UI.DOM.appendNewElement("div", node, progressReport("citizen"));
		App.Events.addParagraph(node, []);

		if (V.SecExp.buildings.riotCenter.upgrades.rapidUnit === 0) {
			node.append(
				makeLink(
					"Create rapid deployment riot units",
					7500,
					"Will allow spending authority or reputation to lower the progress of rebellions.",
					"rapidUnit"
				)
			);
		} else {
			node.append("You created a rapid deployment riot unit.");
			if (V.SecExp.buildings.riotCenter.upgrades.rapidUnit < 5) {
				App.UI.DOM.appendNewElement("div", node,
					makeLink(
						"Invest more resources in the rapid deployment unit",
						5000,
						"Will lower action costs.",
						"rapidUnit"
					)
				);
			} else {
				App.UI.DOM.appendNewElement("div", node, "You upgraded your rapid deployment unit to its limits.");
			}

			if (V.SecExp.buildings.riotCenter.upgrades.rapidUnitSpeed < 2) {
				App.UI.DOM.appendNewElement("div", node,
					makeLink(
						"Enhance the internal informants network",
						5000,
						"Will reduce cooldown of the rapid deployment riot unit.",
						"rapidUnitSpeed"
					)
				);
			} else {
				App.UI.DOM.appendNewElement("div", node, "You enhanced your informants network to its limits.");
			}

			App.Events.addParagraph(node, []);
			if (V.SecExp.buildings.riotCenter.sentUnitCooldown === 0) {
				App.UI.DOM.appendNewElement("div", node, deployUnit());
			} else {
				App.UI.DOM.appendNewElement("div", node, `The unit cannot be deployed again for ${V.SecExp.buildings.riotCenter.sentUnitCooldown} weeks.`);
			}
		}
		App.Events.addParagraph(node, []);

		if (V.SecExp.buildings.riotCenter.brainImplant < 106) {
			if (V.SecExp.buildings.riotCenter.brainImplantProject === 0) {
				node.append(
					makeLink(
						"Start secretly installing brain implants in your citizens and resident slaves",
						0,
						`Will take weeks of work and will cost ${cashFormat(5000)} each week, but once finished rebellions will progress a lot slower.`,
						"brainImplantStart"
					)
				);
			} else if (V.SecExp.buildings.riotCenter.brainImplantProject < 5) {
				node.append(
					makeLink(
						"Invest more resources into the project to increase its speed",
						50000,
						"Will shorten the time required to complete the project.",
						"brainImplantProject",
						true
					)
				);
			} else {
				node.append("You sped up the project to its maximum.");
			}
			if (V.SecExp.buildings.riotCenter.brainImplant !== -1) {
				App.UI.DOM.appendNewElement("div", node, `The great brain implant project is underway. Estimated time to completion: ${Math.trunc((100 - V.SecExp.buildings.riotCenter.brainImplant) / V.SecExp.buildings.riotCenter.brainImplantProject)}`);
			}
		} else {
			node.append("The great brain implant project is completed, rebellions against you will be extremely difficult to organize.");
		}
		App.Events.addParagraph(node, []);

		if (V.SecExp.buildings.riotCenter.advancedRiotEquip === 0) {
			node.append(
				makeLink(
					"Develop advanced anti-riot equipment",
					30000,
					"Will allow the selection of advanced riot equipment in case of a rebellion, which will let your troops fight at full effectiveness while doing reduced collateral damage.",
					"advancedRiotEquip"
				)
			);
		} else {
			node.append("You developed advanced riot equipment, which allows your troops to fight within the confines of your arcology without the fear of doing major collateral damage.");
		}

		if (V.SecExp.buildings.riotCenter.fort.reactor === 0) {
			App.UI.DOM.appendNewElement("div", node,
				makeLink(
					"Reinforce the reactor complex",
					10000,
					"Will add protection to the reactor building, making it less likely to be damaged and speeding up repairs if our defensive efforts should fail.",
					"reactor"
				)
			);
		} else {
			App.UI.DOM.appendNewElement("div", node, "You have installed additional protection layers and redundant systems in the reactor complex.");
		}

		if (V.SecExp.buildings.riotCenter.fort.waterway === 0) {
			App.UI.DOM.appendNewElement("div", node,
				makeLink(
					"Reinforce the waterways",
					10000,
					"Will add protection to the waterways, making it less likely to be damaged and speeding up repairs if our defensive efforts should fail.",
					"waterway"
				)
			);
		} else {
			App.UI.DOM.appendNewElement("div", node, "You have installed additional protection layers and redundant systems in the waterways.");
		}

		if (V.SecExp.buildings.riotCenter.fort.assistant === 0) {
			App.UI.DOM.appendNewElement("div", node,
				makeLink(
					"Reinforce the assistant CPU core",
					10000,
					"Will add protection to the assistant CPU core, making it less likely to be damaged and speeding up repairs if our defensive efforts should fail.",
					"assistant"
				)
			);
		} else {
			App.UI.DOM.appendNewElement("div", node, "You have installed additional protection layers and redundant systems in the assistant CPU core.");
		}

		if (V.SF.Toggle && V.SF.Active >= 1) {
			if (V.SecExp.edicts.SFSupportLevel >= 4 && V.SF.Squad.Armoury >= 8 && !V.SecExp.rebellions.sfArmor) {
				App.UI.DOM.appendNewElement("div", node);
				const cost = Math.ceil(500000 * App.Mods.SF.env() * (1.15 + (V.SF.Squad.Armoury/10) ));
				App.UI.DOM.appendNewElement("span", node,
					App.UI.DOM.link(
						`Give the riot unit access to the combat armor suits of ${V.SF.Lower}.`,
						() => {
							V.SecExp.rebellions.sfArmor = 1;
							cashX(-cost, "capEx");
						}
					)
				);
				App.UI.DOM.appendNewElement("span", node, `Costs ${cashFormat(cost)}.`, "note");
			} else {
				App.UI.DOM.appendNewElement("div", node, `You have given the riot unit access to the combat armor suits of ${V.SF.Lower}.`);
			}
		}
		return node;

		function deployUnit() {
			const deploy = document.createElement("span");
			const r = [];
			App.UI.DOM.appendNewElement("div", deploy, "You can send out the squad to slow down the progress of hostile groups within the arcology.");
			for (const type of ["authority", "reputation"]) {
				r.push(App.UI.DOM.link(
					`${capFirstChar(type)}`,
					() => {
						App.UI.DOM.replace(deploy, menu(type));
					}
				));
			}
			deploy.append("Spend: ", App.UI.DOM.generateLinksStrip(r));
			return deploy;
			/**
			 * @param {string} cost
			 * @returns {HTMLSpanElement}
			 */
			function menu(cost) {
				const text = document.createElement("span");
				App.UI.DOM.appendNewElement("div", text, `Your ${cost} will be leveraged to suppress the rebels.`);
				for (const type of ["slave", "citizen"]) {
					App.UI.DOM.appendNewElement("div", text, App.UI.DOM.link(
						`Deploy the unit against ${type} rebel leaders`,
						() => {
							const price = forceNeg(1000 + 50 * V.SecExp.buildings.riotCenter.upgrades.rapidUnit);
							(function() { cost === "reputation" ? repX(price, "war") : App.Mods.SecExp.authorityX(-price); })();
							const change = random(15) + random(1, 2) * V.SecExp.buildings.riotCenter.upgrades.rapidUnit;
							V.SecExp.rebellions[type + "Progress"] = Math.clamp(V.SecExp.rebellions[type + "Progress"] - change, 0, 100);
							V.SecExp.buildings.riotCenter.sentUnitCooldown = 3 - V.SecExp.buildings.riotCenter.upgrades.rapidUnitSpeed;
							App.UI.DOM.replace(text, `${capFirstChar(type)} rebellion progress set back by ${change}%. The unit will be able to deployed again in ${V.SecExp.buildings.riotCenter.sentUnitCooldown} weeks.`);
						}
					));
				}
				return text;
			}
		}
		function makeLink(text, price, note, type, applyHacking=false) {
			const r = new DocumentFragment();
			r.append(App.UI.DOM.link(text,
				() => {
					cashX(-getCost(), "capEx");
					if (applyHacking) {
						V.PC.skill.hacking++;
					}
					switch (type) {
						case "freeMedia":
						case "rapidUnit":
						case "rapidUnitSpeed":
							V.SecExp.buildings.riotCenter.upgrades[type]++;
							break;
						case "brainImplantStart":
							V.SecExp.buildings.riotCenter.brainImplantProject = 1;
							V.SecExp.buildings.riotCenter.brainImplant = 0;
							break;
						case "brainImplantProject":
						case "advancedRiotEquip":
							V.SecExp.buildings.riotCenter[type]++;
							break;
						case "reactor":
						case "waterway":
						case "assistant":
							V.SecExp.buildings.riotCenter.fort[type]++;
					}
					App.UI.reload();
				},
			));

			if (type !== "brainImplantProject") {
				App.UI.DOM.appendNewElement("div", r, `Costs ${cashFormat(getCost())}. ${note}`, "note");
			} else {
				App.UI.DOM.appendNewElement("div", r, `One-time cost of ${cashFormat(getCost())} with an additional ${cashFormat(5000)} each week in maintenance. ${note}`, "note");
			}
			return r;

			function getCost() {
				if (["freeMedia", "rapidUnit", "rapidUnitSpeed"].includes(type)) {
					return Math.trunc(price * V.upgradeMultiplierArcology * (V.SecExp.buildings.riotCenter.upgrades[type] + 1) * (applyHacking ? V.HackingSkillMultiplier : 1));
				} else if (type === "brainImplantProject") {
					return Math.trunc(price * V.upgradeMultiplierArcology * (V.SecExp.buildings.riotCenter.brainImplantProject) * (applyHacking ? V.HackingSkillMultiplier : 1));
				} else if (type !== "advancedRiotEquip") {
					return Math.trunc(price * V.upgradeMultiplierArcology * (applyHacking ? V.HackingSkillMultiplier : 1));
				} else {
					return Math.trunc(price * V.upgradeMultiplierTrade);
				}
			}
		}
		function progressReport(type) {
			if (V.SecExp.rebellions[type + "Progress"] <= 25) {
				return `There is very low unrest between the ${type + 's'} of the arcology. The chances of a rebellion igniting are extremely low.`;
			} else if (V.SecExp.rebellions[type + "Progress"] <= 50) {
				return `There is some unrest between the ${type + 's'}. No major movement is forming yet, but it might be time to consider preventive measures.`;
			} else if (V.SecExp.rebellions[type + "Progress"] <= 75 ) {
				return `Unrest is getting high between the ${type + 's'} of the arcology. Preventive measures are necessary if we want to prevent a violent rebellion.`;
			}
			return `Unrest is extremely high between ${type + 's'}. The chances of a rebellion happening in the near future are extremely high.`;
		}
	}
})();


code:
App.Mods.SecExp.barracks = (function() {
	return {
		init,
		GUI
	};

	function init() {
		V.SecExp.buildings.barracks = {
			size: 0,
			luxury: 0,
			training: 0,
			loyaltyMod: 0
		};
	}

	function GUI() {
		const node = new DocumentFragment();
		V.nextButton = "Back";
		V.nextLink = "Main";
		let r = [];
		let cost;
		let text;

		node.append(`While this is a sore sight for many citizens of ${V.arcologies[0].name}, the barracks stand proud before you. `);
		App.UI.DOM.appendNewElement("h1", node, "Upgrades", ["underline"]);
		switch (V.SecExp.buildings.barracks.size) {
			case 0: r.push("The building is relatively small and able to house a limited number of units."); break;
			case 1: r.push("The building has been expanded and can now house more units comfortably."); break;
			case 2: r.push("The building has been further expanded and can now house a high number of units."); break;
			case 3: r.push("The building has been greatly expanded and can now house a sizable military."); break;
			case 4: r.push("The building has been greatly expanded and can now house a small army."); break;
			case 5: r.push("The building has been greatly expanded and can now house an army worthy of an old world nation."); break;
		}
		App.UI.DOM.appendNewElement("div", node, toSentence(r, " ", " "));
		r = [];

		if (V.SecExp.buildings.barracks.luxury === 0) {
			node.append("The barracks are a spartan building, with little to make the day to day lives of your soldiers pleasant.");
		} else {
			r.push("The barracks have been made more comfortable by");
			if (V.SecExp.buildings.barracks.luxury >= 1) {
				r.push("installing high tech furniture");
			}
			if (V.SecExp.buildings.barracks.luxury >= 2) {
				r.push("and advanced kitchen facilities");
			}
			if (V.SecExp.buildings.barracks.luxury >= 3) {
				r.push("It also provides free access to any digital media");
			}
			if (V.SecExp.buildings.barracks.luxury >= 4) {
				r.push("A small limited-access brothel has been added to the structure");
			}
			App.UI.DOM.appendNewElement("div", node, toSentence(r));
		}

		if (V.SecExp.buildings.barracks.training === 0) {
			App.UI.DOM.appendNewElement("div", node, "The building lacks the space and the equipment to train your units.");
		} else if (V.SecExp.buildings.barracks.training === 1) {
			App.UI.DOM.appendNewElement("div", node, "A training facility has been set up, allowing your units to better their skills with time.");
		} else {
			App.UI.DOM.appendNewElement("div", node, "The training facility has been filled with specialized equipment and skilled trainers.");
		}

		if (V.SecExp.buildings.barracks.loyaltyMod === 0) {
			App.UI.DOM.appendNewElement("div", node, "The barracks lack an indoctrination facility.");
		} else if (V.SecExp.buildings.barracks.loyaltyMod === 1) {
			App.UI.DOM.appendNewElement("div", node, "The barracks have been fitted with an indoctrination facility.");
		} else {
			App.UI.DOM.appendNewElement("div", node, "The barracks have been fitted with an advanced indoctrination facility.");
		}
		App.Events.addParagraph(node, []);

		if (V.SecExp.buildings.barracks.size < 5) {
			cost = Math.trunc(5000 * (V.SecExp.buildings.barracks.size + 1) * V.upgradeMultiplierArcology);
			node.append(App.UI.DOM.link("Increase the size of the barracks", () => {
				cashX(-cost, "capEx");
				V.SecExp.buildings.barracks.size++;
				App.UI.reload();
			}
			));
			App.UI.DOM.appendNewElement("div", node, `Costs ${cashFormat(cost)} and will increase the maximum number of units by 2`, ["note"]);
		} else {
			const activeSF = V.SF.Toggle && V.SF.Active >= 1;
			const sectionSF = activeSF && V.SF.Squad.Firebase > 5 && V.SecExp.edicts.SFSupportLevel >= 4 && App.Mods.SecExp.battle.maxUnits() === 18 && App.Mods.SecExp.battle.deploySpeed() <= 10;
			const reasons = [];
			if (activeSF) {
				if (V.SF.Squad.Firebase < 5) {
					reasons.push('the Firebase is expanded');
				}
				if (V.SecExp.edicts.SFSupportLevel < 4) {
					reasons.push('the scope of the support contract/edict is increased');
				}
			}

			if (reasons.length > 0 || sectionSF) {
				const capSF = capFirstChar(V.SF.Lower || "the Special Force");
				if (reasons.length > 0) {
					App.UI.DOM.appendNewElement("div", node, `The Colonel says that ${capSF} may be able to provide assistance if ${toSentence(reasons)}.`);
				}
				cost = Math.trunc( (750000 * (1.15 + (App.Mods.SF.upgrades.total() / 1000)) * (1.15 + (V.SF.Squad.Firebase / 10))) * App.Mods.SF.env() );
				if (sectionSF && !V.SecExp.sectionInFirebase) {
					node.append(App.UI.DOM.link(`Direct the ${capSF} to provide the security force with their own section in the Firebase `, () => {
						V.SecExp.sectionInFirebase = 1;
						cashX(-cost, "specialForcesCap");
						App.UI.reload();
					}
					));
					App.UI.DOM.appendNewElement("span", node, `Costs ${cashFormat(cost)}`, ["cash", "dec"]);
				}
			} else {
				App.UI.DOM.appendNewElement("div", node, "You've expanded the barracks to their maximum.");
			}
		}

		if (V.SecExp.buildings.barracks.luxury < 4) {
			switch (V.SecExp.buildings.barracks.luxury) {
				case 0:
					cost = Math.trunc(5000 * V.upgradeMultiplierTrade);
					text = "Increase the quality of life of your soldiers by installing high tech furniture and appliances";
					break;
				case 1:
					cost = Math.trunc(10000 * V.upgradeMultiplierTrade);
					text = "Further increase the quality of life of your soldiers by installing advanced kitchen equipment and hiring skilled chefs";
					break;
				case 2:
					cost = Math.trunc(10000 * V.upgradeMultiplierTrade);
					text = "Further increase the quality of life of your soldiers by providing high speed, free access to digital media";
					break;
				case 3:
					cost = Math.trunc(15000 * V.upgradeMultiplierTrade);
					text = "Further increase the quality of life of your soldiers by adding and staffing an exclusive brothel to the structure";
			}

			App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link(text, () => {
				cashX(forceNeg(cost), "capEx");
				V.SecExp.buildings.barracks.luxury++;
				App.UI.reload();
			}
			));
			App.UI.DOM.appendNewElement("div", node, `Costs ${cashFormat(cost)} and will provide a 5% bonus to morale${V.SecExp.buildings.barracks.luxury === 0 ? "." : `for a total of +${(V.SecExp.buildings.barracks.luxury + 1) * 5}.`}`, ["note"]);
		} else {
			App.UI.DOM.appendNewElement("div", node, "You've made life in your barracks as good as it can get.");
		}

		if (V.SecExp.buildings.barracks.training < 2) {
			switch (V.SecExp.buildings.barracks.training) {
				case 0:
					cost = Math.trunc(10000 * V.upgradeMultiplierArcology);
					text = "Add a training facility to the barracks";
					break;
				case 1:
					cost = Math.trunc(20000 * V.upgradeMultiplierTrade);
					text = "Improve the training facility with modern equipment and skilled personnel";
			}

			App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link(text, () => {
				cashX(forceNeg(cost), "capEx");
				V.SecExp.buildings.barracks.training++;
				App.UI.reload();
			}
			));
			App.UI.DOM.appendNewElement("div", node, `Costs ${cashFormat(cost)} and will allow units to accumulate ${V.SecExp.buildings.barracks.training === 0 ? "some" : "additional"} experience each week.`, ["note"]);
		} else {
			App.UI.DOM.appendNewElement("div", node, "You have improved the training facility to the limit.");
		}

		if (V.SecExp.buildings.barracks.loyaltyMod < 2) {
			switch (V.SecExp.buildings.barracks.loyaltyMod) {
				case 0:
					cost = Math.trunc(10000 * V.upgradeMultiplierArcology);
					text = "Add an indoctrination facility to the barracks";
					break;
				case 1:
					cost = Math.trunc(20000 * V.upgradeMultiplierTrade);
					text = "Improve the indoctrination facility with advanced equipment and skilled personnel";
			}

			App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link(text, () => {
				cashX(forceNeg(cost), "capEx");
				V.SecExp.buildings.barracks.loyaltyMod++;
				App.UI.reload();
			}
			));
			App.UI.DOM.appendNewElement("div", node, `Costs ${cashFormat(cost)} and will ${V.SecExp.buildings.barracks.loyaltyMod === 0 ? "slowly raise loyalty of all units" : "raise loyalty of all units faster"}.`, "note");
		} else {
			App.UI.DOM.appendNewElement("div", node, "You have improved the indoctrination facility to the limit.");
		}

		App.UI.DOM.appendNewElement("h1", node, "Units", "underline");
		node.append(`${App.Mods.SecExp.battle.activeUnits()}/${App.Mods.SecExp.battle.maxUnits()} are active, totalling ${num(App.Mods.SecExp.unit.squads().reduce((acc, t) => acc += t.troops, 0))} troops `);
		if (App.Mods.SecExp.battle.activeUnits() === 2 * App.Mods.SecExp.battle.deploySpeed()) {
			node.append(`and all can be deployed.`);
		} else {
			node.append(`however only ${2 * App.Mods.SecExp.battle.deploySpeed()} can be deployed.`);
		}
		if (V.SecExp.buildings.barracks.luxury > 0) {
			node.append(` The barracks provides ${V.SecExp.buildings.barracks.luxury * 5}% bonus morale when battle occurs.`);
		}
		if (V.SecExp.buildings.barracks.training > 0) {
			node.append(" The training facility will increase the effectiveness of your units with time.");
		}

		const options = new App.UI.OptionsGroup();
		options.addOption("Unit descriptions are", "unitDescriptions", V.SecExp.settings)
			.addValue("Abbreviated", 1).on().addValue("Summarized", 0).off();
		node.append(options.render());
		if (App.Mods.SecExp.battle.activeUnits() >= App.Mods.SecExp.battle.maxUnits()) {
			App.UI.DOM.appendNewElement("div", node, "You have reached the maximum number of units. You'll have to disband one or enlarge the barracks before forming a new unit.");
		}
		node.append(App.Mods.SecExp.unit.replenishAll());

		const tabBar = new App.UI.Tabs.TabBar("SecExpBarracks");
		for (const [unit, data] of App.Mods.SecExp.unit.list()) {
			if (data.unlock) {
				tabBar.addTab(`${capFirstChar(data.name || unit)}: ${(V.SecExp.units[unit].squads.length)}`, unit, page(unit));
			} else {
				App.UI.DOM.appendNewElement("div", node, data.lockedText);
			}
		}
		node.append(tabBar.render());
		return node;

		function page(u) {
			const r = new DocumentFragment();
			switch (u) {
				case "slaves":
					App.UI.DOM.appendNewElement("div", r, `You are free to organize your menial slaves into fighting units. Currently you have ${num(V.menials)} slaves available, while ${num(App.Mods.SecExp.Manpower.employedSlave)} are already employed as soldiers. During all your battles you lost a total of ${num(V.SecExp.units.slaves.dead)}.`);
					break;
				case "militia":
					App.UI.DOM.appendNewElement("div", r, `You founded the ${V.arcologies[0].name} free militia. You are now able to organize your citizens into fighting units.`);
					switch (V.SecExp.edicts.defense.militia) {
						case 2:
							App.UI.DOM.appendNewElement("div", r, `The militia is composed entirely of volunteers, your manpower is ${num(App.Mods.SecExp.militiaCap()*100)}% of the citizens population of your arcology.`);
							break;
						case 3:
							App.UI.DOM.appendNewElement("div", r, `With the establishment of conscription, your available manpower has increased to now ${num(App.Mods.SecExp.militiaCap()*100)}% of the arcology's citizens population.`);
							break;
						case 4:
							App.UI.DOM.appendNewElement("div", r, `By establishing obligatory military service to obtain citizenship you have enlarged your manpower pool to be ${num(App.Mods.SecExp.militiaCap()*100)}% of the arcology's citizens population.`);
							break;
						case 5:
							App.UI.DOM.appendNewElement("div", r, `With the adoption of a militarized society, your available manpower has swelled to be ${num(App.Mods.SecExp.militiaCap()*100)}% of the arcology's citizens population.`);
					}
					App.UI.DOM.appendNewElement("div", r, `Your current total manpower is ${num(App.Mods.SecExp.Manpower.totalMilitia)}, of which ${num(App.Mods.SecExp.Manpower.employedMilitia)} is in active duty. You lost in total ${num(V.SecExp.units.militia.dead)} citizens, leaving you with ${num(V.SecExp.units.militia.free)} available citizens.`);
					break;
				case "mercs":
					App.UI.DOM.appendNewElement("div", r, `With the installation of a mercenary company in the arcology, many other are attracted to your free city, hoping to land a contract with you.`);
					App.UI.DOM.appendNewElement("div", r, `You are able to organize them in units to use in the defense of the arcology. Excluding the defense force you set up, there are ${num(App.Mods.SecExp.Manpower.totalMerc)} mercenaries in your arcology, of which ${num(App.Mods.SecExp.Manpower.employedMerc)} actively employed and ${num(V.SecExp.units.mercs.free)} not yet under contract. In total ${num(V.SecExp.units.mercs.dead)} mercenaries have died defending your arcology.`);
					break;
			}

			App.UI.DOM.appendNewElement("div", r, App.Mods.SecExp.unit.barracksList(u));
			return r;
		}
	}
})();


code:
App.Mods.SecExp.secHub = (function() {
	return {
		init,
		GUI
	};

	function init() {
		V.SecExp.buildings.secHub = {
			menials: 0,
			coldstorage: 0,
			upgrades: {
				security: {
					nanoCams: 0,
					cyberBots: 0,
					eyeScan: 0,
					cryptoAnalyzer: 0,
				},
				crime: {
					autoTrial: 0,
					autoArchive: 0,
					worldProfiler: 0,
					advForensic: 0,
				},
				intel : {
					sensors: 0,
					radar: 0,
					signalIntercept: 0,
				},
				readiness: {
					earlyWarn: 0,
					rapidPlatforms: 0,
					pathways: 0,
					rapidVehicles: 0,
				}
			}
		};
	}
	function GUI() {
		const node = new DocumentFragment();
		V.nextButton = "Back";
		V.nextLink = "Main";
		let r = [];

		r.push("The security headquarters stand in front of you. Innumerable screens flood with light the great central room.");
		if (V.SecExp.buildings.secHub.menials > 0) {
			r.push("Some slaves see you enter and interrupt their work to greet you.");
		}
		r.push("From here you can build a safe and prosperous arcology.");
		node.append(r.join(" "));
		if (V.SecExp.core.authority < 10000 || V.SecExp.core.authority < 12000) {
			App.UI.DOM.appendNewElement("div", node, "You lack the authority to access more advanced upgrades.", "red");
		}

		App.UI.DOM.appendNewElement("div", node, `You have ${num(V.SecExp.buildings.secHub.menials)} slaves working in the HQ. ${App.Mods.SecExp.Check.reqMenials()} are required and you have ${num(V.menials)} free menial slaves.`);
		if (V.SecExp.buildings.secHub.menials < App.Mods.SecExp.Check.reqMenials()) {
			App.UI.DOM.appendNewElement("div", node, "You do not have enough slaves here. You will not receive the full benefit of the installed upgrades.");
		} else {
			App.UI.DOM.appendNewElement("div", node, "You have enough slaves to man all security systems.");
		}
		App.UI.DOM.appendNewElement("div", node, App.UI.market({menialWorkersOnly: true}));

		const optionsList = [1, 5, 10, 100, 500, 1000];
		let linkArray;
		for (const flow of ["in", "out"]) {
			linkArray = [];
			for (const value of optionsList.filter(s => (flow === "in" ? V.menials : V.SecExp.buildings.secHub.menials) >= s)) {
				linkArray.push(
					App.UI.DOM.link(
						`${value}`,
						() => {
							if (flow === "in") {
								V.menials -= value;
								V.SecExp.buildings.secHub.menials += value;
							} else {
								V.menials += value;
								V.SecExp.buildings.secHub.menials -= value;
							}
							App.UI.reload();
						}
					)
				);
			}
			if (linkArray.length > 0) {
				const line = new DocumentFragment();
				line.append(`Transfer ${flow}: `, App.UI.DOM.generateLinksStrip(linkArray));
				App.UI.DOM.appendNewElement("div", node, line);
			}
		}

		if (V.SecExp.buildings.secHub.menials > 0) {
			App.UI.DOM.appendNewElement("div", node,
				App.UI.DOM.link(
					"Match the requirement",
					() => {
						if (V.menials >= App.Mods.SecExp.Check.reqMenials() - V.SecExp.buildings.secHub.menials) {
							V.menials -= App.Mods.SecExp.Check.reqMenials() - V.SecExp.buildings.secHub.menials;
							V.SecExp.buildings.secHub.menials = App.Mods.SecExp.Check.reqMenials();
						} else if (App.Mods.SecExp.Check.reqMenials() < V.SecExp.buildings.secHub.menials) {
							V.menials += App.Mods.SecExp.Check.reqMenials() - V.SecExp.buildings.secHub.menials;
							V.SecExp.buildings.secHub.menials = App.Mods.SecExp.Check.reqMenials();
						} else {
							V.SecExp.buildings.secHub.menials += V.menials;
							V.menials = 0;
						}
						App.UI.reload();
					}
				)
			);
		}

		App.Events.addParagraph(node, []);
		switch (App.Mods.SecExp.battle.recon()) {
			case 0:
				App.UI.DOM.appendNewElement("div", node, "Your reconnaissance capabilities are very limited. Very little information will be available if the arcology is attacked.");
				break;
			case 1:
				App.UI.DOM.appendNewElement("div", node, "You have limited reconnaissance capabilities. You'll have limited intel available in case of an attack.");
				break;
			case 2:
				App.UI.DOM.appendNewElement("div", node, "You have good reconnaissance capabilities. Good, reliable intel will be available if the arcology is attacked.");
				break;
			case 3:
				App.UI.DOM.appendNewElement("div", node, "You have great reconnaissance capabilities. You'll have very accurate information on the enemy if the arcology is attacked.");
		}

		switch (App.Mods.SecExp.battle.deploySpeed()) {
			case 1:
				App.UI.DOM.appendNewElement("div", node, "You have low readiness. You won't be able to mobilize many troops in time in case of an attack.");
				break;
			case 2:
				App.UI.DOM.appendNewElement("div", node, "You have decent readiness. You will be able to muster up sufficient forces to handle an average attack.");
				break;
			case 3:
				App.UI.DOM.appendNewElement("div", node, "You have good readiness. You will be able to mobilize a lot of troops in case of an attack.");
				break;
			case 4:
				App.UI.DOM.appendNewElement("div", node, "You have great readiness. You can mobilize a small army in very little time.");
		}

		App.UI.DOM.appendNewElement("div", node, situationAnalysis("security"));
		App.UI.DOM.appendNewElement("div", node, situationAnalysis("crime"));

		if (V.SecExp.core.authority > 12000) {
			App.Events.addParagraph(node, []);
			App.UI.DOM.appendNewElement("h2", node, `Cold Data Storage Facility:`);
			if (App.Mods.SecExp.Check.reqMenials() <= 10) {
				App.UI.DOM.appendNewElement("div", node, "Personnel cannot be further reduced.");
			} else {
				r = [];
				if (V.SecExp.buildings.secHub.coldstorage > 0) {
					r.push("You have installed a cold storage facility for the Security HQ's archives with a data retention capability of");
				}
				if (V.SecExp.buildings.secHub.coldstorage > 6) {
					r.push("three years.");
				} else {
					let cost;
					let authorityGate = 19500;
					let text = ["Expand the cold storage facility to increase data retention to"];
					const targetValue = V.SecExp.buildings.secHub.coldstorage;
					const note = `Will lower the amount of required slaves by ${targetValue > 0 ? "a further" : ""} 10, but will increase upkeep. The remaining slaves will be more efficient in dealing with crime.`;
					if (V.SecExp.buildings.secHub.coldstorage === 6) {
						cost = 2400000;
						r.push("two years.");
						text.push("three years.");
					} else if (V.SecExp.buildings.secHub.coldstorage === 5) {
						cost = 1200000;
						r.push("one year.");
						text.push("two years.");
					} else if (V.SecExp.buildings.secHub.coldstorage === 4) {
						cost = 900000;
						r.push("nine months.");
						text.push("one year.");
					} else if (V.SecExp.buildings.secHub.coldstorage === 3) {
						authorityGate = 18000;
						cost = 600000;
						r.push("six months.");
						text.push("nine months.");
					} else if (V.SecExp.buildings.secHub.coldstorage === 2) {
						authorityGate = 16000;
						cost = 300000;
						r.push("three months.");
						text.push("six months.");
					} else if (V.SecExp.buildings.secHub.coldstorage === 1) {
						authorityGate = 14000;
						cost = 100000;
						r.push("one month.");
						text.push("three months.");
					} else if (V.SecExp.buildings.secHub.coldstorage === 0) {
						authorityGate = 12000;
						cost = 50000;
						text = ["Install a cold storage facility"];
					}
					if (checkStatus(targetValue, authorityGate)) {
						App.UI.DOM.appendNewElement("div", node, makeLink(text.join(" "), cost, note, "coldstorage"));
					} else {
						App.UI.DOM.appendNewElement("div", node, `At least ${num(authorityGate)} authority is required to unlock the next tier.`, "red");
					}
				}
				if (r.length > 0) {
					App.UI.DOM.appendNewElement("div", node, r.join(" "));
				}
			}
		}

		App.Events.addParagraph(node, []);
		const tabBar = new App.UI.Tabs.TabBar("SecExpSecurityHQ");
		tabBar.addTab("Security and crime", "SecurityCrime", SecurityCrime());
		tabBar.addTab("Reconnaissance and readiness", "ReconReadiness", ReconReadiness());
		node.append(tabBar.render());

		return node;

		function SecurityCrime() {
			const z = new DocumentFragment();
			App.UI.DOM.appendNewElement("h2", z, `Security`);
			if (V.SecExp.buildings.secHub.upgrades.security.nanoCams === 0) {
				z.append(
					makeLink("Install a nano-camera system",
						5000,
						"Will raise rest point of security by 10 points, but will require 5 extra slaves in the headquarters and increases upkeep. The remaining slaves will be more efficient in dealing with crime.",
						"nanoCams")
				);
			} else {
				z.append("You have installed all across the arcology closed circuit nano-cameras to keep the arcology under your watchful eye.");
			}

			if (V.SecExp.buildings.secHub.upgrades.security.cyberBots === 0) {
				App.UI.DOM.appendNewElement("div", z,
					makeLink("Buy cybersecurity algorithms",
						7500,
						"Will raise rest point of security by 10 points, but will require 5 extra slaves in the headquarters and increases upkeep. The remaining slaves will be more efficient in dealing with crime.",
						"cyberBots")
				);
			} else {
				App.UI.DOM.appendNewElement("div", z, "You have bought advanced cybersecurity algorithms that will defend your arcology against hack attempts or cyber frauds.");
			}

			if (V.SecExp.core.authority > 10000) {
				if (V.SecExp.buildings.secHub.upgrades.security.eyeScan === 0) {
					App.UI.DOM.appendNewElement("div", z,
						makeLink("Install invisible eye scanners",
							10000,
							"Will raise rest point of security by 15 points, but will require 10 extra slaves in the headquarters and increases upkeep. The remaining slaves will be more efficient in dealing with crime.",
							"eyeScan")
					);
				} else {
					App.UI.DOM.appendNewElement("div", z, "You have installed numerous hidden eye scanners that accurately register the movements of everyone inside the arcology.");
				}

				if (V.SecExp.buildings.secHub.upgrades.security.cryptoAnalyzer === 0) {
					App.UI.DOM.appendNewElement("div", z,
						makeLink("Buy and install crypto analyzers",
							15000,
							"Will raise rest point of security by 15 points, but will require 10 extra slaves in the headquarters and increases upkeep. The remaining slaves will be more efficient in dealing with crime.",
							"cryptoAnalyzer")
					);
				} else {
					App.UI.DOM.appendNewElement("div", z, "You have bought and employed sophisticated crypto analyzing software to accurately track and archive every financial movement or transaction made inside the walls of your arcology.");
				}
			}

			App.UI.DOM.appendNewElement("h2", z, `Crime`);
			if (V.SecExp.buildings.secHub.upgrades.crime.advForensic === 0) {
				App.UI.DOM.appendNewElement("div", z,
					makeLink("Install advanced forensic equipment",
						5000,
						"Will bring down the crime level cap by 10 points, but will require 10 extra slaves in the headquarters and increases upkeep. The remaining slaves will be more efficient in dealing with crime.",
						"advForensic")
				);
			} else {
				App.UI.DOM.appendNewElement("div", z, "You have installed advanced forensic equipment, able to extract every bit of precious information from any clue.");
			}
			if (V.SecExp.buildings.secHub.upgrades.crime.autoArchive === 0) {
				App.UI.DOM.appendNewElement("div", z,
					makeLink("Install auto-curating archiver",
						7500,
						"Will bring down the crime level cap by 10 points, but will require 5 extra slaves in the headquarters and increases upkeep. The remaining slaves will be more efficient in dealing with crime.",
						"autoArchive")
				);
			} else {
				App.UI.DOM.appendNewElement("div", z, "You have installed auto-curating archiver software, which will update in real time your data archives with any new relevant information on criminals residing in your arcology.");
			}

			if (V.SecExp.core.authority > 10000) {
				if (V.SecExp.buildings.secHub.upgrades.crime.autoTrial === 0) {
					App.UI.DOM.appendNewElement("div", z,
						makeLink("Install automated trials software",
							10000,
							"Will bring down the crime level cap by 15 points, but will require 5 extra slaves in the headquarters and increases upkeep. The remaining slaves will be more efficient in dealing with crime.",
							"autoTrial")
					);
				} else {
					App.UI.DOM.appendNewElement("div", z, "You have installed advanced legal algorithms that allows the handling of legal matters much quicker and much more accurately.");
				}

				if (V.SecExp.buildings.secHub.upgrades.crime.worldProfiler === 0) {
					App.UI.DOM.appendNewElement("div", z,
						makeLink("Install worldwide profilers",
							15000,
							"Will bring down the crime level cap by 15 points, but will require 10 extra slaves in the headquarters and increases upkeep. The remaining slaves will be more efficient in dealing with crime.",
							"worldProfiler")
					);
				} else {
					App.UI.DOM.appendNewElement("div", z, "You have installed advanced profiler software, which will constantly scour every known data archive on the globe (legally or not) to gather as much information as possible on dangerous criminals.");
				}
			}
			return z;
		}
		function ReconReadiness() {
			const z = new DocumentFragment();
			App.UI.DOM.appendNewElement("h2", z, `Reconnaissance`);
			if (V.SecExp.buildings.secHub.upgrades.intel.sensors === 0) {
				App.UI.DOM.appendNewElement("div", z,
					makeLink("Install perimeter sensors",
						5000,
						"Will increase recon capabilities, but will require 5 extra slaves in the headquarters and increases upkeep. The remaining slaves will be more efficient in dealing with crime.",
						"sensors")
				);
			} else {
				App.UI.DOM.appendNewElement("div", z, "You have installed perimeter seismic sensors able to detect movement with high accuracy.");
			}
			if (V.SecExp.buildings.secHub.upgrades.intel.signalIntercept === 0) {
				App.UI.DOM.appendNewElement("div", z,
					makeLink("Create signal interception hub",
						10000,
						"Will increase recon capabilities, but will require 5 extra slaves in the headquarters and increases upkeep. The remaining slaves will be more efficient in dealing with crime.",
						"signalIntercept")
				);
			} else {
				App.UI.DOM.appendNewElement("div", z, "You have installed advanced signal interception equipment.");
			}

			if (V.SecExp.core.authority > 10000) {
				if (V.SecExp.buildings.secHub.upgrades.intel.radar === 0) {
					App.UI.DOM.appendNewElement("div", z,
						makeLink("Install advanced radar equipment",
							15000,
							"Will increase recon capabilities, but will require 10 extra slaves in the headquarters and increases upkeep. The remaining slaves will be more efficient in dealing with crime.",
							"radar")
					);
				} else {
					App.UI.DOM.appendNewElement("div", z, "You have installed sophisticated radar equipment.");
				}
			}

			App.UI.DOM.appendNewElement("h2", z, `Readiness`);
			if (V.SecExp.buildings.secHub.upgrades.readiness.pathways === 0) {
				App.UI.DOM.appendNewElement("div", z,
					makeLink("Build specialized pathways in the arcology",
						5000,
						"Will increase readiness by 1, but will require 5 extra slaves in the headquarters and increase upkeep. The remaining slaves will be more efficient in dealing with crime.",
						"pathways")
				);
			} else {
				App.UI.DOM.appendNewElement("div", z, "You have built specialized pathways inside the arcology to quickly move troops around the structure.");
			}
			if (V.SecExp.buildings.secHub.upgrades.readiness.rapidVehicles === 0) {
				App.UI.DOM.appendNewElement("div", z,
					makeLink("Buy rapid armored transport vehicles",
						7500,
						"Will increase readiness by 2, but will require 5 extra slaves in the headquarters and increases upkeep. The remaining slaves will be more efficient in dealing with crime.",
						"rapidVehicles")
				);
			} else {
				App.UI.DOM.appendNewElement("div", z, "You have bought rapid armored transport vehicles able to bring your troops to battle much quicker than before.");
			}

			if (V.SecExp.core.authority > 10000) {
				if (V.SecExp.buildings.secHub.upgrades.readiness.rapidPlatforms === 0) {
					App.UI.DOM.appendNewElement("div", z,
						makeLink("Build rapid deployment platforms",
							10000,
							"Will increase readiness by 2, but will require 10 extra slaves in the headquarters and increases upkeep. The remaining slaves will be more efficient in dealing with crime.",
							"rapidPlatforms",
							false)
					);
				} else {
					App.UI.DOM.appendNewElement("div", z, "You have built rapid deployment platforms able to equip and deploy units within very limited time windows.");
				}
				if (V.SecExp.buildings.secHub.upgrades.readiness.earlyWarn === 0) {
					App.UI.DOM.appendNewElement("div", z,
						makeLink("Institute early warning systems",
							15000,
							"Will increase readiness by 2, but will require 10 extra slaves in the headquarters and increases upkeep. The remaining slaves will be more efficient in dealing with crime.",
							"earlyWarn",
							false)
					);
				} else {
					App.UI.DOM.appendNewElement("div", z, "You have created early warning systems that constantly analyze in real time data to determine the likeness of an attack.");
				}
			}

			return z;
		}
		function situationAnalysis(state) {
			const isSecurity = state === "security";
			const variable = isSecurity ? "security" : "crimeLow";
			const colour = isSecurity ? "deepskyblue" : "orangered";
			let text = [];

			const r = new DocumentFragment();
			r.append(`Your ${state} level (`, App.UI.DOM.makeElement("span", `${V.SecExp.core[variable]}`, colour), `)`);
			text.push(" ");
			if (V.SecExp.core[variable] <= 20) {
				text.push(`is ${isSecurity ? "dangerously" : "very"} low.`);
			} else if (V.SecExp.core[variable] <= 40) {
				text.push("is low.");
			} else if (V.SecExp.core[variable] <= 60) {
				text.push(`is ${isSecurity ? "decent" : "average"}.`);
			} else if (V.SecExp.core[variable] <= 80) {
				text.push(`is ${isSecurity ? "good" : "high"}.`);
			} else {
				text.push(`is ${isSecurity ? "great" : "extremely high"}.`);
			}
			text.push("Considering the current upgrades the");
			if (isSecurity) {
				text.push(`resting level for security is ${Math.trunc(App.Mods.SecExp.Check.secRestPoint() * (Math.clamp(V.SecExp.buildings.secHub.menials, 0, App.Mods.SecExp.Check.reqMenials()) / App.Mods.SecExp.Check.reqMenials()))}, `);
				text.push(`while the effective maximum level is ${Math.trunc(App.Mods.SecExp.Check.reqMenials() * (Math.clamp(V.SecExp.buildings.secHub.menials, 0, App.Mods.SecExp.Check.reqMenials()) / App.Mods.SecExp.Check.reqMenials()))}.`);
			} else {
				text.push(`maximum level of crime is ${App.Mods.SecExp.Check.crimeCap()}, `);
				text.push(`while the effective maximum level is ${Math.trunc(Math.clamp(App.Mods.SecExp.Check.crimeCap() + (App.Mods.SecExp.Check.crimeCap() - App.Mods.SecExp.Check.crimeCap() * (V.SecExp.buildings.secHub.menials / App.Mods.SecExp.Check.reqMenials())), 0, 100))}.`);
			}
			r.append(text.join(" "));

			return r;
		}
		function checkStatus(value, authority) {
			return V.SecExp.buildings.secHub.coldstorage === value && V.SecExp.core.authority >= authority && App.Mods.SecExp.Check.reqMenials() > 10;
		}
		function makeLink(text, price, note, type, applyHacking=true) {
			const r = new DocumentFragment();
			r.append(App.UI.DOM.link(text,
				() => {
					cashX(-getCost(), "capEx");
					if (applyHacking) {
						V.PC.skill.hacking++;
					}
					switch (type) {
						case "coldstorage":
							V.SecExp.buildings.secHub.coldstorage++;
							break;
						case "nanoCams":
						case "cyberBots":
						case "eyeScan":
						case "cryptoAnalyzer":
							V.SecExp.buildings.secHub.upgrades.security[type] = 1;
							break;
						case "advForensic":
						case "autoArchive":
						case "autoTrial":
						case "worldProfiler":
							V.SecExp.buildings.secHub.upgrades.crime[type] = 1;
							break;
						case "sensors":
						case "signalIntercept":
						case "radar":
							V.SecExp.buildings.secHub.upgrades.intel[type] = 1;
							break;
						case "pathways":
						case "rapidVehicles":
						case "rapidPlatforms":
						case "earlyWarn":
							V.SecExp.buildings.secHub.upgrades.readiness[type] = 1;
							break;
					}
					App.UI.reload();
				},
			));
			r.append(App.UI.DOM.makeElement("div", `Costs ${cashFormat(getCost())}. ${note}`, "note"));
			return r;

			function getCost() {
				const HistoryDiscount = ["mercenary", "gang", "slaver"].includes(V.PC.career) ? 0.5 : 1;
				return Math.trunc(price * V.upgradeMultiplierArcology * HistoryDiscount * (applyHacking ? V.HackingSkillMultiplier : 1));
			}
		}
	}
})();


code:
App.Mods.SecExp.transportHub = (function() {
	return {
		Init,
		GUI
	};

	function Init() {
		V.SecExp.buildings.transportHub = {
			airport: 1,
			security: 1,
			surfaceTransport: 1,
		};
	}
	function GUI() {
		const frag = new DocumentFragment();
		V.nextButton = "Back";
		V.nextLink = "Main";
		frag.append(
			intro(),
			trade(),
			upgrades(),
		);
		return frag;

		function intro() {
			const div = document.createElement("div");
			const text = [];

			text.push(`You quickly reach the transport hub, where a constant stream of vehicles, people and goods greets you. Part of the structure is dedicated to air travel and the other is mainly occupied by the ${V.terrain !== "oceanic" && V.terrain !== "marine" ? `monorail station` : `docks`}.`);

			if (V.SecExp.edicts.limitImmigration || V.policies.immigrationRep === -1) {
				text.push(`Due to your strict policies concerning immigration, very few new citizens arrive in the transport hub.`);
			} else if (V.SecExp.edicts.openBorders || V.policies.immigrationCash) {
				text.push(`Due to your liberal policies concerning immigration, the transport hub is filled with a flow of new citizens.`);
			}

			App.Events.addNode(div, text, "div", ['scene-intro']);
			App.UI.DOM.appendNewElement("div", div, App.UI.DOM.passageLink(`Decommission the Transport Hub`, "Main", () => {
				delete V.SecExp.buildings.transportHub;

				App.Arcology.cellUpgrade(V.building, App.Arcology.Cell.Market, "Transport Hub", "Markets");
			}), ['indent']);
			return div;
		}

		function trade() {
			const div = document.createElement("div");
			const text = [];

			App.UI.DOM.appendNewElement("h2", div, `Trade`);
			if (V.SecExp.core.trade <= 20) {
				text.push(`Trade is <span class="red">almost non-existent.</span> Outside the supplies for the arcology's domestic consumption little else crosses the territory of the free city.`);
			} else if (V.SecExp.core.trade <= 40) {
				text.push(`Trade is <span class="orange">low.</span> There's some but limited commercial activity crossing the territory of the free city.`);
			} else if (V.SecExp.core.trade <= 60) {
				text.push(`Trade is at <span class="yellow">positive levels.</span> There's a good amount commercial activity outside the supplies for the arcology's domestic consumption.`);
			} else if (V.SecExp.core.trade <= 80) {
				text.push(`Trade is at <span class="limegreen">high levels.</span> There's a lot of commercial activity outside the supplies for the arcology's domestic consumption.`);
			} else {
				text.push(`Trade is at <span class="green">extremely high levels.</span> There's a constant stream of commercial activity crossing the arcology.`);
			}
			App.Events.addNode(div, text);
			return div;
		}

		function upgrades() {
			const div = document.createElement("div");
			const price = cost => Math.trunc(cost * V.upgradeMultiplierArcology);
			App.UI.DOM.appendNewElement("h2", div, `Upgrades`);
			div.append(
				airport(),
				V.terrain !== "oceanic" && V.terrain !== "marine"
					? land()
					: sea(),
				security(),
			);
			return div;

			function airport() {
				const div = document.createElement("div");
				const text = [];
				const links = [];

				if (V.SecExp.buildings.transportHub.airport === 1) {
					text.push(`The arcology's airport is relatively small and poorly equipped. It can handle some traffic, but nothing noteworthy.`);
					links.push(App.UI.DOM.link(`Modernize the airport`, () => {
						V.SecExp.buildings.transportHub.airport = 2;
						cashX(forceNeg(price(5000)), "capEx");

						App.UI.reload();
					}, [], '', `Costs ${cashFormat(price(5000))} and will increase trade, but will affect security.`));
				} else if (V.SecExp.buildings.transportHub.airport === 2) {
					text.push(`The arcology's airport is relatively small, but fairly well equipped. It can handle some traffic, but nothing too serious.`);
					links.push(App.UI.DOM.link(`Enlarge the airport`, () => {
						V.SecExp.buildings.transportHub.airport = 3;
						cashX(forceNeg(price(15000)), "capEx");

						App.UI.reload();
					}, [], '', `Costs ${cashFormat(price(15000))} and will increase trade, but will affect security.`));
				} else if (V.SecExp.buildings.transportHub.airport === 3) {
					text.push(`The arcology's airport is good sized and well equipped. It can handle a good amount of traffic.`);
					links.push(App.UI.DOM.link(`Further modernize the airport`, () => {
						V.SecExp.buildings.transportHub.airport = 4;
						cashX(forceNeg(price(45000)), "capEx");

						App.UI.reload();
					}, [], '', `Costs ${cashFormat(price(45000))} and will increase trade, but will affect security.`));
				} else if (V.SecExp.buildings.transportHub.airport === 4) {
					links.push(App.UI.DOM.link(`Further enlarge the airport`, () => {
						V.SecExp.buildings.transportHub.airport = 5;
						cashX(forceNeg(price(85000)), "capEx");

						App.UI.reload();
					}, [], '', `Costs ${cashFormat(price(85000))} and will increase trade, but will affect security.`));
					text.push(`The arcology's airport is good sized and very well equipped. It can handle a lot of traffic.`);
				} else {
					text.push(`The arcology's airport is huge and very well equipped. It can handle an impressive amount of traffic.`);
				}

				App.Events.addNode(div, text);
				App.UI.DOM.appendNewElement("div", div, App.UI.DOM.generateLinksStrip(links), ['indent']);
				return div;
			}

			function land() {
				const div = document.createElement("div");
				const text = [];
				const links = [];

				if (V.SecExp.buildings.transportHub.surfaceTransport === 1) {
					text.push(`The railway network is old and limited. It can handle some traffic, but not sustain commercial activity.`);
					links.push(App.UI.DOM.link(`Modernize the railway`, () => {
						V.SecExp.buildings.transportHub.surfaceTransport = 2;
						cashX(forceNeg(price(10000)), "capEx");

						App.UI.reload();
					}, [], '', `Costs ${cashFormat(price(10000))} and will increase trade, but will affect security.`));
				} else if (V.SecExp.buildings.transportHub.surfaceTransport === 2) {
					text.push(`The railway network is modern and efficient, but limited in reach. It can handle some traffic, but not sustain commercial activity of any significant size.`);
					links.push(App.UI.DOM.link(`Enlarge the railway`, () => {
						V.SecExp.buildings.transportHub.surfaceTransport = 3;
						cashX(forceNeg(price(25000)), "capEx");

						App.UI.reload();
					}, [], '', `Costs ${cashFormat(price(25000))} and will increase trade, but will affect security.`));
				} else if (V.SecExp.buildings.transportHub.surfaceTransport === 3) {
					text.push(`The railway network is modern, efficient and expansive. It can handle a significant amount of traffic.`);
					links.push(App.UI.DOM.link(`Further modernize the railway`, () => {
						V.SecExp.buildings.transportHub.surfaceTransport = 4;
						cashX(forceNeg(price(65000)), "capEx");

						App.UI.reload();
					}, [], '', `Costs ${cashFormat(price(65000))} and will increase trade, but will affect security.`));
				} else {
					text.push(`The railway network is high tech and very far reaching. It can handle an enormous amount of traffic.`);
				}

				App.Events.addNode(div, text);
				App.UI.DOM.appendNewElement("div", div, App.UI.DOM.generateLinksStrip(links), ['indent']);
				return div;
			}

			function sea() {
				const div = document.createElement("div");
				const text = [];
				const links = [];

				if (V.SecExp.buildings.transportHub.surfaceTransport === 1) {
					text.push(`The docks are old and small. They can handle some traffic, but not sustain commercial activity.`);
					links.push(App.UI.DOM.link(`Modernize the docks`, () => {
						V.SecExp.buildings.transportHub.surfaceTransport = 2;
						cashX(forceNeg(price(10000)), "capEx");

						App.UI.reload();
					}, [], '', `Costs ${cashFormat(price(10000))} and will increase trade, but will affect security.`));
				} else if (V.SecExp.buildings.transportHub.surfaceTransport === 2) {
					text.push(`The docks are modern and efficient, but limited in size. They can handle some traffic, but not sustain commercial activity of significant size.`);
					links.push(App.UI.DOM.link(`Enlarge the docks`, () => {
						V.SecExp.buildings.transportHub.surfaceTransport = 3;
						cashX(forceNeg(price(25000)), "capEx");

						App.UI.reload();
					}, [], '', `Costs ${cashFormat(price(25000))} and will increase trade, but will affect security.`));
				} else if (V.SecExp.buildings.transportHub.surfaceTransport === 3) {
					text.push(`The docks are modern, efficient and expansive. They can handle a significant amount of traffic.`);
					links.push(App.UI.DOM.link(`Further modernize the docks`, () => {
						V.SecExp.buildings.transportHub.surfaceTransport = 4;
						cashX(forceNeg(price(65000)), "capEx");

						App.UI.reload();
					}, [], '', `Costs ${cashFormat(price(65000))} and will increase trade, but will affect security.`));
				} else {
					text.push(`The docks are huge in size and high tech. They can handle an enormous amount of traffic.`);
				}

				App.Events.addNode(div, text);
				App.UI.DOM.appendNewElement("div", div, App.UI.DOM.generateLinksStrip(links), ['indent']);
				return div;
			}

			function security() {
				const div = document.createElement("div");
				const text = [];
				const links = [];

				if (V.SecExp.buildings.transportHub.security === 1) {
					text.push(`The security of the hub is limited to a few cameras and the occasional guard.`);
					links.push(App.UI.DOM.link(`Expand and modernize the surveillance system`, () => {
						V.SecExp.buildings.transportHub.security = 2;
						cashX(forceNeg(price(15000)), "capEx");

						App.UI.reload();
					}, [], '', `Costs ${cashFormat(price(15000))}, increases upkeep costs, and will increase security.`));
				} else if (V.SecExp.buildings.transportHub.security === 2) {
					text.push(`The security of the hub is guaranteed by a powerful camera surveillance system.`);
					links.push(App.UI.DOM.link(`Establish a rapid response team`, () => {
						V.SecExp.buildings.transportHub.security = 3;
						cashX(forceNeg(price(35000)), "capEx");

						App.UI.reload();
					}, [], '', `Costs ${cashFormat(price(35000))}, increases upkeep costs, and will increase security.`));
				} else if (V.SecExp.buildings.transportHub.security === 3) {
					text.push(`The security of the hub is guaranteed by a powerful camera surveillance system and a rapid response team constantly patrolling the structure.`);
					links.push(App.UI.DOM.link(`Add additional security drones to the structure`, () => {
						V.SecExp.buildings.transportHub.security = 4;
						cashX(forceNeg(price(55000)), "capEx");

						App.UI.reload();
					}, [], '', `Costs ${cashFormat(price(55000))}, increases upkeep costs, and will increase security.`));
				} else {
					text.push(`The security of the hub is guaranteed by a powerful camera surveillance system, a rapid response team constantly patrolling the building and additional security drones making the rounds around the exterior.`);
				}

				App.Events.addNode(div, text);
				App.UI.DOM.appendNewElement("div", div, App.UI.DOM.generateLinksStrip(links), ['indent']);
				return div;
			}
		}
	}
})();


code:
App.Mods.SecExp.weapManu = (function() {
	return {
		Init,
		baseTime,
		current,
		completed,
		GUI,
		// purchase - helper function
	};

	function Init() {
		V.SecExp.buildings.weapManu = {
			space: 500,
			menials: 0,
			productivity: 1,
			lab: 1,
			sellTo: {
				citizen: 1,
				raiders: 1,
				oldWorld: 1,
				FC: 1,
			},
			upgrades: {completed: []}
		};
	}

	/** Weeks to completion without any modification.
	 * @returns {number}
	 */
	function baseTime() { return 10; }

	/** Checks the supplied ID value and assigns values.
	 * @param {number} [upgradeID] passed ID
	 * @returns {object}
	 */
	function current(upgradeID) {
		switch (upgradeID) {
			case -3:
				return {
					dec: "advanced synthetic alloys", type: "hp",
					purpose: "survivability", cost: 10000*V.HackingSkillMultiplier,
					unit: "the security drones"
				};
			case -2:
				return {
					dec: "adaptive armored frames", type: "defense",
					purpose: "defensive capabilities", cost: 10000,
					unit: "the security drones"
				};
			case -1:
				return {
					dec: "dynamic battle aware AI", type: "attack",
					purpose: "attack power", cost: 30000,
					unit: "the security drones"
				};
			case 0:
				return {
					dec: "magnetic based ballistic weaponry", type: "attack",
					purpose: "attack power", cost: 30000,
					unit: "our human troops"
				};
			case 1:
				return {
					dec: "ceramo-metallic alloys", type: "defense",
					purpose: "defensive capabilities", cost: 30000,
					unit: "our human troops"
				};
			case 2:
				return {
					dec: "rapid action stimulants", type: "hp",
					purpose: "survivability", cost: 60000,
					unit: "our human troops"
				};
			case 3:
				return {
					dec: "fast response neural stimulant", type: "morale",
					purpose: "standing power", cost: 60000,
					unit: "our human troops"
				};
			case 4:
				return {
					dec: "universal cyber enhancements", type: "attack and defense",
					purpose: "offensive and defensive effectiveness", cost: 120000*V.HackingSkillMultiplier,
					unit: "our human troops"
				};
			case 5:
				return {
					dec: "remote neural links", type: "hp and morale",
					purpose: "morale and survivability", cost: 120000*V.HackingSkillMultiplier,
					unit: "our human troops"
				};
			case 6:
				return {
					dec: `combined training regimens with ${capFirstChar(V.SF.Lower)}`, type: "attack and defense",
					purpose: "offensive and defensive effectiveness", cost: 0,
					unit: "our human troops"
				};
			case 7:
				return {
					dec: `a variant of the stimulant cocktail that ${capFirstChar(V.SF.Lower)} created`, type: "hp and morale",
					purpose: "morale and survivability", cost: 300000,
					unit: "our human troops"
				};
			case 8:
				return {
					dec: `a mesh network based off the custom network of ${capFirstChar(V.SF.Lower)}`, type: "all",
					purpose: "offensive,defensive effectiveness in addition to morale and survivability", cost: 1000000*V.HackingSkillMultiplier,
					unit: "our human troops"
				};
		}
	}

	/** Checks if the class of unit is fully upgraded.
	 * @returns {boolean}
	 */
	 function completed(check = "all") {
		let human = [0, 1, 2, 3, 4, 5];
		if (V.SF.Toggle && V.SF.Active >= 1) {
			human.push(6, 7, 8);
		}

		if (check === "human") {
			return V.SecExp.buildings.weapManu.upgrades.completed.includesAll(human);
		} else if (check === "bots") {
			return V.SecExp.buildings.weapManu.upgrades.completed.includesAll(-1, -2, -3);
		}
		return V.SecExp.buildings.weapManu.upgrades.completed.includesAll(human.concat(-1, -2, -3));
	}

	function GUI() {
		const frag = new DocumentFragment();

		V.nextButton = "Back";
		V.nextLink = "Main";
		const refreshDiv = App.UI.DOM.makeElement("div", content());

		function content() {
			const div = document.createElement("div");
			div.append(
				intro(),
				menials(),
				rules(),
				upgrades(),
				research(),
			);
			return div;
		}
		frag.append(refreshDiv);
		return frag;

		function intro() {
			const div = document.createElement("div");
			const text = [];
			const units = [];

			text.push(`This sector of the arcology has been dedicated to weapons manufacturing. These factories supply`);
			if (V.SecExp.units.militia.squads) {
				units.push(`your militia`);
			}
			if (V.SecExp.units.slaves.squads) {
				units.push(`your slave soldiers`);
			}
			if (V.mercenaries) {
				units.push(`your mercenaries`);
			}

			text.push(`${toSentence([...units, `many small old world nations`])} as the advanced technology that Free Cities have available is hard to come by otherwise.`);

			App.Events.addNode(div, text, "div", ['scene-intro']);
			App.UI.DOM.appendNewElement("div", div, App.UI.DOM.passageLink(`Decommission the Weapons Manufacturing`, "Main", () => {
				delete V.SecExp.buildings.weapManu;

				App.Arcology.cellUpgrade(V.building, App.Arcology.Cell.Manufacturing, "Weapon Manufacturing", "Manufacturing");
			}), ['indent']);

			return div;
		}

		function menials() {
			const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
			App.UI.DOM.appendNewElement("h2", div, `Menials`);
			const unitCost = Math.trunc(1000 * V.upgradeMultiplierArcology * (V.SecExp.buildings.weapManu.space/100));
			let text = [];
			// let links = [];

			// Transferring
			if (V.SecExp.buildings.weapManu.menials > 0) {
				text.push(`Assigned here ${V.SecExp.buildings.weapManu.menials === 1 ? `is` : `are`} ${numberWithPluralOne(V.SecExp.buildings.weapManu.menials, 'menial slave')}, working to produce as much equipment as they can.`);
			}
			text.push(`You ${V.menials ? `own ${num(V.menials)}` : `don't own any`} free menial slaves. This manufacturing complex is currently housing ${num(V.SecExp.buildings.weapManu.menials)} out of ${num(V.SecExp.buildings.weapManu.space)} possible menial slaves.`);
			div.append(text.join(' '));
			text = [];

			App.UI.DOM.appendNewElement("div", div, App.UI.market({menialWorkersOnly: true}), ['indent']);
			const optionsList = [1, 5, 10, 100, 500];
			let linkArray;
			for (const flow of ["in", "out"]) {
				linkArray = [];
				for (const value of optionsList.filter(s => (flow === "in" ? ((V.SecExp.buildings.weapManu.space - V.SecExp.buildings.weapManu.menials) >= s && V.menials >= s) : V.SecExp.buildings.weapManu.menials >= s) )) {
					linkArray.push(
						App.UI.DOM.link(
							`${value}`,
							() => {
								V.menials += (flow === "in" ? forceNeg(value) : value);
								V.SecExp.buildings.weapManu.menials += (flow === "in" ? value : forceNeg(value));
								App.UI.reload();
							}
						)
					);
				}
				if (linkArray.length > 0) {
					if (flow !== "in" || flow === "in" && V.SecExp.buildings.weapManu.menials < V.SecExp.buildings.weapManu.space) {
						const line = new DocumentFragment();
						line.append(`Transfer ${flow}: `, App.UI.DOM.generateLinksStrip(linkArray));
						App.UI.DOM.appendNewElement("div", div, line);
					}
				}
			}
			// FIXME: this is unused
			// if (V.SecExp.buildings.weapManu.menials) {
			// 	links.push(App.UI.DOM.link("Transfer out all menial slaves", () => {
			// 		V.menials += V.SecExp.buildings.weapManu.menials;
			// 		V.SecExp.buildings.weapManu.menials = 0;
			// 		App.UI.reload();
			// 	}));
			// }

			// Housing
			App.UI.DOM.appendNewElement("div", div, `There is enough room in the complex to build housing, enough to give an additional 100 workers a place to sleep and relax.`);
			App.UI.DOM.appendNewElement("div", div, App.UI.DOM.link(`Build a new housing unit`, () => {
				cashX(forceNeg(unitCost), "capEx");
				V.SecExp.buildings.weapManu.space += 100;
				App.UI.reload();
			},
			[], '', `Costs ${cashFormat(unitCost)} and increases housing by 100.`), ['indent']);

			return div;
		}

		function upgrades() {
			const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
			/** @type {FC.Upgrade[]} */
			const upgrades = [
				new App.Upgrade(
					"productivity",
					[
						{
							value: 1,
							upgraded: 2,
							text: `Production is completely manned by human workers. The complex has close to zero automation.`,
							link: `Invest in automating the complex`,
							cost: 10000 * V.SecExp.buildings.weapManu.productivity,
							handler: () => V.PC.skill.engineering += 0.1,
							notes: [`will increase income in addition to speeding up upgrade production`],
						},
						{
							value: 2,
							upgraded: 3,
							text: `Production is mostly handled by human workers. A few of the most tiresome tasks are handled by robots.`,
							link: `Invest in automating the complex`,
							cost: 10000 * V.SecExp.buildings.weapManu.productivity,
							handler: () => V.PC.skill.engineering += 0.1,
							notes: [`will increase income in addition to speeding up upgrade production`],
						},
						{
							value: 3,
							upgraded: 4,
							text: `A good part of production is handled by robots with humans handling the most complex tasks.`,
							link: `Invest in automating the complex`,
							cost: 10000 * V.SecExp.buildings.weapManu.productivity,
							handler: () => V.PC.skill.engineering += 0.1,
							notes: [`will increase income in addition to speeding up upgrade production`],
						},
						{
							value: 4,
							upgraded: 5,
							text: `Almost all production is handled by robots, with humans acting as support for the machines.`,
							link: `Invest in automating the complex`,
							cost: 10000 * V.SecExp.buildings.weapManu.productivity,
							handler: () => V.PC.skill.engineering += 0.1,
							notes: [`will increase income in addition to speeding up upgrade production`],
						},
						{
							value: 5,
							text: `All production here is handled by robots. The few humans working in the complex occupy themselves exclusively with management and quality assurance.`,
						},
					],
					V.SecExp.buildings.weapManu,
				),
				new App.Upgrade(
					"lab",
					[
						{
							value: 1,
							upgraded: 2,
							text: `There's a very spartan lab attached to the complex that occupies itself mainly with weapons testing and small adjustments to the manufacturing process.`,
							link: `Invest in research and development`,
							cost: 10000 * V.SecExp.buildings.weapManu.lab,
							handler: () => V.PC.skill.engineering += 0.1,
							notes: [`will increase income in addition to unlocking more advanced upgrades`],
						},
						{
							value: 2,
							upgraded: 3,
							text: `There's a lab attached to the complex. It mainly test weapons effectiveness and manufacturing efficiency, but has enough equipment and personnel to develop new technology.`,
							link: `Invest in research and development`,
							cost: 10000 * V.SecExp.buildings.weapManu.lab,
							handler: () => V.PC.skill.engineering += 0.1,
							notes: [`will increase income in addition to unlocking more advanced upgrades`],
						},
						{
							value: 3,
							text: `There's a large lab attached to the complex. The complement of equipment and personnel makes it a great beacon of military science in an otherwise ignorant world.`,
						},
					],
					V.SecExp.buildings.weapManu,
				),
			];

			App.UI.DOM.appendNewElement("h2", div, `Upgrades`);
			upgrades.forEach(upgrade => div.append(upgrade.render()));
			return div;
		}

		function rules() {
			const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
			App.UI.DOM.appendNewElement("h2", div, `Rules`);
			[
				{
					property: "citizen",
					options: [
						{
							get text() { return `We are not selling our weaponry to our citizens.`; },
							link: `Forbid`,
							value: 0,
						},
						{
							get text() { return `We are currently selling our weapons to the domestic market of the arcology.`; },
							link: `Allow`,
							value: 1,
						}
					],
					object: V.SecExp.buildings.weapManu.sellTo,
				},
				{
					property: "raiders",
					options: [
						{
							get text() { return `We are not selling our weaponry to raiders.`; },
							link: `Forbid`,
							value: 0,
						},
						{
							get text() { return `We are currently selling our weapons to various groups of outlaws, also known as raiders.`; },
							link: `Allow`,
							value: 1,
						}
					],
					object: V.SecExp.buildings.weapManu.sellTo,
				},
				{
					property: "oldWorld",
					options: [
						{
							get text() { return `We are not selling our weaponry to old world nations.`; },
							link: `Forbid`,
							value: 0,
						},
						{
							get text() { return `We are currently selling our weapons to many old world nations.`; },
							link: `Allow`,
							value: 1,
						}
					],
					object: V.SecExp.buildings.weapManu.sellTo,
				},
				{
					property: "FC",
					options: [
						{
							get text() { return `We are not selling our weaponry to other Free Cities.`; },
							link: `Forbid`,
							value: 0,
						},
						{
							get text() { return `We are currently selling our weapons to other Free Cities.`; },
							link: `Allow`,
							value: 1,
						}
					],
					object: V.SecExp.buildings.weapManu.sellTo,
				},
			].forEach(rule => {
				const options = new App.UI.OptionsGroup();
				const option = options.addOption(null, rule.property, V.SecExp.buildings.weapManu.sellTo);

				rule.options.forEach(o => {
					option.addValue(o.link, o.value);
					if (o.handler) {
						option.addCallback(o.handler);
					}
					if (o.note) {
						option.addComment(o.note);
					}

					if (_.isEqual(V.SecExp.buildings.weapManu.sellTo[rule.property], o.value)) {
						App.UI.DOM.appendNewElement("div", div, o.text);
					}
				});
				App.UI.DOM.appendNewElement("div", div, options.render(), ['indent', 'margin-bottom']);
			});
			return div;
		}

		function research() {
			const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
			const time = Math.ceil(baseTime() / V.SecExp.buildings.weapManu.productivity);
			const completedArray = V.SecExp.buildings.weapManu.upgrades.completed;

			App.UI.DOM.appendNewElement("h2", div, `Research`);
			div.append(`With our current industrial and research capabilities, upgrades will be finished in ${time} weeks.`);
			if (completed()) {
				delete V.SecExp.buildings.weapManu.upgrades.queue;
			} else {
				V.SecExp.buildings.weapManu.upgrades.queue = V.SecExp.buildings.weapManu.upgrades.queue || [];
				if (V.SecExp.buildings.weapManu.lab < 3) {
					div.append(`Upgrade the research facility further to unlock additional upgrades.`);
				}
			}

			App.UI.DOM.appendNewElement("h3", div, `Security Drones`);
			if (completed("bots")) {
				div.append(`You have fully upgraded the security drones.`);
			} else {
				div.append(purchase(-1));
				if (V.SecExp.buildings.weapManu.lab > 1) {
					div.append(purchase(-2));
				}
				if (V.SecExp.buildings.weapManu.lab > 2) {
					div.append(purchase(-3));
				}
			}

			App.UI.DOM.appendNewElement("h3", div, `Troops`);
			if (V.SF.Toggle && V.SF.Active >= 1 &&
				(App.Mods.SecExp.getAppliedUpgrades('human').attack >= 4 ||
					App.Mods.SecExp.getAppliedUpgrades('human').hp >= 4 ||
					App.Mods.SecExp.getAppliedUpgrades('human').morale >= 40 ||
					App.Mods.SecExp.getAppliedUpgrades('human').defense >= 4)) {
				div.append(`You have fully upgraded your human troops.`);
			} else if (App.Mods.SecExp.getAppliedUpgrades('human').attack >= 2 ||
				App.Mods.SecExp.getAppliedUpgrades('human').hp >= 2 ||
				App.Mods.SecExp.getAppliedUpgrades('human').morale >= 20 ||
				App.Mods.SecExp.getAppliedUpgrades('human').defense >= 2) {
				if (V.SF.Toggle && V.SF.Active >= 1) {
					const reasons = [];
					if (V.SF.Squad.Drugs < 8) {
						reasons.push(`the drug lab needs more advanced equipment`);
					}
					if (V.SecExp.edicts.SFSupportLevel < 2 || V.SecExp.edicts.SFSupportLevel < 4 || V.SecExp.edicts.SFSupportLevel < 5) {
						reasons.push(`you need to pass higher SF support edicts`);
					}
					if (V.SF.Squad.Firebase < 7) {
						reasons.push(`the Firebase need additional expansion(s)`);
					}

					div.append(`With support from ${V.SF.Lower}, we may be able to further upgrade our troops.`);
					if (reasons.length > 0) {
						div.append(`The Colonel says ${toSentence(reasons)}.`);
					}
				} else {
					div.append(`You have fully upgraded your human troops.`);
				}
			}

			div.append(purchase(0));
			div.append(purchase(1));
			if (V.SecExp.buildings.weapManu.lab > 1) {
				div.append(purchase(2));
				div.append(purchase(3));
			}
			if (V.SecExp.buildings.weapManu.lab > 2) {
				div.append(purchase(4));
				div.append(purchase(5));
			}

			if (V.SF.Toggle && V.SF.Active > 0) {
				if (V.SecExp.buildings.weapManu.lab > 1 &&
					V.SecExp.edicts.SFSupportLevel > 1 &&
					V.SF.Squad.Firebase > 6) {
					div.append(purchase(6));
				}
				if (V.SecExp.buildings.weapManu.lab > 1 &&
					V.SecExp.edicts.SFSupportLevel > 3 &&
					V.SF.Squad.Firebase > 7) {
					div.append(purchase(7));
				}
				if (V.SecExp.buildings.weapManu.lab > 2 &&
					V.SecExp.edicts.SFSupportLevel > 4) {
					div.append(purchase(8));
				}
			}

			if (V.SecExp.buildings.weapManu.upgrades.queue) {
				App.Events.addParagraph(div, []);
				for (let i = 0; i < V.SecExp.buildings.weapManu.upgrades.queue.length; i++) {
					const upgrade = V.SecExp.buildings.weapManu.upgrades.queue[i];
					const latest = current(upgrade.ID);
					if (i === 0) {
						div.append(`Currently developing`);
					} else {
						div.append(`${ordinalSuffix(i + 1)} in queue:`);
					}
					div.append(` ${latest.dec} for ${latest.unit}. It will enhance their ${latest.purpose}. Estimated completion time is ${numberWithPluralOne(upgrade.time, "week")}.`);
					App.UI.DOM.appendNewElement("div", div);
				}
			}

			if (completedArray.length) {
				App.UI.DOM.appendNewElement("div", div, `You have completed the following projects: ${toSentence(completedArray.map(u => current(u).dec))}.`, ['margin-top']);
			}
			return div;
		}
	}

	/** Prints a line that allows a user to purchase an upgrade.
	 * helper function, not callable externally
	 * @param {number} [upgradeID] ID value to when generating.
	 * @returns {Node}
	 */
	 function purchase(upgradeID) {
		let el = document.createElement("div");
		const found = V.SecExp.buildings.weapManu.upgrades.queue && V.SecExp.buildings.weapManu.upgrades.queue.find(s => s.ID === upgradeID);
		if (!V.SecExp.buildings.weapManu.upgrades.completed.includes(upgradeID)) {
			const item = current(upgradeID); const time = Math.ceil(baseTime() / V.SecExp.buildings.weapManu.productivity);
			if (!found) {
				el.append(App.UI.DOM.link(`Develop ${item.dec}.`, () => {
					V.SecExp.buildings.weapManu.upgrades.queue.push({ID: upgradeID, time: time});
					cashX(-item.cost, "capEx");
					App.UI.reload();
				}
				));
				el.append(` This will take ${time} weeks`);
				if (item.cost > 0) {
					el.append(`, cost ${cashFormat(item.cost)}`);
				}
				el.append(` and will increase `);
				if (item.type !== "all") {
					el.append(`the base ${item.type} value${item.type.contains("and") ? 's' : ''}`);
				} else {
					el.append('all base stats');
				}
				el.append(` of ${item.unit}.`);
			} else {
				el.append(App.UI.DOM.link(`Remove ${item.dec} from the queue`, () => {
					V.SecExp.buildings.weapManu.upgrades.queue.deleteAt(found);
					App.UI.reload();
				}
				));
			}
		}
		return el;
	}
})();