code:
App.SecExp.weapManuUpgrade = (function() {
	return {
		baseTime,
		current,
		purchase,
		fully,
	};

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

	/** Checks the supplied ID value and assigns values.
	 * @param {number} [x=null] the optional ID value to use instead of the current upgrades ID.
	 * @returns {Object}
	 */
	function current(x = null) {
		let o = {unit: "our human troops", ID: jsDef(x) ? x : V.SecExp.buildings.weapManu.upgrades.queue[0].ID};
		switch(o.ID) {
			case -3:
				Object.assign(o, {
					dec: "advanced synthetic alloys", type: "hp", unit: "the security drones",
					cost: 10000*V.HackingSkillMultiplier,
				});
				break;
			case -2:
				Object.assign(o, {
					dec: "adaptive armored frames", type: "defense", unit: "the security drones",
					cost: 10000
				});
				break;
			case -1:
				Object.assign(o, {
					dec: "dynamic battle aware AI", type: "attack", unit: "the security drones",
					cost: 30000
				});
				break;
			case 0:
				Object.assign(o, {
					dec: "magnetic based ballistic weaponry", type: "attack",
					cost: 30000
				});
				break;
			case 1:
				Object.assign(o, {
					dec: "ceramo-metallic alloys", type: "defense",
					cost: 30000
				});
				break;
			case 2:
				Object.assign(o, {
					dec: "rapid action stimulants", type: "hp",
					cost: 60000
				});
				break;
			case 3:
				Object.assign(o, {
					dec: "fast response neural stimulant", type: "morale",
					cost: 60000
				});
				break;
			case 4:
				Object.assign(o, {
					dec: "universal cyber enhancements", type: "attack and defense",
					cost: 120000*V.HackingSkillMultiplier
				});
				break;
			case 5:
				Object.assign(o, {
					dec: "remote neural links", type: "hp and morale",
					cost: 120000*V.HackingSkillMultiplier
				});
				break;
			case 6:
				Object.assign(o, {
					dec: "combined training regimens with the special force", type: "attack and defense",
					cost: 0
				});
				break;
			case 7:
				Object.assign(o, {
				dec: `a variant of the stimulant cocktail that the ${V.SF.Lower} created`, type: "hp and morale",
					cost: 300000
				});
				break;
			case 8:
				Object.assign(o, {
					dec: "a mesh network based off the custom network of the special force", type: "all",
					cost: 1000000*V.HackingSkillMultiplier
				});
				break;
		}

		switch(o.type) {
			case "hp":
				Object.assign(o, {purpose: "survivability"}); break;
			case "defense":
				Object.assign(o, {purpose: "defensive capabilities"}); break;
			case "attack":
				Object.assign(o, {purpose: "attack power"}); break;
			case "morale":
				Object.assign(o, {purpose: "standing power"}); break;
			case "attack and defense":
				Object.assign(o, {purpose: "offensive and defensive effectiveness."}); break;
			case "hp and morale":
				Object.assign(o, {purpose: "morale and survivability"}); break;
			case "all":
				Object.assign(o, {purpose: "offensive,defensive effectiveness in addition to morale and survivability"}); break;
		}
		return o;
	}

	/** Prints a line that allows a user to purchase an upgrade.
	 * @param {number} [x] ID value to use.
	 * @returns {Node}
	 */
	function purchase(x) {
		let el = document.createElement("div"), found = null;
		if (!V.SecExp.buildings.weapManu.upgrades.completed.includes(x)) {
			for (let i = 0; i < V.SecExp.buildings.weapManu.upgrades.queue.length; i++) {
				if (V.SecExp.buildings.weapManu.upgrades.queue[i].ID === x) {
					found = i; break;
				}
			}
			const item = current(x), time = Math.ceil(baseTime() / V.SecExp.buildings.weapManu.productivity);
			if (!jsDef(found)) {
				el.append(App.UI.DOM.link(`Develop ${item.dec}.`, () => {
					V.SecExp.buildings.weapManu.upgrades.queue.push({ID: x, time: time});
					cashX(-item.cost, "capEx");
				},
				[], passage()
				));
				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);
				},
				[], passage()
				));
			}
		}
		return el;
	}

	function fully() {
		const human = (V.SF.Toggle && V.SF.Active >= 1) ? [0, 1, 2, 3, 4, 5, 6, 7, 8] : [0, 1, 2, 3, 4, 5];
		return {
			human: V.SecExp.buildings.weapManu.upgrades.completed.includesAll(human),
			bots: V.SecExp.buildings.weapManu.upgrades.completed.includesAll(-1, -2, -3),
		};
	}
})();

App.SecExp.propHub = (function() {
	return {
		Init,
		BC
	};

	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 BC() {
		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;
		}
	}
})();

App.SecExp.barracks = (function() {
	return {
		Init,
		BC
	};

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

	function BC() {
		if (V.SecExp.buildings.barracks) {
			delete V.SecExp.buildings.barracks.active;
		}
		if (V.SecExp.buildings.barracks && Object.entries(V.SecExp.buildings.barracks === 0).length) {
			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;
			}
		}
	}
})();

App.SecExp.secHub = (function() {
	return {
		Init,
		BC
	};

	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 BC() {
		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;
		}
	}
})();

App.SecExp.riotCenter = (function() {
	return {
		Init,
		BC
	};

	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 BC() {
		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;
		}
	}
})();

App.SecExp.weapManu = (function() {
	return {
		Init,
		BC,
	};

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

	function BC() {
		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.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.SecExp.weapManuUpgrade.fully().bots && !App.SecExp.weapManuUpgrade.fully().human) {
				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;
			}
		}
	}
})();

App.SecExp.transportHub = (function() {
	return {
		Init,
		BC
	};

	function Init() {
		V.SecExp.buildings.transportHub = {
			airport: 1,
			security: 1,
			surfaceTransport: 1,
		};
	}

	function BC() {
		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;
				}
			}
		}
	}
})();


code:
/**
 * Returns the effect (if any) the Special Force provides.
 * @param {string} [report] which report is this function being called from.
 * @param {string} [section=''] which sub section (if any) is this function being called from.
 * @returns {{text:string, bonus:number}}
 */
App.SecExp.SF_effect = function(report, section = '') {
	const size = V.SF.Toggle && V.SF.Active >= 1 ? App.SF.upgrades.total() : 0;
	let r = ``, bonus = 0;
	if (size > 10) {
		if (report === 'authority' || report === 'trade') {
			r += `Having a powerful special force increases ${report === 'authority' ? 'your authority' : 'trade security'}.`;
			bonus += size / 10;
		} else if (report === 'security') {
			r += `Having a powerful special force attracts a lot of ${section === 'militia' ? 'citizens' : 'mercenaries'}, hopeful that they may be able to fight along side it.`;
			if (section === 'militia') {
				bonus *= 1 + (random(1, (Math.round(size / 10))) / 20); // not sure how high size goes, so I hope this makes sense
			} else if (section === 'mercs') {
				bonus += random(1, Math.round(size / 10));
			}
		}
	}
	return {text: r, bonus: bonus};
};

/**
 * Returns the effect of a campaign launched from the PR hub.
 * @param {string} [focus] campaign option to check against.
 * @returns {{text:string, effect:number}}}
 */
App.SecExp.propagandaEffects = function(focus) {
	let t = ``, increase = 0;
	if (V.secExpEnabled > 0 && V.SecExp.buildings.propHub && V.SecExp.buildings.propHub.upgrades.campaign >= 1 && V.SecExp.buildings.propHub.focus === focus) {
		let campaign, modifier;
		const forcedViewing = V.SecExp.edicts.propCampaignBoost === 1;
		const noRecruiter = V.SecExp.buildings.propHub.recruiterOffice === 0 || V.RecruiterID === 0;
		const recruiterActive = V.SecExp.buildings.propHub.recruiterOffice && V.RecruiterID > 0;
		switch (focus) {
			case "social engineering":
				campaign = 'societal engineering';
				modifier = forcedViewing ? V.SecExp.buildings.propHub.upgrades.campaign : 1;
				if (noRecruiter) {
					increase += (forcedViewing ? 2 : 1) * modifier;
				} else if (recruiterActive) {
					increase += modifier + Math.floor((S.Recruiter.intelligence + S.Recruiter.intelligenceImplant) / 32);
				}
				break;
			case "recruitment":
				campaign = 'militia recruitment';
				modifier = forcedViewing ? 0.2 : 0.15;
				if (noRecruiter) {
					increase += modifier + (forcedViewing ? 0.1 : 0.05);
				} else if (recruiterActive) {
					increase += modifier + Math.floor((S.Recruiter.intelligence + S.Recruiter.intelligenceImplant) / 650);
				}
				break;
			case "immigration":
				modifier = forcedViewing ? V.SecExp.buildings.propHub.upgrades.campaign : 1;
				if (noRecruiter) {
					increase += (forcedViewing ? random(1, 4) : random(1, 2)) * modifier;
				} else if (recruiterActive) {
					increase += modifier + Math.floor((S.Recruiter.intelligence + S.Recruiter.intelligenceImplant) / 16);
				}
				t = `Your advertisement campaign outside the free city brings more people to the gates of your arcology`;
				break;
			case "enslavement":
				modifier = forcedViewing ? V.SecExp.buildings.propHub.upgrades.campaign : 1;
				if (noRecruiter) {
					increase += (forcedViewing ? random(0, 4) : random(0, 2)) * modifier;
				} else if (recruiterActive) {
					increase += modifier + Math.floor((S.Recruiter.intelligence + S.Recruiter.intelligenceImplant) / 16);
				}
				t = `Many were attracted by your advertisement campaigns.`;
				break;
		}

		if (focus === "social engineering" || focus === "recruitment") {
			t += `<span class='green'>Your propaganda campaign helps further your ${campaign} efforts.`;
			if (recruiterActive) {
				t += ` <span class='slave-name'>${SlaveFullName(S.Recruiter)}</span> is boosting your ${campaign} campaign.`;
			}
			t += `</span>`;
		}
	}
	return {text: t, effect: Math.round(increase)};
};

