diff --git a/src/js/economyJS.js b/src/js/economyJS.js
index ac469bcb3f6e185b26111c9a110e3d97f0ccd518..08dbf711dbe67868cb43218f70f6f1e9597c3d2c 100644
--- a/src/js/economyJS.js
+++ b/src/js/economyJS.js
@@ -534,9 +534,12 @@ window.calculateCosts = (function() {
 		return costs;
 	}
 
-	// The amount of slaves served by a servant
+	/**
+	 * The amount of slaves served by a servant
+	 * @param {App.Entity.SlaveState} slave
+	 */
 	function getSlaveMinorCosts(slave) {
-		let effectiveness;
+		let effectiveness = 0;
 		if (slave.trust < -20) {
 			effectiveness = 80;
 		} else if (slave.devotion < -20) {
@@ -1166,7 +1169,7 @@ window.slaveJobValues = function(lowerClassSexDemandRef, middleClassSexDemandRef
 		} else {
 			V.Madam.skill.madam += jsRandom(1, Math.ceil((V.Madam.intelligence + V.Madam.intelligenceImplant) / 15) + 8);
 		}
-		if (V.Madam.intelligence+V.Madam.intelligenceImplant > 15) {
+		if (V.Madam.intelligence + V.Madam.intelligenceImplant > 15) {
 			// $He is a clever manager.
 			V.MadamCashBonus += 0.05 * Math.floor((V.Madam.intelligence + V.Madam.intelligenceImplant) / 32);
 		}
@@ -1180,7 +1183,7 @@ window.slaveJobValues = function(lowerClassSexDemandRef, middleClassSexDemandRef
 				V.MadamCashBonus -= 0.05;
 			} else if (V.familyTesting === 1 && areRelated(V.Madam, V.slaves[i]) > 0) {
 				V.MadamCashBonus += 0.05;
-			} else if ( V.Madam.relationTarget === V.slaves[i].ID && $familyTesting === 0) {
+			} else if (V.Madam.relationTarget === V.slaves[i].ID && V.familyTesting === 0) {
 				V.MadamCashBonus += 0.05;
 			}
 			if (V.slaves[i].prestigeDesc === "$He is a famed Free Cities whore, and commands top prices.") {
@@ -1188,11 +1191,11 @@ window.slaveJobValues = function(lowerClassSexDemandRef, middleClassSexDemandRef
 			} else if (V.slaves[i].prestigeDesc === "$He is a famed Free Cities slut, and can please anyone.") {
 				V.MadamCashBonus += 0.15;
 			} else if (V.slaves[i].prestigeDesc === "$He is remembered for winning best in show as a dairy cow.") {
-				if ($arcologies[0].FSPhysicalIdealist !== "unset") {
-					if (V.slaves[i].muscles > 60 && V.slaves[i].weight < 30 && V.slaves[i].lactation > 0 && V.slaves[i].boobs-V.slaves[i].boobsImplant > 6000) {
+				if (V.arcologies[0].FSPhysicalIdealist !== "unset") {
+					if (V.slaves[i].muscles > 60 && V.slaves[i].weight < 30 && V.slaves[i].lactation > 0 && V.slaves[i].boobs - V.slaves[i].boobsImplant > 6000) {
 						V.MadamCashBonus += 0.15;
 					}
-				} else if (V.slaves[i].lactation > 0 && V.slaves[i].boobs-V.slaves[i].boobsImplant > 6000) {
+				} else if (V.slaves[i].lactation > 0 && V.slaves[i].boobs - V.slaves[i].boobsImplant > 6000) {
 					V.MadamCashBonus += 0.10;
 				}
 			} else if (V.slaves[i].prestigeDesc === "$He is remembered for winning best in show as a cockmilker.") {
@@ -1382,7 +1385,7 @@ window.slaveJobValues = function(lowerClassSexDemandRef, middleClassSexDemandRef
 				} else {
 					let canA = canDoAnal(s);
 					let canV = canDoVaginal(s);
-					let skilltarget = (100 + ((s.skill.anal - 100)*canA*(1.5 - 0.5*canV) + (s.skill.vaginal - 100)*canV*(1.5 - 0.5*canA) + (s.skill.oral - 100)*(3 - 1.5*canA - 1.5*canV + canA*canV))*3/10);
+					let skilltarget = (100 + ((s.skill.anal - 100) * canA * (1.5 - 0.5 * canV) + (s.skill.vaginal - 100) * canV * (1.5 - 0.5 * canA) + (s.skill.oral - 100) * (3 - 1.5 * canA - 1.5 * canV + canA * canV)) * 3 / 10);
 					// Complicated, I know - but it should automatically account for what acts are possible to scale the injury risk smoothly between 90% when totally unskilled
 					// and 0% when perfectly skilled in the relevant method or methods.
 
@@ -1458,6 +1461,13 @@ window.slaveJobValues = function(lowerClassSexDemandRef, middleClassSexDemandRef
 		}
 	}
 
+	/**
+	 * @param {App.Entity.SlaveState} s
+	 * @param {number} lowerClassSexDemandRef
+	 * @param {number} middleClassSexDemandRef
+	 * @param {number} upperClassSexDemandRef
+	 * @param {number} topClassSexDemandRef
+	 */
 	function SJVBrothel(s, lowerClassSexDemandRef, middleClassSexDemandRef, upperClassSexDemandRef, topClassSexDemandRef) {
 		let toTheBrothel = 0;
 		let beautyMultiplier = 1;
@@ -1467,7 +1477,7 @@ window.slaveJobValues = function(lowerClassSexDemandRef, middleClassSexDemandRef
 		if (s.sexualFlaw === "neglectful") {
 			beautyMultiplier += 0.1;
 		}
-		if ((s.hears === -1 && s.earwear !== "hearing aids") || (s.hears === 0 && s.earwear === "muffling ear plugs") ||(s.hears === -2)) {
+		if ((s.hears === -1 && s.earwear !== "hearing aids") || (s.hears === 0 && s.earwear === "muffling ear plugs") || (s.hears === -2)) {
 			if (!canHear(s)) {
 				beautyMultiplier -= 0.25;
 			} else {
@@ -1570,7 +1580,7 @@ window.slaveJobValues = function(lowerClassSexDemandRef, middleClassSexDemandRef
 				} else {
 					let canA = canDoAnal(s);
 					let canV = canDoVaginal(s);
-					let skilltarget = (100 + ((s.skill.anal - 100)*canA*(1.5 - 0.5*canV) + (s.skill.vaginal - 100)*canV*(1.5 - 0.5*canA) + (s.skill.oral - 100)*(3 - 1.5*canA - 1.5*canV + canA*canV))*3/10);
+					let skilltarget = (100 + ((s.skill.anal - 100) * canA * (1.5 - 0.5 * canV) + (s.skill.vaginal - 100) * canV * (1.5 - 0.5 * canA) + (s.skill.oral - 100) * (3 - 1.5 * canA - 1.5 * canV + canA * canV)) * 3 / 10);
 					// Complicated, I know - but it should automatically account for what acts are possible to scale the injury risk smoothly between 90% when totally unskilled
 					// and 0% when perfectly skilled in the relevant method or methods.
 
@@ -1635,8 +1645,15 @@ window.slaveJobValues = function(lowerClassSexDemandRef, middleClassSexDemandRef
 			s.sexQuality = 2;
 		}
 
-		// The whoreScore function finds the appropriate customer class and then calculates the whore income stats associated with that class and adds to the class supply.
-		// whoreClass is the MAXIMUM player set class the whore is allowed to service, if the whore is not eligable it will service the highest it is capable of servicing properly. A whoreClass of 0 means it is on auto (always service the highest possible class).
+		/**
+		 * The whoreScore function finds the appropriate customer class and then calculates the whore income stats associated with that class and adds to the class supply.
+		 * whoreClass is the MAXIMUM player set class the whore is allowed to service, if the whore is not eligable it will service the highest it is capable of servicing properly. A whoreClass of 0 means it is on auto (always service the highest possible class).
+		 * @param {App.Entity.SlaveState} s
+		 * @param {number} lowerClassSexDemandRef
+		 * @param {number} middleClassSexDemandRef
+		 * @param {number} upperClassSexDemandRef
+		 * @param {number} topClassSexDemandRef
+		 */
 		function whoreScore(s, lowerClassSexDemandRef, middleClassSexDemandRef, upperClassSexDemandRef, topClassSexDemandRef) {
 			let income = s.sexAmount * s.sexQuality;
 			const initialHealthPenalty = healthPenalty(s);
@@ -1644,8 +1661,6 @@ window.slaveJobValues = function(lowerClassSexDemandRef, middleClassSexDemandRef
 			s.maxWhoreClass = s.effectiveWhoreClass;
 			income *= initialHealthPenalty;
 
-
-
 			// Automatically changing effectiveWhoreClass
 			// what is the initial effective whore class? Are we providing more sex than overal demand? Is the ratio of supply/demand for this tier higher than the one below it?
 			// This also takes into consideration public sluts and ignores the NPC market and arcades
@@ -1669,15 +1684,15 @@ window.slaveJobValues = function(lowerClassSexDemandRef, middleClassSexDemandRef
 
 			// Calculate the stats
 			if (s.effectiveWhoreClass === 4) {
-				s.sexAmount = Math.clamp(Math.trunc(s.sexAmount * (1/3)), normalRandInt(30, 2), normalRandInt(60, 3)); // Bringing sex amount into the desired range. Beauty improves use amount between values of aprox. 90 and 180.
+				s.sexAmount = Math.clamp(Math.trunc(s.sexAmount * (1 / 3)), normalRandInt(30, 2), normalRandInt(60, 3)); // Bringing sex amount into the desired range. Beauty improves use amount between values of aprox. 90 and 180.
 				tiredFucks(s); // adding tiredness based on number of fucks and then adjusting income in case the tiredness penalty changed as a result.
 				if (healthPenalty(s) < initialHealthPenalty) {
 					income *= healthPenalty(s) / initialHealthPenalty;
 				}
-				s.sexQuality = Math.min(Math.trunc(Math.min((income * 1.2) / s.sexAmount, V.whoreBudget.topClass * 0.2)), Math.trunc(V.whoreBudget.topClass * (1/3))); // Adjusting the price to the correct sex amount with 20% bonus for being of the highest tier. The top class will pay a maximum of 33% of their weekly budget per service.
+				s.sexQuality = Math.min(Math.trunc(Math.min((income * 1.2) / s.sexAmount, V.whoreBudget.topClass * 0.2)), Math.trunc(V.whoreBudget.topClass * (1 / 3))); // Adjusting the price to the correct sex amount with 20% bonus for being of the highest tier. The top class will pay a maximum of 33% of their weekly budget per service.
 				slaveJobValues.brothel.topClass += Math.trunc(Math.min(s.sexAmount * s.sexQuality, s.sexAmount * V.whoreBudget.topClass * 0.2)); // Registering the job value in the right slot
 			} else if (s.effectiveWhoreClass === 3) {
-				s.sexAmount = Math.clamp(Math.trunc(s.sexAmount * (2/3)), normalRandInt(40, 3), normalRandInt(80, 3)); // Beauty improves use amount between values of aprox. 60 and 120.
+				s.sexAmount = Math.clamp(Math.trunc(s.sexAmount * (2 / 3)), normalRandInt(40, 3), normalRandInt(80, 3)); // Beauty improves use amount between values of aprox. 60 and 120.
 				tiredFucks(s);
 				if (healthPenalty(s) < initialHealthPenalty) {
 					income *= healthPenalty(s) / initialHealthPenalty;
@@ -1719,6 +1734,10 @@ window.slaveJobValues = function(lowerClassSexDemandRef, middleClassSexDemandRef
 	return slaveJobValues;
 };
 
+/**
+ * @param {App.Entity.SlaveState} s
+ * @returns {number}
+ */
 window.effectiveWhoreClass = function(s) {
 	let score = s.sexAmount * s.sexQuality;
 	let result;
@@ -1741,6 +1760,11 @@ window.effectiveWhoreClass = function(s) {
 	return result;
 };
 
+/**
+ * @param {App.Entity.SlaveState} s
+ * @param {Object|undefined} facility
+ * @returns {Object}
+ */
 window.getSlaveStatisticData = function(s, facility) {
 	if (!facility) { // Base data, even without facility
 		return {
@@ -1928,29 +1952,29 @@ Number.prototype.toFixedHTML = function() {
 };
 
 window.SectorCounts = function() {
- V.Sweatshops = 0; // Ternaries: - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator
- V.AProsperityCapModified = V.AProsperityCapModified > 0 ? V.AProsperityCapModified : 0;
- const caps = [
- {upgrade: "drones", cap: 10},
- {upgrade: "hydro", cap: 30},
- {upgrade: "apron", cap: 60},
- {upgrade: "grid", cap: 100},
- {upgrade: "spire", cap: 150}];
-
- V.AProsperityCap = 0;
- caps.forEach(cap => {
+	V.Sweatshops = 0; // Ternaries: - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator
+	V.AProsperityCapModified = V.AProsperityCapModified > 0 ? V.AProsperityCapModified : 0;
+	const caps = [
+		{upgrade: "drones", cap: 10},
+		{upgrade: "hydro", cap: 30},
+		{upgrade: "apron", cap: 60},
+		{upgrade: "grid", cap: 100},
+		{upgrade: "spire", cap: 150}];
+
+	V.AProsperityCap = 0;
+	caps.forEach(cap => {
 		if (V.arcologyUpgrade[cap.upgrade] > 0) {
 			V.AProsperityCap = cap.cap;
 		}
- });
+	});
 
- for (let i = 0; i < V.sectors.length; i++) {
+	for (let i = 0; i < V.sectors.length; i++) {
 		if (V.sectors[i].type.includes("Apartments")) {
 			V.AProsperityCap += V.sectors[i].type.includes("Luxury") ? 15 : 10;
 		} else if (V.sectors[i].type.includes("Sweatshops")) {
 			V.Sweatshops++;
 		}
- }
+	}
 
- V.AProsperityCap += V.AProsperityCapModified;
+	V.AProsperityCap += V.AProsperityCapModified;
 };
diff --git a/src/js/generateGenetics.js b/src/js/generateGenetics.js
index 7e4993b7b1fe3c00d3987e9fe60597800da01513..548d119fb77dd6a6e779fdefc0974dda29ee7e32 100644
--- a/src/js/generateGenetics.js
+++ b/src/js/generateGenetics.js
@@ -12,8 +12,14 @@ window.generateGenetics = (function() {
 	// intelligence and face parameters are the same so we can use the same distribution for both values
 	// clamping makes edge values (-100, 100) more likely; this is expected behavior
 	// please see https://gitgud.io/pregmodfan/fc-pregmod/issues/852
-	const fuzzy = (a, b) => Math.clamp(normalRandInt((a+b)/2, 20), -100, 100);
+	const fuzzy = (a, b) => Math.clamp(normalRandInt((a + b) / 2, 20), -100, 100);
 
+	/**
+	 * @param {App.Entity.SlaveState} actor1
+	 * @param {number} actor2 Slave ID of actor 2
+	 * @param {number} x
+	 * @returns
+	 */
 	function generateGenetics(actor1, actor2, x) {
 		genes = {
 			gender: "XX",
@@ -38,7 +44,8 @@ window.generateGenetics = (function() {
 			underArmHStyle: "bushy",
 			clone: 0,
 			cloneID: 0,
-			geneticQuirks: 0
+			geneticQuirks: {},
+			fetish: "none"
 		};
 		if (actor1.ID > 0) {
 			mother = V.genePool.find(s => s.ID === actor1.ID);
@@ -658,7 +665,13 @@ window.generateGenetics = (function() {
 		return shape;
 	}
 
-	// genetic quirks
+	/**
+	 * Genetic quirks
+	 * @param {App.Entity.SlaveState|number} father
+	 * @param {App.Entity.SlaveState} mother
+	 * @param {string} sex
+	 * @returns {Object}
+	 */
 	function setGeneticQuirks(father, mother, sex) {
 		let quirks = {
 			macromastia: 0,
@@ -852,7 +865,7 @@ window.generateGenetics = (function() {
 			chance = jsRandom(1, 16);
 			if (chance <= genetarget) {
 				quirks.pFace = 2;
-			} else if (chance <= 3*genetarget) {
+			} else if (chance <= 3 * genetarget) {
 				quirks.pFace = 1;
 			}
 		}
@@ -866,7 +879,7 @@ window.generateGenetics = (function() {
 			chance = jsRandom(1, 16);
 			if (chance <= genetarget) {
 				quirks.uFace = 2;
-			} else if (chance <= 3*genetarget) {
+			} else if (chance <= 3 * genetarget) {
 				quirks.uFace = 1;
 			}
 		}
@@ -880,7 +893,7 @@ window.generateGenetics = (function() {
 			chance = jsRandom(1, 16);
 			if (chance <= genetarget) {
 				quirks.gigantism = 2;
-			} else if (chance <= 3*genetarget) {
+			} else if (chance <= 3 * genetarget) {
 				quirks.gigantism = 1;
 			}
 		}
@@ -894,7 +907,7 @@ window.generateGenetics = (function() {
 			chance = jsRandom(1, 16);
 			if (chance <= genetarget) {
 				quirks.dwarfism = 2;
-			} else if (chance <= 3*genetarget) {
+			} else if (chance <= 3 * genetarget) {
 				quirks.dwarfism = 1;
 			}
 		}
@@ -908,7 +921,7 @@ window.generateGenetics = (function() {
 			chance = jsRandom(1, 16);
 			if (chance <= genetarget) {
 				quirks.albinism = 2;
-			} else if (chance <= 3*genetarget) {
+			} else if (chance <= 3 * genetarget) {
 				quirks.albinism = 1;
 			}
 		}
@@ -922,7 +935,7 @@ window.generateGenetics = (function() {
 			chance = jsRandom(1, 16);
 			if (chance <= genetarget) {
 				quirks.heterochromia = 2;
-			} else if (chance <= 3*genetarget) {
+			} else if (chance <= 3 * genetarget) {
 				quirks.heterochromia = 1;
 			}
 		}
@@ -936,7 +949,7 @@ window.generateGenetics = (function() {
 			chance = jsRandom(1, 16);
 			if (chance <= genetarget) {
 				quirks.rearLipedema = 2;
-			} else if (chance <= 3*genetarget) {
+			} else if (chance <= 3 * genetarget) {
 				quirks.rearLipedema = 1;
 			}
 		}
@@ -950,7 +963,7 @@ window.generateGenetics = (function() {
 			chance = jsRandom(1, 16);
 			if (chance <= genetarget) {
 				quirks.gigantomastia = 2;
-			} else if (chance <= 3*genetarget) {
+			} else if (chance <= 3 * genetarget) {
 				quirks.gigantomastia = 1;
 			}
 		}
@@ -964,7 +977,7 @@ window.generateGenetics = (function() {
 			chance = jsRandom(1, 16);
 			if (chance <= genetarget) {
 				quirks.macromastia = 2;
-			} else if (chance <= 3*genetarget) {
+			} else if (chance <= 3 * genetarget) {
 				quirks.macromastia = 1;
 			}
 		}
@@ -978,7 +991,7 @@ window.generateGenetics = (function() {
 			chance = jsRandom(1, 16);
 			if (chance <= genetarget) {
 				quirks.mGain = 2;
-			} else if (chance <= 3*genetarget) {
+			} else if (chance <= 3 * genetarget) {
 				quirks.mGain = 1;
 			}
 		}
@@ -992,7 +1005,7 @@ window.generateGenetics = (function() {
 			chance = jsRandom(1, 16);
 			if (chance <= genetarget) {
 				quirks.mLoss = 2;
-			} else if (chance <= 3*genetarget) {
+			} else if (chance <= 3 * genetarget) {
 				quirks.mLoss = 1;
 			}
 		}
@@ -1006,7 +1019,7 @@ window.generateGenetics = (function() {
 			chance = jsRandom(1, 16);
 			if (chance <= genetarget) {
 				quirks.wGain = 2;
-			} else if (chance <= 3*genetarget) {
+			} else if (chance <= 3 * genetarget) {
 				quirks.wGain = 1;
 			}
 		}
@@ -1020,7 +1033,7 @@ window.generateGenetics = (function() {
 			chance = jsRandom(1, 16);
 			if (chance <= genetarget) {
 				quirks.wLoss = 2;
-			} else if (chance <= 3*genetarget) {
+			} else if (chance <= 3 * genetarget) {
 				quirks.wLoss = 1;
 			}
 		}
@@ -1034,7 +1047,7 @@ window.generateGenetics = (function() {
 			chance = jsRandom(1, 16);
 			if (chance <= genetarget) {
 				quirks.androgyny = 2;
-			} else if (chance <= 3*genetarget) {
+			} else if (chance <= 3 * genetarget) {
 				quirks.androgyny = 1;
 			}
 		}
@@ -1045,6 +1058,9 @@ window.generateGenetics = (function() {
 	return generateGenetics;
 })();
 
+/**
+ * @param {App.Entity.SlaveState} mother
+ */
 window.generateChild = function(mother, ova, destination) {
 	let genes = ova.genetics; // maybe just argument this? We'll see.
 	let pregUpgrade = V.pregnancyMonitoringUpgrade;