/**
 * Returns the raw percentage of society that can be drafted.
 * @returns {number}
 */
App.SecExp.militiaCap = function(x = 0) {
	x = x || V.SecExp.edicts.defense.militia;
	if (x === 2) {
		return 0.02;
	} else if (x === 3) {
		return 0.05;
	} else if (x === 4) {
		return 0.1;
	} else if (x === 5) {
		return 0.2;
	}
};

App.SecExp.initTrade = function() {
	if (V.SecExp.core.trade === 0 || !jsDef(V.SecExp.core.trade)) {
		let init = jsRandom(20, 30);
		if (V.terrain === "urban") {
			init += jsRandom(10, 10);
		} else if (V.terrain === "ravine") {
			init -= jsRandom(5, 5);
		}
		if (["BlackHat", "capitalist", "celebrity", "wealth"].includes(V.PC.career)) {
			init += jsRandom(5, 5);
		} else if (["escort", "gang", "servant"].includes(V.PC.career)) {
			init -= jsRandom(5, 5);
		}
		V.SecExp.core.trade = init;
	}
};

App.SecExp.generalInit = function() {
	if (V.secExpEnabled === 0) {
		return;
	}

	Object.assign(V.SecExp, {
		battles: {
			major: 0,
			slaveVictories: [],
			lastSelection: [],
			victories: 0,
			victoryStreak: 0,
			losses: 0,
			lossStreak: 0,
			lastEncounterWeeks: 0,
			saved: {}
		},
		rebellions: {
			tension: 0,
			slaveProgress: 0,
			citizenProgress: 0,
			victories: 0,
			losses: 0,
			lastEncounterWeeks: 0
		},
		core: {
			trade: 0,
			authority: 0,
			security: 100,
			crimeLow: 30,
			totalKills: 0,
		},
		settings: {
			difficulty: 1,
			unitDescriptions: 0,
			battle: {
				enabled: 1,
				allowSlavePrestige: 1,
				force: 0,
				showStats: 0,
				frequency: 1,
				major: {
					enabled: 0,
					gameOver: 1,
					mult: 1,
					force: 0
				}
			},
			rebellion: {
				enabled: 1,
				force: 0,
				gameOver: 1,
				speed: 1
			}
		},
		buildings: {},
		proclamation: {
			cooldown: 0,
			currency: "",
			type: "crime"
		},
		/*
		repairTime: {
			waterway: 0,
			assistant: 0,
			reactor: 0,
			arc: 0
		},
		units: {
			bots: {},
			slaves: {
				created: 0,
				casualties: 0,
				squads: []
			},
			militia: {
				created: 0,
				free: 0,
				casualties: 0,
				squads: []
			},
			mercs: {
				created: 0,
				free: 0,
				casualties: 0,
				squads: []
			}
		},
		*/
		edicts: {
			alternativeRents: 0,
			enslavementRights: 0,
			sellData: 0,
			propCampaignBoost: 0,
			tradeLegalAid: 0,
			taxTrade: 0,
			slaveWatch: 0,
			subsidyChurch: 0,
			SFSupportLevel: 0,
			limitImmigration: 0,
			openBorders: 0,
			weaponsLaw: 3,
			defense: {
				soldierWages: 1,
				slavesOfficers: 0,
				discountMercenaries: 0,
				militia: 0,
				militaryExemption: 0,
				noSubhumansInArmy: 0,
				pregExemption: 0,
				liveTargets: 0,
				privilege: {
					militiaSoldier: 0,
					slaveSoldier: 0,
					mercSoldier: 0,
				},
				// Soldiers
				martialSchool: 0,
				eliteOfficers: 0,
				lowerRequirements: 0,
				// FS soldiers
				legionTradition: 0,
				eagleWarriors: 0,
				ronin: 0,
				sunTzu: 0,
				mamluks: 0,
				pharaonTradition: 0,
			}
		},
		smilingMan: {progress: 0},
		defaultNames: {
			slaves: "slave platoon",
			militia: "citizens' platoon",
			mercs: "mercenary platoon"
		}
	});

	App.SecExp.initTrade();
};

App.SecExp.upkeep = (function() {
	return {
		edictsCash,
		edictsAuth,
		SF,
		buildings
	};

	/** Upkeep cost of edicts, in cash
	 * @returns {number}
	 */
	function edictsCash() {
		let value = 0;
		if (V.SecExp.edicts.slaveWatch) { value++; }
		if (V.SecExp.edicts.subsidyChurch) { value++; }
		if (V.SecExp.edicts.tradeLegalAid) { value++; }
		if (V.SecExp.edicts.propCampaignBoost) { value++; }

		if (V.SecExp.edicts.defense.martialSchool) { value++; }

		if (V.SecExp.edicts.defense.legionTradition) { value++; }
		if (V.SecExp.edicts.defense.pharaonTradition) { value++; }
		if (V.SecExp.edicts.defense.eagleWarriors) { value++; }
		if (V.SecExp.edicts.defense.ronin) { value++; }
		if (V.SecExp.edicts.defense.mamluks) { value++; }
		if (V.SecExp.edicts.defense.sunTzu) { value++; }

		return value * 1000;
	}

	/** Upkeep cost of edicts, in authority
	 * @returns {number}
	 */
	function edictsAuth() {
		let value = 0;
		if (V.SecExp.edicts.enslavementRights > 0) {
			value += 10;
		}
		if (V.SecExp.edicts.sellData === 1) {
			value += 10;
		}
		if (V.SecExp.edicts.defense.privilege.slaveSoldier === 1) {
			value += 10;
		}
		if (V.SecExp.edicts.weaponsLaw === 0) {
			value += 30;
		} else if (V.SecExp.edicts.weaponsLaw === 1) {
			value += 20;
		} else if (V.SecExp.edicts.weaponsLaw === 2) {
			value += 10;
		}
		if (V.SecExp.edicts.defense.slavesOfficers === 1) {
			value += 10;
		}
		return value;
	}

	/** Upkeep cost of Special Forces (why is this here? who knows!)
	 * @returns {number}
	 */
	function SF() {
		let value = 0;
		if (V.SecExp.edicts.SFSupportLevel >= 1) {
			value += 1000;
		}
		if (V.SecExp.edicts.SFSupportLevel >= 2) {
			value += 2000;
		}
		if (V.SecExp.edicts.SFSupportLevel >= 3) {
			value += 3000;
		}
		if (V.SecExp.edicts.SFSupportLevel >= 4) {
			value += 3000;
		}
		if (V.SecExp.edicts.SFSupportLevel >= 5) {
			value += 4000;
		}
		return value;
	}

	/** Upkeep cost of buildings (in cash)
	 * @returns {number}
	 */
	function buildings() {
		let value = 0;
		const base = V.facilityCost * 5, upgrade = 50;
		if (V.SecExp.buildings.propHub) {
			value += base + upgrade * Object.values(V.SecExp.buildings.propHub.upgrades).reduce((a, b) => a + b);
		}
		if (V.SecExp.buildings.secHub) {
			value += base + 20 * V.SecExp.buildings.secHub.menials;
			value += upgrade * Object.values(V.SecExp.buildings.secHub.upgrades.security).reduce((a, b) => a + b);
			value += upgrade * Object.values(V.SecExp.buildings.secHub.upgrades.crime).reduce((a, b) => a + b);
			value += upgrade * Object.values(V.SecExp.buildings.secHub.upgrades.readiness).reduce((a, b) => a + b);
			value += upgrade * Object.values(V.SecExp.buildings.secHub.upgrades.intel).reduce((a, b) => a + b);
			value += V.SecExp.edicts.SFSupportLevel >= 5 ? 1000 : 0;
		}
		if (V.SecExp.buildings.barracks) {
			value += base + upgrade * Object.values(V.SecExp.buildings.barracks).reduce((a, b) => a + b);
		}
		if (V.SecExp.buildings.riotCenter) {
			value += base + upgrade * Object.values(V.SecExp.buildings.riotCenter.upgrades).reduce((a, b) => a + b);
			if (V.SecExp.buildings.riotCenter.brainImplant < 106 && V.SecExp.buildings.riotCenter.brainImplantProject > 0) {
				value += 5000 * V.SecExp.buildings.riotCenter.brainImplantProject;
			}
			if (V.SF.Toggle && V.SF.Active >= 1 && V.SecExp.rebellions.sfArmor) {
				value += 15000;
			}
		}
		return value;
	}
})();

App.SecExp.battle = (function() {
	"use strict";
	return {
		deployedUnits,
		troopCount,
		deploySpeed,
		deployableUnits,
		activeUnits,
		maxUnits,
		recon,
		bribeCost,
	};

	/** Get count of deployed/active units for a particular battle
	 * @param {string} [input] unit type to measure; if omitted, count all types
	 * @returns {number} unit count
	 */
	function deployedUnits(input = '') {
		let bots = 0, militiaC = 0, slavesC = 0, mercsC = 0, init = 0;
		if (V.slaveRebellion !== 1 && V.citizenRebellion !== 1) { // attack
			if (V.secBots.isDeployed > 0) {
				bots++;
			}
			if (V.SF.Toggle && V.SF.Active >= 1 && V.SFIntervention) {
				init++;
			}

			militiaC += V.militiaUnits.filter((u) => u.isDeployed === 1).length;
			slavesC += V.slaveUnits.filter((u) => u.isDeployed === 1).length;
			mercsC += V.mercUnits.filter((u) => u.isDeployed === 1).length;
		} else { // rebellion
			if (V.secBots.active > 0) {
				bots++;
			}
			if (V.SF.Toggle && V.SF.Active >= 1) {
				init++;
			}
			if (V.irregulars > 0) {
				militiaC++;
			}

			militiaC += V.militiaUnits.filter((u) => u.active === 1 && !V.rebellingID.includes(u.ID)).length;
			slavesC += V.slaveUnits.filter((u) => u.active === 1 && !V.rebellingID.includes(u.ID)).length;
			mercsC += V.mercUnits.filter((u) => u.active === 1 && !V.rebellingID.includes(u.ID)).length;
		}

		if (input === '') {
			return bots + militiaC + slavesC + mercsC + init;
		} else if (input === 'bots') {
			return bots;
		} else if (input === 'militia') {
			return militiaC;
		} else if (input === 'slaves') {
			return slavesC;
		} else if (input === 'mercs') {
			return mercsC;
		}
	}

	/** Get total troop count of deployed/active units for a particular battle
	 * @returns {number} troop count
	 */
	function troopCount() {
		let troops = 0;

		/** @param {function(FC.SecExp.PlayerHumanUnitData) : boolean} pred */
		function countHumanTroops(pred) {
			const arrays = [V.militiaUnits, V.slaveUnits, V.mercUnits];
			for (const arr of arrays) {
				for (const unit of arr) {
					if (pred(unit)) {
						troops += unit.troops;
					}
				}
			}
		}

		if (V.slaveRebellion !== 1 && V.citizenRebellion !== 1) { // attack
			if (V.secBots.isDeployed === 1) {
				troops += V.secBots.troops;
			}
			countHumanTroops((u) => u.isDeployed === 1);
			if (V.SF.Toggle && V.SF.Active >= 1 && V.SFIntervention) {
				troops += App.SecExp.troopsFromSF();
			}
		} else {
			if (V.irregulars > 0) {
				troops += V.irregulars;
			}
			if (V.secBots.active === 1) {
				troops += V.secBots.troops;
			}
			countHumanTroops((u) => u.active === 1 && !V.rebellingID.includes(u.ID));
			if (V.SF.Toggle && V.SF.Active >= 1) {
				troops += App.SecExp.troopsFromSF();
			}
		}
		return troops;
	}

	/** Get mobilization readiness (in *pairs* of units) given upgrades
	 * @returns {number} readiness
	 */
	function deploySpeed() {
		let init = 1;
		if (V.SecExp.buildings.secHub) {
			if (V.SecExp.buildings.secHub.upgrades.readiness.pathways > 0) {
				init += 1;
			}
			if (V.SecExp.buildings.secHub.upgrades.readiness.rapidVehicles > 0) {
				init += 2;
			}
			if (V.SecExp.buildings.secHub.upgrades.readiness.rapidPlatforms > 0) {
				init += 2;
			}
			if (V.SecExp.buildings.secHub.upgrades.readiness.earlyWarn > 0) {
				init += 2;
			}
		}
		if (V.SF.Toggle && V.SF.Active >= 1 && V.SecExp.sectionInFirebase >= 1) {
			init += 2;
		}
		return init;
	}

	/** Get remaining deployable units (mobilization in units minus units already deployed)
	 * @returns {number}
	 */
	function deployableUnits() {
		let init = 2 * App.SecExp.battle.deploySpeed();
		if (V.secBots.isDeployed > 0) {
			init--;
		}

		const Militia = V.militiaUnits.length;
		for (let i = 0; i < Militia; i++) {
			if (V.militiaUnits[i].isDeployed > 0) {
				init--;
			}
		}

		const Slaves = V.slaveUnits.length;
		for (let i = 0; i < Slaves; i++) {
			if (V.slaveUnits[i].isDeployed > 0) {
				init--;
			}
		}

		const Mercs = V.mercUnits.length;
		for (let i = 0; i < Mercs; i++) {
			if (V.mercUnits[i].isDeployed > 0) {
				init--;
			}
		}

		return Math.max(0, init);
	}

	/** Get total active units
	 * @returns {number}
	 */
	function activeUnits() {
		return V.secBots.active + V.militiaUnits.length + V.slaveUnits.length + V.mercUnits.length;
	}

	/** Get maximum active units
	 * @returns {number}
	 */
	function maxUnits() {
		let max = 0;
		if (V.SecExp.buildings.barracks) {
			max = 8 + (V.SecExp.buildings.barracks.size * 2);
			if (App.SecExp.battle.deploySpeed() === 10) {
				max += 2;
			}
		}
		return max;
	}

	/** Get recon score (scale 0-3)
	 * @returns {number}
	 */
	function recon() {
		return V.SecExp.buildings.secHub ? Object.values(V.SecExp.buildings.secHub.upgrades.intel).reduce((a, b) => a + b) : 0;
	}

	/** Get bribe cost for an attacker to go away
	 * @returns {number}
	 */
	function bribeCost() {
		let cost; const baseBribePerAttacker = 5;
		if (V.week <= 30) {
			cost = 5000 + baseBribePerAttacker * V.attackTroops;
		} else if (V.week <= 40) {
			cost = 10000 + baseBribePerAttacker * V.attackTroops;
		} else if (V.week <= 50) {
			cost = 15000 + baseBribePerAttacker * V.attackTroops;
		} else if (V.week <= 60) {
			cost = 20000 + baseBribePerAttacker * V.attackTroops;
		} else if (V.week <= 70) {
			cost = 25000 + baseBribePerAttacker * V.attackTroops;
		} else {
			cost = 30000 + baseBribePerAttacker * V.attackTroops;
		}
		cost *= V.majorBattle > 0 ? 3 : 1;
		return Math.trunc(Math.clamp(cost, 0, 1000000));
	}
})();

App.SecExp.Check = (function() {
	"use strict";
	return {
		secRestPoint,
		crimeCap,
		reqMenials,
	};

	function secRestPoint() {
		let rest = 40;
		if (V.SecExp.buildings.secHub) {
			if (V.SecExp.buildings.secHub.upgrades.security.nanoCams === 1) {
				rest += 15;
			}
			if (V.SecExp.buildings.secHub.upgrades.security.cyberBots === 1) {
				rest += 15;
			}
			if (V.SecExp.buildings.secHub.upgrades.security.eyeScan === 1) {
				rest += 20;
			}
			if (V.SecExp.buildings.secHub.upgrades.security.cryptoAnalyzer === 1) {
				rest += 20;
			}
		}
		return rest;
	}

	function crimeCap() {
		let cap = 100;
		if (V.SecExp.buildings.secHub) {
			if (V.SecExp.buildings.secHub.upgrades.crime.autoTrial === 1) {
				cap -= 10;
			}
			if (V.SecExp.buildings.secHub.upgrades.crime.autoArchive === 1) {
				cap -= 10;
			}
			if (V.SecExp.buildings.secHub.upgrades.crime.worldProfiler === 1) {
				cap -= 15;
			}
			if (V.SecExp.buildings.secHub.upgrades.crime.advForensic === 1) {
				cap -= 15;
			}
		}
		return cap;
	}

	function reqMenials() {
		let Req = 20;
		if (V.SecExp.buildings.secHub) {
			if (V.SecExp.buildings.secHub.upgrades.security.nanoCams === 1) {
				Req += 5;
			}
			if (V.SecExp.buildings.secHub.upgrades.security.cyberBots === 1) {
				Req += 5;
			}
			if (V.SecExp.buildings.secHub.upgrades.security.eyeScan === 1) {
				Req += 10;
			}
			if (V.SecExp.buildings.secHub.upgrades.security.cryptoAnalyzer === 1) {
				Req += 10;
			}
			if (V.SecExp.buildings.secHub.upgrades.crime.autoTrial === 1) {
				Req += 5;
			}
			if (V.SecExp.buildings.secHub.upgrades.crime.autoArchive === 1) {
				Req += 5;
			}
			if (V.SecExp.buildings.secHub.upgrades.crime.worldProfiler === 1) {
				Req += 10;
			}
			if (V.SecExp.buildings.secHub.upgrades.crime.advForensic === 1) {
				Req += 10;
			}
			if (V.SecExp.buildings.secHub.upgrades.intel.sensors === 1) {
				Req += 5;
			}
			if (V.SecExp.buildings.secHub.upgrades.intel.signalIntercept === 1) {
				Req += 5;
			}
			if (V.SecExp.buildings.secHub.upgrades.intel.radar === 1) {
				Req += 10;
			}
			if (V.SecExp.buildings.secHub.upgrades.readiness.rapidVehicles === 1) {
				Req += 5;
			}
			if (V.SecExp.buildings.secHub.upgrades.readiness.rapidPlatforms === 1) {
				Req += 10;
			}
			if (V.SecExp.buildings.secHub.upgrades.readiness.earlyWarn === 1) {
				Req += 10;
			}
			Req -= 5 * V.SecExp.edicts.SFSupportLevel;
			Req -= 10 * V.SecExp.buildings.secHub.coldstorage;
		}
		return Req;
	}
})();

App.SecExp.inflictBattleWound = (function() {
	/** @typedef {object} Wound
	 * @property {number} weight
	 * @property {function(App.Entity.SlaveState):boolean} allowed
	 * @property {function(App.Entity.SlaveState):void} effects
	 */
	/** @type { Object<string, Wound> } */
	const wounds = {
		eyes: {
			weight: 10,
			allowed: (s) => canSee(s),
			effects: (s) => { clampedDamage(s, 30); eyeSurgery(s, "both", "blind"); }
		},
		voice: {
			weight: 10,
			allowed: (s) => canTalk(s),
			effects: (s) => { clampedDamage(s, 60); s.voice = 0; }
		},
		legs: {
			weight: 5,
			allowed: (s) => hasAnyNaturalLegs(s),
			effects: (s) => { clampedDamage(s, 80); removeLimbs(s, "left leg"); removeLimbs(s, "right leg"); }
		},
		arm: {
			weight: 5,
			allowed: (s) => hasAnyNaturalArms(s),
			effects: (s) => { clampedDamage(s, 60); removeLimbs(s, jsEither(["left arm", "right arm"])); }
		},
		flesh: {
			weight: 70,
			allowed: () => true,
			effects: (s) => { clampedDamage(s, 30); }
		}
		// TODO: add more wound types? destroy prosthetics?
	};

	/** Inflicts a large amount of damage upon a slave without killing them (i.e. leaving their health total above -90)
	 * @param {App.Entity.SlaveState} slave
	 * @param {number} magnitude
	 */
	function clampedDamage(slave, magnitude) {
		if ((slave.health.health - magnitude) > -90) {
			healthDamage(slave, magnitude);
		} else {
			healthDamage(slave, 90 + slave.health.health);
		}
	}

	/** Inflicts a wound upon a slave during a battle.  Returns the wound type from the wound table (see above) so it can be described.
	 * @param {App.Entity.SlaveState} slave
	 * @returns {string}
	 */
	function doWound(slave) {
		let woundHash = {};
		for (const w of Object.keys(wounds)) {
			if (wounds[w].allowed(slave)) {
				woundHash[w] = wounds[w].weight;
			}
		}
		/** @type {string} */
		// @ts-ignore - FIXME: hashChoice has bad JSDoc
		const wound = hashChoice(woundHash);
		wounds[wound].effects(slave);
		return wound;
	}

	return doWound;
})();

repo_name: Welptard/fc

license: mit


code:
// @ts-nocheck
App.SecExp.generalBC = function() {
	if (jsDef(V.secExp)) {
		if (V.secExpEnabled !== 1) {
			V.secExpEnabled = V.secExp;
		}
	}
	if (typeof V.secExpEnabled !== "number") {
		V.secExpEnabled = 0;
	}

	V.SecExp.settings = V.SecExp.settings || {};
	delete V.SecExp.settings.show;
	delete V.SecExp.army;

	if (V.secExpEnabled === 0) {
		return;
	} else {
		V.SecExp.edicts = V.SecExp.edicts || {};
		V.SecExp.edicts.alternativeRents = V.SecExp.edicts.alternativeRents || V.alternativeRents || 0;
		V.SecExp.edicts.enslavementRights = V.SecExp.edicts.enslavementRights || V.enslavementRights || 0;
		V.SecExp.edicts.sellData = V.SecExp.edicts.sellData || V.sellData || 0;
		V.SecExp.edicts.propCampaignBoost = V.SecExp.edicts.propCampaignBoost || V.propCampaignBoost || 0;
		V.SecExp.edicts.tradeLegalAid = V.SecExp.edicts.tradeLegalAid || V.tradeLegalAid || 0;
		V.SecExp.edicts.taxTrade = V.SecExp.edicts.taxTrade || V.taxTrade || 0;
		V.SecExp.edicts.slaveWatch = V.SecExp.edicts.slaveWatch || V.slaveWatch || 0;
		V.SecExp.edicts.subsidyChurch = V.SecExp.edicts.subsidyChurch || V.subsidyChurch || 0;
		V.SecExp.edicts.SFSupportLevel = V.SecExp.edicts.SFSupportLevel || V.SFSupportLevel || 0;
		V.SecExp.edicts.limitImmigration = V.SecExp.edicts.limitImmigration || V.limitImmigration || 0;
		V.SecExp.edicts.openBorders = V.SecExp.edicts.openBorders || V.openBorders || 0;
		V.SecExp.edicts.weaponsLaw = V.SecExp.edicts.weaponsLaw || V.weaponsLaw || 3;

		V.SecExp.edicts.defense = V.SecExp.edicts.defense || {};
		V.SecExp.edicts.defense.soldierWages = V.SecExp.edicts.defense.soldierWages || V.soldierWages || 1;
		V.SecExp.edicts.defense.slavesOfficers = V.SecExp.edicts.defense.slavesOfficers || V.slavesOfficers || 0;
		V.SecExp.edicts.defense.discountMercenaries = V.SecExp.edicts.defense.discountMercenaries  || V.discountMercenaries || 0;

		V.SecExp.edicts.defense.militia = V.SecExp.edicts.defense.militia || 0;
		if (V.militiaFounded) {
			V.SecExp.edicts.defense.militia = 1;
		}
		if (V.recruitVolunteers) {
			V.SecExp.edicts.defense.militia = 2;
		}
		if (V.conscription) {
			V.SecExp.edicts.defense.militia = 3;
		}
		if (V.militaryService) {
			V.SecExp.edicts.defense.militia = 4;
		}
		if (V.militarizedSociety) {
			V.SecExp.edicts.defense.militia = 5;
		}

		V.SecExp.edicts.defense.militaryExemption = V.SecExp.edicts.defense.militaryExemption || V.militaryExemption || 0;
		V.SecExp.edicts.defense.noSubhumansInArmy = V.SecExp.edicts.defense.noSubhumansInArmy || V.noSubhumansInArmy || 0;
		V.SecExp.edicts.defense.pregExemption = V.SecExp.edicts.defense.pregExemption || V.pregExemption || 0;
		V.SecExp.edicts.defense.liveTargets = V.SecExp.edicts.defense.liveTargets || V.liveTargets || 0;
		V.SecExp.edicts.defense.pregExemption = V.SecExp.edicts.defense.pregExemption || V.pregExemption || 0;

		// Units
		V.SecExp.edicts.defense.martialSchool = V.SecExp.edicts.defense.martialSchool || V.martialSchool || 0;
		V.SecExp.edicts.defense.eliteOfficers = V.SecExp.edicts.defense.eliteOfficers || V.eliteOfficers || 0;
		V.SecExp.edicts.defense.lowerRequirements = V.SecExp.edicts.defense.lowerRequirements || V.lowerRequirements|| V.lowerRquirements || 0;
		V.SecExp.edicts.defense.legionTradition = V.SecExp.edicts.defense.legionTradition || V.legionTradition || 0;
		V.SecExp.edicts.defense.eagleWarriors = V.SecExp.edicts.defense.eagleWarriors || V.eagleWarriors || 0;
		V.SecExp.edicts.defense.ronin = V.SecExp.edicts.defense.ronin || V.ronin || 0;
		V.SecExp.edicts.defense.sunTzu = V.SecExp.edicts.defense.sunTzu || V.sunTzu || 0;
		V.SecExp.edicts.defense.mamluks = V.SecExp.edicts.defense.mamluks || V.mamluks || 0;
		V.SecExp.edicts.defense.pharaonTradition = V.SecExp.edicts.defense.pharaonTradition || V.pharaonTradition || 0;

		// Priv
		V.SecExp.edicts.defense.privilege = V.SecExp.edicts.defense.privilege || {};
		V.SecExp.edicts.defense.privilege.militiaSoldier = V.SecExp.edicts.defense.privilege.militiaSoldier || V.militiaSoldier || 0;
		V.SecExp.edicts.defense.privilege.slaveSoldier = V.SecExp.edicts.defense.privilege.slaveSoldier || V.slaveSoldier || 0;
		V.SecExp.edicts.defense.privilege.mercSoldier = V.SecExp.edicts.defense.privilege.mercSoldier || V.mercSoldier || 0;

		V.SecExp.defaultNames = V.SecExp.defaultNames || {};
		V.SecExp.defaultNames.slaves = V.SecExp.defaultNames.slaves || "slave platoon";
		V.SecExp.defaultNames.militia = V.SecExp.defaultNames.militia || "citizens' platoon";
		if (jsDef(V.SecExp.defaultNames.milita)) {
			V.SecExp.defaultNames.militia = V.SecExp.defaultNames.milita;
			delete V.SecExp.defaultNames.milita;
		}
		V.SecExp.defaultNames.mercs = V.SecExp.defaultNames.mercs || "mercenary platoon";

		// V.SecExp.units = V.SecExp.units || {};
		Object.assign(V.secBots, {
			active: Math.max(0, V.secBots.active) || V.arcologyUpgrade.drones > 0 ? 1 : 0,
			ID: -1,
			isDeployed: V.secBots.isDeployed || 0,
			troops: Math.max(V.secBots.troops || 0, V.arcologyUpgrade.drones > 0 ? 30 : 0),
			maxTroops: Math.max(V.secBots.maxTroops || 0, V.arcologyUpgrade.drones > 0 ? 30 : 0)
		});
		/* if (V.secBots) {
			V.SecExp.units.bots = V.secBots;
		}
		*/
		// V.SecExp.units.slaves = V.SecExp.units.slaves || {};
		// V.SecExp.units.slaves.casualties = V.SecExp.units.slaves.casualties || V.slavesTotalCasualties || 0;
		// V.SecExp.units.slaves.created = V.SecExp.units.slaves.created || V.createdSlavesUnits || 0;
		// V.SecExp.units.slaves.sqauds = V.SecExp.units.slaves.sqauds || V.slaveUnits || [];
		for (let i = 0; i < V.slaveUnits; i++) {
			App.SecExp.fixBrokenUnit(V.slaveUnits[i]);
		}

		// V.SecExp.units.milita = V.SecExp.units.milita || {};
		// V.SecExp.units.milita.created = V.SecExp.units.milita.created || V.createdMilitiaUnits || 0;
		// V.SecExp.units.milita.free = V.SecExp.units.milita.free || V.militiaFreeManpower || 0;
		// V.SecExp.units.milita.casualties = V.SecExp.units.milita.casualties || V.militiaTotalCasualties || 0;
		// V.SecExp.units.milita.sqauds = V.SecExp.units.milita.sqauds || V.militiaUnits || [];
		for (let i = 0; i < V.militiaUnits; i++) {
			App.SecExp.fixBrokenUnit(V.militiaUnits[i]);
		}

		// V.SecExp.units.mercs = V.SecExp.units.mercs || {};
		// V.SecExp.units.mercs.created = V.SecExp.units.mercs.created || V.createdMercUnits || 0;
		// V.SecExp.units.mercs.free = V.SecExp.units.mercs.free || V.mercFreeManpower || 0;
		if (V.mercFreeManpower === 0) {
			if (V.mercenaries === 1) {
				V.mercFreeManpower = 15;
			} else if (V.mercenaries > 1) {
				V.mercFreeManpower = 30;
			}
		}
		// V.SecExp.units.mercs.casualties = V.SecExp.units.mercs.casualties || V.mercTotalCasualties || 0;
		// V.SecExp.units.mercs.sqauds = V.SecExp.units.mercs.sqauds || V.mercUnits || [];
		for (let i = 0; i < V.mercUnits; i++) {
			App.SecExp.fixBrokenUnit(V.mercUnits[i]);
		}

		V.SecExp.smilingMan = V.SecExp.smilingMan || {};
		V.SecExp.smilingMan.progress = V.SecExp.smilingMan.progress || V.smilingManProgress || 0;
		if (jsDef(V.smilingManFate)) {
			if (V.smilingManFate === 0) { // Offer $him a new life
				V.SecExp.smilingMan.progress = 10;
			} else if (V.smilingManFate === 1) { // Make $him pay
				V.SecExp.smilingMan.progress = 20;
			} else if (V.smilingManFate === 2) { // Enslave $him
				V.SecExp.smilingMan.progress = 30;
			}
		}

		if (V.SecExp.smilingMan.progress === 4) {
			V.SecExp.smilingMan.progress = 10;
		} else if (V.SecExp.smilingMan.progress < 4) {
			if (V.SecExp.smilingMan.progress === 0 && V.investedFunds) {
				V.SecExp.smilingMan.investedFunds = V.investedFunds;
			}
			if (V.relationshipLM) {
				V.SecExp.smilingMan.relationship = V.relationshipLM;
			}
			if (V.globalCrisisWeeks) {
				V.SecExp.smilingMan.globalCrisisWeeks = V.globalCrisisWeeks;
			}
		}

		V.SecExp.core = V.SecExp.core || {};
		delete V.SecExp.core.crimeCap;

		V.SecExp.core.trade = V.SecExp.core.trade || V.trade || 0;
		App.SecExp.initTrade();

		V.SecExp.core.authority = V.SecExp.core.authority || V.authority || 0;
		V.SecExp.core.security = V.SecExp.core.security || V.security || 100;
		if (jsDef(V.SecExp.security)) {
			V.SecExp.core.security = V.SecExp.security.cap;
			delete V.SecExp.security;
		}
		V.SecExp.core.totalKills = +V.SecExp.core.totalKills || V.totalKills || 0;

		if (V.week === 1 || !jsDef(V.SecExp.core.crimeLow)) {
			V.SecExp.core.crimeLow = 30;
		}
		V.SecExp.core.crimeLow = Math.clamp(V.SecExp.core.crimeLow, 0, 100);
		if (V.crime) {
			V.SecExp.core.crimeLow = V.crime;
		}

		V.SecExp.battles = V.SecExp.battles || {};
		V.SecExp.battles.slaveVictories = V.SecExp.battles.slaveVictories || V.slaveVictories || [];
		V.SecExp.battles.major = V.SecExp.battles.major || 0;
		if (jsDef(V.majorBattlesCount)) {
			if (V.majorBattlesCount === 0 && V.hasFoughtMajorBattleOnce === 1) {
				V.SecExp.battles.major = 1;
			} else {
				V.SecExp.battles.major = V.majorBattlesCount;
			}
		}
		V.SecExp.battles.victories = V.SecExp.battles.victories || V.PCvictories || 0;
		V.SecExp.battles.victoryStreak = V.SecExp.battles.victoryStreak || V.PCvictoryStreak || 0;
		V.SecExp.battles.losses = V.SecExp.battles.losses || V.PClosses || 0;
		V.SecExp.battles.lossStreak = V.SecExp.battles.lossStreak || V.PClossStreak || 0;
		V.SecExp.battles.lastEncounterWeeks = V.SecExp.battles.lastEncounterWeeks || V.lastAttackWeeks || 0;
		V.SecExp.battles.lastSelection = V.SecExp.battles.lastSelection || V.lastSelection || [];
		V.SecExp.battles.saved = V.SecExp.battles.saved || {};
		V.SecExp.battles.saved.commander = V.SecExp.battles.saved.commander || V.SavedLeader || "";
		V.SecExp.battles.saved.sfSupport = V.SecExp.battles.saved.sfSupport || V.SavedSFI || 0;

		V.SecExp.rebellions = V.SecExp.rebellions || {};
		V.SecExp.rebellions.tension = V.SecExp.rebellions.tension || V.tension || 0;
		V.SecExp.rebellions.slaveProgress = V.SecExp.rebellions.slaveProgress || V.slaveProgress || 0;
		V.SecExp.rebellions.citizenProgress = V.SecExp.rebellions.citizenProgress || V.citizenProgress || 0;
		V.SecExp.rebellions.victories = V.SecExp.rebellions.victories || V.PCrebWon || 0;
		V.SecExp.rebellions.losses = V.SecExp.rebellions.losses || V.PCrebLoss || 0;
		V.SecExp.rebellions.lastEncounterWeeks = V.SecExp.rebellions.lastEncounterWeeks || V.lastRebellionWeeks || 0;
		if (V.SFGear) {
			V.SecExp.rebellions.sfArmor = V.SFGear;
		}

		V.SecExp.settings.difficulty = V.SecExp.settings.difficulty || 1;
		if (jsDef(V.difficulty)) {
			V.SecExp.settings.difficulty = V.difficulty;
		}

		V.SecExp.settings.battle = V.SecExp.settings.battle || {};
		if (!jsDef(V.SecExp.settings.battle.enabled)) {
			V.SecExp.settings.battle.enabled = 1;
		}
		if (jsDef(V.battlesEnabled)) {
			V.SecExp.settings.battle.enabled = V.battlesEnabled;
		}
		delete V.SecExp.battle;

		V.SecExp.settings.battle.major = V.SecExp.settings.battle.major || {};
		V.SecExp.settings.battle.frequency = V.SecExp.settings.battle.frequency || 1;
		if (jsDef(V.battleFrequency)) {
			V.SecExp.settings.battle.frequency = V.battleFrequency;
		}
		V.SecExp.settings.battle.force = V.SecExp.settings.battle.force || 0;
		if (jsDef(V.forceBattle)) {
			V.SecExp.settings.battle.force = V.forceBattle;
		}

		if (V.readiness && V.readiness === 10 || V.sectionInFirebase) {
			V.SecExp.sectionInFirebase = 1;
		}

		V.SecExp.settings.unitDescriptions = V.SecExp.settings.unitDescriptions || 0;

		if (!jsDef(V.SecExp.settings.battle.allowSlavePrestige)) {
			V.SecExp.settings.battle.allowSlavePrestige = 1;
		}
		if (jsDef(V.allowPrestigeFromBattles)) {
			V.SecExp.settings.battle.allowSlavePrestige = V.allowPrestigeFromBattles;
		}

		V.SecExp.settings.battle.major.enabled = V.SecExp.settings.battle.major.enabled || 0;
		if (jsDef(V.majorBattlesEnabled)) {
			V.SecExp.settings.battle.major.enabled = V.majorBattlesEnabled;
		}

		if (!jsDef(V.SecExp.settings.battle.major.gameOver)) {
			V.SecExp.settings.battle.major.gameOver = 1;
		}
		if (jsDef(V.majorBattleGameOver)) {
			V.SecExp.settings.battle.major.gameOver = V.majorBattleGameOver;
		}
		V.SecExp.settings.battle.major.force = V.SecExp.settings.battle.major.force || 0;
		if (jsDef(V.forceMajorBattle)) {
			V.SecExp.settings.battle.major.force = V.forceMajorBattle;
		}
		V.SecExp.settings.battle.major.mult = V.SecExp.settings.battle.major.mult || 1;

		V.SecExp.settings.rebellion = V.SecExp.settings.rebellion || {};
		if (!jsDef(V.SecExp.settings.rebellion.enabled)) {
			V.SecExp.settings.rebellion.enabled = 1;
		}
		if (jsDef(V.rebellionsEnabled)) {
			V.SecExp.settings.rebellion.enabled = V.rebellionsEnabled;
		}

		V.SecExp.settings.rebellion.force = V.SecExp.settings.rebellion.force || 0;
		if (jsDef(V.forceRebellion)) {
			V.SecExp.settings.rebellion.force = V.forceRebellion;
		}
		if (!jsDef(V.SecExp.settings.rebellion.gameOver)) {
			V.SecExp.settings.rebellion.gameOver = 1;
		}
		if (jsDef(V.rebellionGameOver)) {
			V.SecExp.settings.rebellion.gameOver = V.rebellionGameOver;
		}

		V.SecExp.settings.rebellion.speed = V.SecExp.settings.rebellion.speed || 1;
		if (jsDef(V.rebellionSpeed)) {
			V.SecExp.settings.rebellion.speed = V.rebellionSpeed;
		}

		V.SecExp.settings.showStats = V.SecExp.settings.showStats || 0;
		if (jsDef(V.showBattleStatistics)) {
			V.SecExp.settings.showStats = V.showBattleStatistics;
		}

		V.SecExp.buildings = V.SecExp.buildings || {};
		App.SecExp.propHub.BC();
		App.SecExp.barracks.BC();
		App.SecExp.secHub.BC();
		App.SecExp.transportHub.BC();
		App.SecExp.riotCenter.BC();
		App.SecExp.weapManu.BC();

		V.SecExp.proclamation = V.SecExp.proclamation || {};
		V.SecExp.proclamation.cooldown = V.SecExp.proclamation.cooldown || V.proclamationsCooldown || 0;
		V.SecExp.proclamation.currency = V.SecExp.proclamation.currency || V.proclamationCurrency || "";
		V.SecExp.proclamation.type = V.SecExp.proclamation.type || "crime";
		if (jsDef(V.proclamationType) && V.proclamationType !== "none") {
			V.SecExp.proclamation.type = V.proclamationType;
		}
		/*
		V.SecExp.rebellions.repairTime = V.SecExp.rebellions.repairTime || {};
		V.SecExp.rebellions.repairTime.waterway = V.SecExp.rebellions.repairTime.waterway || 0;
		V.SecExp.rebellions.repairTime.assistant = V.SecExp.rebellions.repairTime.assistant || 0;
		V.SecExp.rebellions.repairTime.reactor = V.SecExp.rebellions.repairTime.reactor || 0;
		V.SecExp.rebellions.repairTime.arc = V.SecExp.rebellions.repairTime.arc || 0;
		if (jsDef(V.garrison)) {
			V.SecExp.rebellions.repairTime.waterway = V.garrison.waterwayTime;
			V.SecExp.rebellions.repairTime.assistant = V.garrison.assistantTime;
			V.SecExp.rebellions.repairTime.reactor = V.garrison.reactorTime;
			V.SecExp.rebellions.repairTime.arc = V.arcRepairTime;
		}
		*/
	}

	delete V.SecExp.security;
};


code:
App.SecExp.tradeReport = function() {
	let r = [], tradeChange = 0, bonus = 0;
	if (V.week < 30) {
		r.push(`The world economy is in good enough shape to sustain economic growth. Trade flows liberally in all the globe.`);
		tradeChange += 1;
	} else if (V.week < 60) {
		r.push(`The world economy is deteriorating, but still in good enough shape to sustain economic growth.`);
		tradeChange += 0.5;
	} else if (V.week < 90) {
		r.push(`The world economy is deteriorating, but still in decent enough shape to sustain economic growth.`);
	} else if (V.week < 120) {
		r.push(`The world economy is deteriorating and the slowing down of global growth is starting to have some effect on trade flow.`);
		tradeChange -= 1;
	} else {
		r.push(`The world economy is heavily deteriorated. The slowing down of global growth has a great negative effect on trade flow.`);
		tradeChange -= 2;
	}

	const warEffects = function(type) {
		if (V.SecExp[type].victories + V.SecExp[type].losses >= 1) {
			if (V.SecExp[type].lastEncounterWeeks < 2) {
				r.push(`The recent ${type === 'battles' ? 'attack' : 'rebellion'} has a negative effect on the trade of the arcology.`);
				tradeChange -= 1;
			} else if (V.SecExp[type].lastEncounterWeeks < 4) {
				r.push(`While some time has passed, the last ${type === 'battles' ? 'attack' : 'rebellion'} still has a negative effect on the commercial activity of the arcology.`);
				tradeChange -= 0.5;
			}
		}
	};

	warEffects('battles');
	warEffects('rebellions');

	if (V.terrain === "urban") {
		r.push(`Since your arcology is located in the heart of an urban area, its commerce is naturally vibrant.`);
		tradeChange++;
	} else if (V.terrain === "ravine") {
		r.push(`Since your arcology is located in the heart of a ravine, its commerce is hindered by a lack of accessibility.`);
		tradeChange -= 0.5;
	}

	if (["wealth", "capitalist", "celebrity", "BlackHat"].includes(V.PC.career)) {
		tradeChange += 1;
	} else if (["escort", "servant", "gang"].includes(V.PC.career)) {
		tradeChange -= 0.5;
	}

	if (V.rep > 12000) {
		r.push(`Your ${V.rep > 18000 ? 'extremely' : ''} high reputation attracts trade from all over the world.`);
		tradeChange += (V.rep > 18000 ? 2 : 1);
	}

	if (V.assistant.power > 0) {
		const lowPower = V.assistant.power === 1;
		r.push(`Due to ${lowPower ? '' : 'incredible'} computing power, ${V.assistant.name} is able to guide the commercial development of the arcology to greater levels.`);
		tradeChange += (lowPower ? 1 : 2);
	}

	if (V.SecExp.edicts.tradeLegalAid === 1) {
		r.push(`Your support in legal matters for new businesses helps improve the economic dynamicity of your arcology, boosting commercial activities.`);
		tradeChange += 1;
	}

	if (V.SecExp.edicts.taxTrade === 1) {
		r.push(`The fees imposed on transitioning goods do little to earn you the favor of the companies making use of your arcology.`);
		tradeChange -= 1;
	}

	if (V.SecExp.buildings.weapManu) {
		r.push(`The weapons manufacturing facility of the arcology attracts a significant amount of trade.`);
		tradeChange += 0.5 * (V.SecExp.buildings.weapManu.productivity + V.SecExp.buildings.weapManu.lab);
	}
	if (V.SecExp.buildings.transportHub) {
		if (V.SecExp.buildings.transportHub.airport === 1) {
			r.push(`The airport, while small, helps facilitate the commercial development of the arcology.`);
			tradeChange += 1;
		} else if (V.SecExp.buildings.transportHub.airport === 2) {
			r.push(`The airport, while fairly small, helps facilitate the commercial development of the arcology.`);
			tradeChange += 1.5;
		} else if (V.SecExp.buildings.transportHub.airport === 3) {
			r.push(`The airport helps facilitate the commercial development of the arcology.`);
			tradeChange += 2;
		} else if (V.SecExp.buildings.transportHub.airport === 4) {
			r.push(`The airport is a great boon to the commercial development of the arcology.`);
			tradeChange += 2.5;
		} else {
			r.push(`The airport is an incredible boon to the commercial development of the arcology.`);
			tradeChange += 3;
		}

		if (V.terrain !== "oceanic" && V.terrain !== "marine") {
			if (V.SecExp.buildings.transportHub.surfaceTransport === 1) {
				r.push(`The railway network's age and limited extension limit commercial activity.`);
			} else if (V.SecExp.buildings.transportHub.surfaceTransport === 2) {
				r.push(`The railway network is a great help to the commercial development of the arcology, but its limited extension hampers its potential.`);
				tradeChange += 1;
			} else if (V.SecExp.buildings.transportHub.surfaceTransport === 3) {
				r.push(`The railway network is a great help to the commercial development of the arcology.`);
				tradeChange += 1.5;
			} else {
				r.push(`The railway network is a huge help to the commercial development of the arcology. Few in the world can boast such a modern and efficient transport system.`);
				tradeChange += 2;
			}
		} else {
			if (V.SecExp.buildings.transportHub.surfaceTransport === 1) {
				r.push(`The docks' age and limited size limit commercial activity.`);
			} else if (V.SecExp.buildings.transportHub.surfaceTransport === 2) {
				r.push(`The docks are a great help to the commercial development of the arcology, but their limited size hampers its potential.`);
				tradeChange += 1;
			} else if (V.SecExp.buildings.transportHub.surfaceTransport === 3) {
				r.push(`The docks are a great help to the commercial development of the arcology.`);
				tradeChange += 1.5;
			} else {
				r.push(`The docks are a huge help to the commercial development of the arcology. Few in the world can boast such a modern and efficient transport system.`);
				tradeChange += 2;
			}
		}
	}

	const SF = App.SecExp.SF_effect('trade');
	r.push(SF.text); tradeChange += SF.bonus;

	if (tradeChange > 0) {
		r.push(`This week <span class="green">trade improved.</span>`);
	} else if (tradeChange === 0) {
		r.push(`This week <span class="yellow">trade did not change.</span>`);
	} else {
		r.push(`This week <span class="red">trade diminished.</span>`);
	}

	V.SecExp.core.trade = Math.clamp(V.SecExp.core.trade + tradeChange, 0, 100);
	if (V.SecExp.core.trade <= 20) {
		r.push(`The almost non-existent trade crossing the arcology <span class="yellow">does little to promote growth.</span>`);
	} else if (V.SecExp.core.trade <= 40) {
		r.push(`The low level of trade crossing the arcology promotes a <span class="green">slow yet steady growth</span> of its economy.`);
		bonus += 1.5;
	} else if (V.SecExp.core.trade <= 60) {
		r.push(`With trade at positive levels, the <span class="green">prosperity of the arcology grows more powerful.</span>`);
		bonus += 2.5;
	} else if (V.SecExp.core.trade <= 80) {
		r.push(`With trade at high levels, the <span class="green">prosperity of the arcology grows quickly and violently.</span>`);
		bonus += 3.5;
	} else {
		r.push(`With trade at extremely high levels, the <span class="green">prosperity of the arcology grows with unprecedented speed.</span>`);
		bonus += 4.5;
	}

	return {text: r.join(" "), bonus: bonus};
};


code:
:: miscSecExpWidgets [widget nobr]

<<widget "fixBrokenStats">>
	<<if !Number.isInteger($mercTotalCasualties)>>
		<<set $mercTotalCasualties = 0>>
	<</if>>
	<<if !Number.isInteger($slavesTotalCasualties)>>
		<<set $slavesTotalCasualties = 0>>
	<</if>>
	<<if !Number.isInteger($militiaTotalCasualties)>>
		<<set $militiaTotalCasualties = 0>>
	<</if>>
	<<if !Number.isInteger($militiaFreeManpower)>>
		<<set $militiaFreeManpower = 0>>
	<</if>>
<</widget>>

<<widget "replenishAllUnits">>
	<<set _hasLossesBots = 0, _hasLossesM = 0, _hasLossesS = 0, _hasLossesMe = 0>>

	<<if $secBots.troops < $secBots.maxTroops && $cash >= 500>>
		<<set _hasLossesBots = 1>>
	<</if>>

	<<for _i = 0; _i < $militiaUnits.length; _i++>>
		<<if $militiaUnits[_i].troops < $militiaUnits[_i].maxTroops && $militiaFreeManpower > 0>>
			<<set _hasLossesM = 1>>
			<<break>>
		<</if>>
	<</for>>

	<<for _i = 0; _i < $slaveUnits.length; _i++>>
		<<if $slaveUnits[_i].troops < $slaveUnits[_i].maxTroops && $menials > 0>>
			<<set _hasLossesS = 1>>
			<<break>>
		<</if>>
	<</for>>

	<<for _i = 0; _i < $mercUnits.length; _i++>>
		<<if $mercUnits[_i].troops < $mercUnits[_i].maxTroops && $mercFreeManpower > 0>>
			<<set _hasLossesMe = 1>>
			<<break>>
		<</if>>
	<</for>>

	<<if _hasLossesBots == 1 || _hasLossesM == 1 || _hasLossesS == 1 || _hasLossesMe == 1>>
		<<link "Replenish all units">>
			<<if _hasLossesBots == 1>>
					<<run cashX(-(($secBots.maxTroops - $secBots.troops) * 500), "securityExpansion")>>
					<<set $secBots.troops = $secBots.maxTroops>>
			<</if>>

			<<if _hasLossesM == 1>>
				<<for _i = 0; _i < $militiaUnits.length; _i++>>
					<<if $militiaUnits[_i].troops < $militiaUnits[_i].maxTroops && $militiaFreeManpower > 0>>
						<<if $militiaFreeManpower >= $militiaUnits[_i].maxTroops - $militiaUnits[_i].troops>>
							<<set $militiaFreeManpower -= $militiaUnits[_i].maxTroops - $militiaUnits[_i].troops>>
							<<set _expLoss = ($militiaUnits[_i].maxTroops - $militiaUnits[_i].troops) / $militiaUnits[_i].troops>>
							<<set $militiaUnits[_i].training -= $militiaUnits[_i].training * _expLoss>>
							<<set $militiaUnits[_i].troops = $militiaUnits[_i].maxTroops>>
						<<else>>
							<<set _expLoss = $militiaFreeManpower / $militiaUnits[_i].troops>>
							<<set $militiaUnits[_i].training -= $militiaUnits[_i].training * _expLoss>>
							<<set $militiaUnits[_i].troops += $militiaFreeManpower>>
							<<set $militiaFreeManpower = 0>>
						<</if>>
					<</if>>
				<</for>>
			<</if>>

			<<if _hasLossesS == 1>>
				<<for _i = 0; _i < $slaveUnits.length; _i++>>
					<<if $slaveUnits[_i].troops < $slaveUnits[_i].maxTroops && $menials > 0>>
						<<if $menials >= $slaveUnits[_i].maxTroops - $slaveUnits[_i].troops>>
							<<set $menials -= $slaveUnits[_i].maxTroops - $slaveUnits[_i].troops>>
							<<set _expLoss = ($slaveUnits[_i].maxTroops - $slaveUnits[_i].troops) / $slaveUnits[_i].troops>>
							<<set $slaveUnits[_i].training -= $slaveUnits[_i].training * _expLoss>>
							<<set $slaveUnits[_i].troops = $slaveUnits[_i].maxTroops>>
						<<else>>
							<<set _expLoss = $menials / $slaveUnits[_i].troops>>
							<<set $slaveUnits[_i].training -= $slaveUnits[_i].training * _expLoss>>
							<<set $slaveUnits[_i].troops += $menials>>
							<<set $menials = 0>>
						<</if>>
					<</if>>
				<</for>>
			<</if>>

			<<if _hasLossesMe == 1>>
				<<for _i = 0; _i < $mercUnits.length; _i++>>
					<<if $mercUnits[_i].troops < $mercUnits[_i].maxTroops && $mercFreeManpower > 0>>
						<<if $mercFreeManpower >= $mercUnits[_i].maxTroops - $mercUnits[_i].troops>>
							<<set $mercFreeManpower -= $mercUnits[_i].maxTroops - $mercUnits[_i].troops>>
							<<set _expLoss = ($mercUnits[_i].maxTroops - $mercUnits[_i].troops) / $mercUnits[_i].troops>>
							<<set $mercUnits[_i].training -= $mercUnits[_i].training * _expLoss>>
							<<set $mercUnits[_i].troops = $mercUnits[_i].maxTroops>>
						<<else>>
							<<set _expLoss = $mercFreeManpower / $mercUnits[_i].troops>>
							<<set $mercUnits[_i].training -= $mercUnits[_i].training * _expLoss>>
							<<set $mercUnits[_i].troops += $mercFreeManpower>>
							<<set $mercFreeManpower = 0>>
						<</if>>
					<</if>>
				<</for>>
			<</if>>

			<<= SugarCube.Engine.play(passage())>>
		<</link>>
		//Will replenish units as long as requirements are met.//<br>
	<</if>>
<</widget>>


code:
Hexall90's last merged commit: 52dde0b3

- Remove unit.isDeployed as it is only used in battles and add the IDs to an array.
	This would require that units have unique IDs (e.g bots: -1 -> 99, militia: 100 -> 199, slaves: 200 -> 299, mercs: 300 - 399, etc).
	It would also allow for _*RebelledID to potentially be removed.

- While at it something for barracks(general? commissar?) and riot center([Insert player title there]'s Will?? Big Sister? ) too would be nice
- While at it decoupling of propaganda slave and recruiter when?
- Would  it be possible to add option for assigning hacker to security HQ that would work similarly to giving office for recruiter in propaganda hub? Preferably with smiling man slave giving extra bonuses there
- Does having a large standing army give any bonus to authority/reputation growth?
- Fix broken immigration stuff (https://gitgud.io/pregmodfan/fc-pregmod/-/issues/2073 && https://gitgud.io/pregmodfan/fc-pregmod/-/merge_requests/7375)
- My personal asst keeps getting the credit, even though I choose to personally lead my forces. (Has been this way for a fewish days): Military01.swf
- Enable oceanic battles
	Fine, I'll Do It Myself
	Pirates? Enemy navies? - 328279
	Pirates could raid trade routs and such ,even could capture a high class cruise liner and you have to move retake it with an army similar to the ground battles. you could have an event where you gain a old world port to ship your goods to, and you have to defend it .		-328413
- How to make threads - 355452
	A suggestion for prisoners of war after winning the battle: maybe add an option to execute them on the spot for authority gains?
	And how about giving a chance (depending on the amount of captives) to actually make one or two of them that aren't as hateful or wounded as your sex slaves instead of just menials? Perhaps you may even turn (hypothetical) female captives into sex dolls or bioreactors too. It can be an optional button.
	Also, maybe make some of them actually surrender so it will be possible to get captives even when you completely overwhelm their forces in numbers/efficiency?
- How to make threads - 355478
- One thing I find to be weird/stupid is that facilities must be manned with menial slaves. I think that it instead should be an option, like with armies, to man them with free citizens instead who then do a better job but instead require a monthly wage.
- Oni-girl soldiers.
- Modify DOL battle scene to recognise SecExp units.
- Update encyclopedia entry to reflect above.
- Add suicide units.
- Add WarAnimal's units - Optimally Functioning Code, 254511 - 3rd Military Animal Platoon.
- Loli unit - Unlocked from Black market, origin Wedding edition - 310602.
- Feature Request: Attack Imminent Layout (GUI suggestion done) - https://gitgud.io/pregmodfan/fc-pregmod/issues/1145
- Feature Request: Potential for damage to Security Expansion Upgrades - https://gitgud.io/pregmodfan/fc-pregmod/issues/1146
- Special Forces Morale Bonus - https://gitgud.io/pregmodfan/fc-pregmod/issues/1165
- Suggestion - Specialized Schools, Fortifications and Militia Edicts -https://gitgud.io/pregmodfan/fc-pregmod/issues/763
- Suggestion - Arcology Conquest - https://gitgud.io/pregmodfan/fc-pregmod/issues/760
- Does forcing every citizen to be in military raise appeal of slaves that know how to fight?
- And if I am a master tactician, maybe I could get an estimate how effective the various tacticts could be?
- Ability to create more drone squads.
- Increase base maximum units to 18, 20 with SF.
- Suggestion - Gradual Battle Frequency - https://gitgud.io/pregmodfan/fc-pregmod/issues/1245#note_82504
- Option to send slaves into military unit to gain some nice scars and experience wold be nice (with retrieval).
- So would be taking slaves from slave units as personal ones. The slave units would pretty much be menial slaves I'd imagine, not sex slaves.
- If I think about it having a squad of personal slaves that you equip in whatever gear you want and send out to capture new slaves, raid caravans and cities and shit would be pretty sweet, I would even call it special forces but that's taken, also the combat skill is still a binary thing which makes the whole thing pointless.
	How about to start off with option to send one or two of your combat trained slaves to assist the merc's when they are on a raid with the possibility of receiving battle wounds.
- It would be a start if the tactics talking about the size difference of the armies actually took the size difference into account.
- How about to start off with option to send one or two of your combat trained slaves to assist the merc's when they are on a raid with the possibility of receiving battle wounds.
- If there are choices, they should be along the lines of "higher risk, higher reward" (defeating the enemy with fewer casualties and damage if it goes right, but suffering higher casualties and damage if it goes wrong), or things like accepting more/less military casualties for better/worse protection of economic assets (costing money/damaging economy) and civilians (costing reputation/damaging population).
- The ability to send units to the general to increase relationship as an alternative to sending slaves.


code:
:: proclamations [nobr]

<<set $nextButton = "Back to Main", $nextLink = "Main">>

<<if $SecExp.proclamation.cooldown == 0>>
	__Issue a proclamation:__

You can dedicate the week to issuing a proclamation, a powerful tool that will have an immediate noticeable effect on the arcology.

Use:
	<<if $SecExp.core.authority >= 2000>>
		<<link "authority" "Personal Attention Select">>
			<<set $SecExp.proclamation.currency = "authority">>
		<</link>>
	<<else>>
		//Requires at least <<= num(2000)>> authority//
	<</if>>
	|
	<<if $rep >= 4000>>
		<<link "reputation" "Personal Attention Select">>
			<<set $SecExp.proclamation.currency = "reputation">>
		<</link>>
	<<else>>
		//Requires at least <<= num(4000)>> reputation//
	<</if>>
	|
	<<if $cash >= 8000>>
		<<link "cash" "Personal Attention Select">>
			<<set $SecExp.proclamation.currency = "cash">>
		<</link>>
	<<else>>
		//Requires at least <<print cashFormat(8000)>> cash//
	<</if>>

	<<link "Issue a proclamation about security" "Main">>
		<<set $personalAttention = "proclamation", $SecExp.proclamation.type = "security">>
	<</link>>

//You will use your <<if $SecExp.proclamation.currency == "authority">>control over the arcology<<elseif $SecExp.proclamation.currency == "reputation">>great influence<<elseif $SecExp.proclamation.currency == "cash">>vast financial means<</if>>
	to force citizens to give up on sensitive information for the good of the arcology.//

	<<link "Issue a proclamation about crime" "Main">>
		<<set $personalAttention = "proclamation", $SecExp.proclamation.type = "crime">>
	<</link>>

//You will use your <<if $SecExp.proclamation.currency == "authority">>control over the arcology<<elseif $SecExp.proclamation.currency == "reputation">>great influence<<elseif $SecExp.proclamation.currency == "cash">>vast financial means<</if>>
	to force the arrest of suspected citizens without passing through the normal legal procedures.//
<<else>>
	It's too early to issue another proclamation. Another will be available in <<= numberWithPluralOne($SecExp.proclamation.cooldown, "week")>>.
<</if>>


code:
:: rebellionEvents [nobr]

<<if $slaveRebellionEventFires == 1>>
	<<if $SecExp.rebellions.tension <= 33>>
		<<set _event = 1>>
	<<elseif $SecExp.rebellions.tension <= 66>>
		<<set _event = 2>>
	<<else>>
		<<set _event = 3>>
	<</if>>
<<elseif $citizenRebellionEventFires == 1>>
	<<if $SecExp.rebellions.tension <= 33>>
		<<set _event = 4>>
	<<elseif $SecExp.rebellions.tension <= 66>>
		<<set _event = 5>>
	<<else>>
		<<set _event = 6>>
	<</if>>
<</if>>

<<setNonlocalPronouns $seeDicks>>
<<switch _event>>
<<case 1>>
	/* low tension slave rebellion events */
	<<set _rand = random(0,6)>>
	<<if _rand == 0>>
		This week several slaves were found plotting the death of their master. They were quickly dealt with, but their owner's choice of punishment did little to calm tensions in the arcology.
	<<elseif _rand == 1>>
		This week a large group of slaves attempted to escape. Several were recaptured, but others were deemed too dangerous and were shot on sight. The unfortunate circumstances raised the disapproval of many citizens, either because of the waste of good slaves or the brutality with which the operation was carried. With a bit of luck, however, the incident will be soon forgotten.
	<<elseif _rand == 2>>
		This week books of unknown origin and dangerous content were found in the possession of several slaves. They were mostly sociopolitical treaties, making it clear that the intent of the ones responsible was to fan the fire of rebellion. The books were quickly collected and archived, hopefully this affair will not have lasting consequences.
	<<elseif _rand == 3>>
		This week a citizen was caught giving refuge to an escaped slave. He was not able to pay for the value of the stolen goods, so he was processed as the case required and the slave returned to their rightful master. Many questions however remain without answers.
	<<elseif _rand == 4>>
		This week a member of a well known anti-slavery group was caught trying to infiltrate the arcology. During the capture attempt shots were fired and several guards were injured, and in the end the fugitive unfortunately managed to escape. Reports indicate several slaves helped the criminal, some going as far as using themselves as shields against the bullets of the security drones.
	<<elseif _rand == 5>>
		This week a slave was caught attempting to sabotage a machine in one of the factories. _HeU explained _hisU action as "trying to defend _himselfU from a dangerous machine". Reports confirmed that the apparatus is indeed quite deadly, having killed several slaves since it was installed, but the expert way _heU handled the sabotage leaves open the possibility of a deliberate plan or even external help.
	<<else>>
		This week a slave was found dead in one of the sewer tunnels. It seems _heU was stabbed repeatedly with a sharp object. _HeU was fairly famous for _hisU capabilities as a slave trainer; _hisU old master spent not an insignificant amount of money trying to find _himU once he realized _heU was missing. The episode might have been a simple mugging gone wrong, but _hisU activities as a slave breaker might have played a role in _hisU homicide.
	<</if>>
	<<set $SecExp.rebellions.tension += random(1,5)>>
<<case 2>>
	/* med tension slave rebellion events */
	<<set _rand = random(0,5)>>
	<<if _rand == 0>>
		This week some strange reports came in: it seems some assemblies of slaves were observed several nights in a row. The slaves were traced and their masters notified, but many suspect there may be something deeper than a few slaves congregating in the night.
	<<elseif _rand == 1>>
		This week an underground railroad was discovered. The rebels did not go down without a fight, but in the end <<if $mercenaries >= 1>>your mercenaries<<else>>your security drones<</if>> managed to destroy the old tunnels they were using to ship out slaves out of the arcology.
	<<elseif _rand == 2>>
		This week a famous citizen was assaulted and brutally murdered by his slaves. The ones responsible were apprehended and dealt with easily enough, but the mere fact something like this could have happened is concerning. Those slaves had to be aware of their certain doom.
	<<elseif _rand == 3>>
		This week a group of slavers entering the arcology was assaulted. Many reported heavy injuries, but fortunately there were no casualties. The attackers were disguised, but the security systems already identified several slaves who were likely part of the group, based on camera feeds.
	<<elseif _rand == 4>>
		This week the waterways were found infected by a virulent pathogen. The cause was later found to be a diseased slave that died while in the maintenance tunnels. It's not clear if the slave was there because of orders given to _himU or if _heU was trying to escape.
	<<else>>
		This week a sleeper cell of a famous anti slavery organization was discovered in the low levels of the arcology. The group, however, was aware of the coming security forces and retreated before they could be dealt with.
	<</if>>
	<<set $SecExp.rebellions.tension += random(5,10)>>
<<case 3>>
	/* high tension slave rebellion events */
	<<set _rand = random(0,4)>>
	<<if _rand == 0>>
		This week a group of slaves took control of one of the manufacturing plants and barricaded themselves inside. It took several days of negotiations and skirmishes to finally end this little insurrection. Many of the slaves involved will be executed in the next few days.
	<<elseif _rand == 1>>
		This week a number of shops were burned to the ground by rioting slaves and sympathetic citizens. It took considerable effort for the security forces to take control of the situation. Harsh punishment is required and scheduled for the instigators.
	<<elseif _rand == 2>>
		This week a mass escape attempt was barely stopped before becoming a catastrophe. Many citizens were trampled by the desperate horde of slaves. It will take some time to restore the streets involved to working order.
	<<elseif _rand == 3>>
		This week a number of riots inflamed the arcology. Many slaves took violent actions against citizens and security personnel. The number of victims keeps getting higher as still now the last sparks of revolt are still active.
	<</if>>
	<<set $SecExp.rebellions.tension += random(10,15)>>
<<case 4>>
	<<set _rand = random(0,6)>>
	<<if _rand == 0>>
		This week a citizen refused to pay rent, claiming ideological opposition to the arcology's ownership policies. He was quickly dealt with, but his words might not have fallen silent yet.
	<<elseif _rand == 1>>
		This week books of unknown origin and dangerous content were found in the possession of several citizens. They were mostly sociopolitical treaties, making it clear that the intent of the ones responsible was to fan the fire of rebellion. Most of them were bought and archived, but a few are still circling amongst the citizens of the arcology.
	<<elseif _rand == 2>>
		This week a citizen was caught giving refuge to other citizens, who would be liable to be enslaved because of their debts. The situation was quickly resolved, but the misplaced generosity of that citizen might have inflamed a few souls.
	<<elseif _rand == 3>>
		This week a citizen died in one of the factories. His death sparked some outrage, even some talk of protests against the owners of the factory, but things seem to have calmed down for now.
	<<elseif _rand == 4>>
		This week a citizen refused to be evicted from his house. After some negotiations the man was forcibly removed from the property by your security forces. Unfortunately the forced entry caused some damage to the building.
	<<elseif _rand == 5>>
		This week a citizen refused to be enslaved as his contract established. With an impressive display of his rhetoric capabilities he managed to gather a small crowd agreeing with his position. The impromptu assembly was promptly disrupted by the drones.
	<<else>>
		This week a security drone was found disabled and stripped of important electronic components. It seems the act was not dictated by greed, as the most precious parts of the drone were left on the machine, but rather to cover up something that the drone saw.
	<</if>>
	<<set $SecExp.rebellions.tension += random(1,5)>>
<<case 5>>
	<<set _rand = random(0,5)>>
	<<if _rand == 0>>
		This week a factory was subject to a strike by a group of citizens protesting against the owner. They were promptly arrested and the factory returned to its rightful proprietor by your security department.
	<<elseif _rand == 1>>
		This week a group of citizens organized a protest against the systemic enslavement of the citizens of the arcology. Their little parade gathered a surprisingly large crowd, but it was nonetheless quickly suppressed by your forces.
	<<elseif _rand == 2>>
		This week the security department registered the formation of several assemblies of citizens, whose purpose seems to be political in nature. For now no further steps were taken, but it's a worrying sign of further political opposition within the arcology.
	<<elseif _rand == 3>>
		This week there was a protest against one of the wealthiest citizen of the arcology. Many criticize his near monopoly. Supporters of the citizen met the protesters on the streets and it was just thanks to the intervention of the security drones that violence was avoided.
	<<elseif _rand == 4>>
		This week several cameras were sabotaged and in many cases damaged beyond repair. A group of anonymous citizens claims to be responsible; their motivation is apparently the excessive surveillance in the arcology and their attack a response to the breach of their privacy.
	<<else>>
		This week several citizens barricaded themselves in a private brothel. It seems their intention is to protest against the use of ex-citizens in the sex trade, claiming that such a position is unfitting for them. The problem was quickly resolved with the intervention of the security department.
	<</if>>
	<<set $SecExp.rebellions.tension += random(5,10)>>
<<case 6>>
	<<set _rand = random(0,4)>>
	<<if _rand == 0>>
		This week the arcology was shaken by a number of strikes throughout the manufacturing levels. Many lament the predatory nature of Free Cities society, many other just want to cause damage to their perceived oppressors. It was a significant effort for the security department to stop all protests.
	<<elseif _rand == 1>>
		This week several factories were set aflame by their workers. The security department worked day and night to control the fire and apprehend the criminals behind the act. Many are known dissidents, but there are a fair few new faces within them. This is a worrying sign.
	<<elseif _rand == 2>>
		This week numerous riots exploded all over the arcology. Many citizens took to the streets to protest against the arcology owner and its supporters. The security forces slowly managed to stop the rioters, with no small amount of trouble and only through generous use of violence.
	<<elseif _rand == 3>>
		This week a massive protest of citizens and slaves gathered just outside the penthouse. The crowd was dispersed only after several hours. There were several victims from both sides and no shortage of injured.
	<</if>>
	<<set $SecExp.rebellions.tension += random(10,15)>>
<</switch>>

<<set $SecExp.rebellions.tension = Math.clamp($SecExp.rebellions.tension,0,100)>>