code:
/* eslint-disable no-unused-vars */
/* eslint-disable no-undef */
window.sameAssignmentP = function sameAssignmentP(A, B) {
	return A.assignment === B.assignment;
};

window.haveRelationP = function haveRelationP(slave, target) {
	return slave.relationTarget === target.ID;
};

window.haveRelationshipP = function haveRelationshipP(slave, target) {
	return slave.relationshipTarget === target.ID;
};

window.isRivalP = function isRivalP(slave, target) {
	return slave.rivalryTarget === target.ID;
};

window.supremeRaceP = /** @param {App.Entity.SlaveState} slave */ function supremeRaceP(slave) {
	return State.variables.arcologies[0].FSSupremacistRace === slave.race;
};

window.inferiorRaceP = /** @param {App.Entity.SlaveState} slave */ function inferiorRaceP(slave) {
	return State.variables.arcologies[0].FSSubjugationistRace === slave.race;
};

window.hasVisibleHeterochromia = /** @param {App.Entity.SlaveState} slave */ function hasVisibleHeterochromia(slave) {
	return slave.geneticQuirks.heterochromia !== 0 && slave.geneticQuirks.heterochromia !== 1 && slave.geneticQuirks.albinism !== 2 && slave.geneticQuirks.heterochromia !== slave.eyeColor && slave.eyeColor === slave.origEye;
};

window.isLeaderP = /** @param {App.Entity.SlaveState} slave */ function isLeaderP(slave) {
	const V = State.variables;
	/** @type {App.Entity.SlaveState[]}*/
	const leaders = [V.HeadGirl, V.Bodyguard, V.Recruiter, V.Concubine, V.Nurse, V.Attendant, V.Matron, V.Madam, V.DJ, V.Milkmaid, V. Farmer, V.Stewardess, V.Schoolteacher, V.Wardeness];
	return leaders.some(leader => leader.ID && leader.ID === slave.ID);
};

// helper function returning PC's title
window.properTitle = function properTitle() {
	const PC = State.variables.PC;
	if (PC.customTitle) return PC.customTitle;
	else if (PC.title !== 0) return "Sir";
	else return "Ma'am";
};

// helper function returning slave's title for PC in situations where WrittenMaster() is inappropriate
window.properMaster = function properMaster() {
	const PC = State.variables.PC;
	if (PC.customTitle) return PC.customTitle;
	else if (PC.title !== 0) return "Master";
	else return "Mistress";
};

window.newSlave = /** @param {App.Entity.SlaveState} slave */ function newSlave(slave) {
	const V = State.variables;

	if (slave.override_Eye_Color !== 1) {
		switch (slave.eyeColor) {
			case "blind blue":
				slave.origEye = "deep blue";
				break;
			case "milky white":
			case "implant":
				slave.origEye = jsEither(["blue", "brown", "dark blue", "dark green", "green", "hazel", "light blue", "light green"]);
				break;
			default:
				slave.origEye = slave.eyeColor;
				break;
		}
	}

	if (slave.override_Race !== 1) {
		slave.origRace = slave.race;
	}
	if (slave.override_H_Color !== 1) {
		slave.origHColor = slave.hColor;
	}
	if (slave.override_Arm_H_Color !== 1) {
		slave.underArmHColor = slave.hColor;
	}
	if (slave.override_Pubic_H_Color !== 1) {
		slave.pubicHColor = slave.hColor;
	}
	if (slave.override_Brow_H_Color !== 1) {
		slave.eyebrowHColor = slave.hColor;
	}
	if (slave.override_Skin !== 1) {
		if ((slave.skin === "sun tanned") || (slave.skin === "spray tanned")) {
			slave.origSkin = randomRaceSkin(slave.origRace);
		} else {
			slave.origSkin = slave.skin;
		}
	}

	slave.override_Race = 0;
	slave.override_H_Color = 0;
	slave.override_Arm_H_Color = 0;
	slave.override_Pubic_H_Color = 0;
	slave.override_Brow_H_Color = 0;
	slave.override_Skin = 0;
	slave.override_Eye_Color = 0;

	if (V.surnamesForbidden === 1) {
		slave.slaveSurname = 0;
	}

	if (slave.preg > 0) {
		slave.pregWeek = slave.preg;
	} else {
		slave.pregWeek = 0;
	}

	if (slave.clone !== 0) {
		slave.canRecruit = 0;
	}

	if (V.familyTesting === 1) {
		slave.sisters = 0;
		slave.daughters = 0;
		if (slave.mother === -1 || slave.father === -1) {
			V.PC.daughters += 1;
		}
		if (areSisters(V.PC, slave) > 0) {
			V.PC.sisters += 1;
		}
		for (let k = 0; k < V.slaves.length; k++) {
			if (V.slaves[k].mother === slave.ID || V.slaves[k].father === slave.ID) {
				slave.daughters++;
			}
			if (slave.mother === V.slaves[k].ID || slave.father === V.slaves[k].ID) {
				V.slaves[k].daughters++;
			}
			if (areSisters(V.slaves[k], slave) > 0) {
				slave.sisters++;
				V.slaves[k].sisters++;
			}
		}
	}

	if (slave.dick > 0 &&
		slave.balls > 0 &&
		slave.devotion <= 50 &&
		(slave.fetish !== "buttslut" || slave.fetishKnown !== 1) &&
		slave.sexualFlaw !== "hates women") {
		V.REFeminizationCheckinIDs.push(slave.ID);
	}
	if (slave.actualAge > 35 && slave.face < 40 && slave.skill.anal <= 30) {
		V.REMILFCheckinIDs.push(slave.ID);
	}
	if (slave.attrXY <= 60 && slave.attrXX > 60 ) {
		V.REOrientationCheckinIDs.push(slave.ID);
	}
	if (slave.face < -10) {
		V.REUglyCheckinIDs.push(slave.ID);
	}
	if (slave.anus < 2) {
		V.REButtholeCheckinIDs.push(slave.ID);
	}
	if (slave.boobs < 800) {
		V.REReductionCheckinIDs.push(slave.ID);
	}

	generatePronouns(slave);
	SetBellySize(slave);
	addSlave(slave);

	if (slave.origin !== "She was your slave, but you freed her, which she repaid by participating in a coup attempt against you. It failed, and she is again your chattel." && slave.ID !== V.boomerangSlave.ID) {
		V.genePool.push(slave);
		/* Store non-albino stats in genePool */
		if (slave.geneticQuirks.albinism === 2) {
			const albInd = V.genePool.findIndex(function(s) { return s.ID === slave.ID; });
			V.genePool.genePool[albInd].origSkin = slave.albinismOverride.skin;
			V.genePool.genePool[albInd].origEye = slave.albinismOverride.eyeColor;
			V.genePool.genePool[albInd].origHColor = slave.albinismOverride.hColor;
			V.genePool.genePool[albInd].underArmHColor = slave.albinismOverride.hColor;
			V.genePool.genePool[albInd].pubicHColor = slave.albinismOverride.hColor;
			V.genePool.genePool[albInd].eyebrowHColor = slave.albinismOverride.hColor;
			slave.albinismOverride = 0;
		}
	} else {
		if (V.genePool.findIndex(function(s) { return s.ID === slave.ID; }) === -1) {
			V.genePool.push(slave);
		}
	}

	assignJob(slave, slave.assignment);

	/** do not run the Rules Assistant before adding the new slave to the slaves list! **/
	if (V.ui !== "start" && V.universalRulesNewSlavesRA === 1 && V.rulesAssistantAuto !== 0) {
		DefaultRules(slave);
	}
};

window.newChild = /** @param {App.Entity.SlaveState} slave */ function newChild(child) {
	const V = State.variables;

	child.age = 0; /* not sure if this is the correct way to do this or if more is required */
	child.birthWeek = 0; /* Child comes out at 0,0. That's all that's needed. The specifics are defined later.*/

	if (child.override_Eye_Color !== 1) {
		switch (child.eyeColor) {
			case "blind blue":
				child.origEye = "deep blue";
				break;
			case "milky white":
			case "implant":
				child.origEye = jsEither(["blue", "brown", "dark blue", "dark green", "green", "hazel", "light blue", "light green"]);
				break;
			default:
				child.origEye = child.eyeColor;
				break;
		}
	}

	if (child.override_Race !== 1) {
		child.origRace = child.race;
	}
	if (child.override_H_Color !== 1) {
		child.origHColor = child.hColor;
	}
	if (child.override_Arm_H_Color !== 1) {
		child.underArmHColor = child.hColor;
	}
	if (child.override_Pubic_H_Color !== 1) {
		child.pubicHColor = child.hColor;
	}
	if (child.override_Brow_H_Color !== 1) {
		child.eyebrowHColor = child.hColor;
	}
	if (child.override_Skin !== 1) {
		child.origSkin = child.skin;
	}

	child.override_Race = 0;
	child.override_H_Color = 0;
	child.override_Arm_H_Color = 0;
	child.override_Pubic_H_Color = 0;
	child.override_Brow_H_Color = 0;
	child.override_Skin = 0;
	child.override_Eye_Color = 0;

	if (V.surnamesForbidden === 1) {
		child.childSurname = 0;
	}

	if (child.clone !== 0) {
		child.canRecruit = 0;
	}

	if (child.fuckdoll > 0) {
		child.pronoun = "it";
		child.possessivePronoun = "its";
		child.possessive = "its";
		child.object = "it";
		child.objectReflexive = "itself";
		child.noun = "toy";
	} else if (child.dick > 0 && child.vagina === -1 && V.diversePronouns === 1) {
		child.pronoun = "he";
		child.possessivePronoun = "his";
		child.possessive = "his";
		child.object = "him";
		child.objectReflexive = "himself";
		child.noun = "boy";
	} else {
		child.pronoun = "she";
		child.possessivePronoun = "hers";
		child.possessive = "her";
		child.object = "her";
		child.objectReflexive = "herself";
		child.noun = "girl";
	}
	State.variables.cribs.push(child);
	State.variables.nurseryBabies++;
};

window.addSlave = /** @param {App.Entity.SlaveState} slave */ function addSlave(slave) {
	State.variables.slaves.push(slave);
	State.variables.slaveIndices[slave.ID] = State.variables.slaves.length - 1;
};
window.removeSlave = function removeSlave(index) {
	const ret = State.variables.slaves.deleteAt(index);
	State.variables.slaveIndices = slaves2indices();
	return ret;
};
window.removeChild = function removeChild(index) {
	const ret = State.variables.cribs.deleteAt(index);
	return ret;
};
window.slaves2indices = function slaves2indices() {
	const obj = {};
	State.variables.slaves.forEach((slave, i) => obj[slave.ID] = i);
	return obj;
};
window.getSlave = /** @returns {App.Entity.SlaveState} */ function getSlave(ID) {
	const index = State.variables.slaveIndices[ID];
	if (index === undefined) return undefined;
	else return State.variables.slaves[index];
};
window.getChild = function getChild(ID) {
	const V = State.variables;
	return V.cribs.find(function(s) { return s.ID === ID; });
};
window.getPronouns = /** @param {App.Entity.SlaveState} slave */ function getPronouns(slave) {
	return {
		pronoun: slave.pronoun,
		possessivePronoun: slave.possessivePronoun,
		possessive: slave.possessive,
		object: slave.object,
		objectReflexive: slave.objectReflexive,
		noun: slave.noun};
};

window.SlavePronouns = /** @param {App.Entity.SlaveState} slave */ function SlavePronouns(slave) {
	const V = State.variables;
	const pronouns = getPronouns(slave);
	V.pronoun = pronouns.pronoun;
	V.pronounCap = capFirstChar(pronouns.pronoun);
	V.possessive = pronouns.possessive;
	V.possessiveCap = capFirstChar(pronouns.possessive);
	V.object = pronouns.object;
};

window.WrittenMaster = /** @param {App.Entity.SlaveState} slave */ function WrittenMaster(slave) {
	const V = State.variables;
	if (slave !== undefined)
		Enunciate(slave);
	else if (V.titleEnunciate === undefined)
		Enunciate(V.activeSlave);
	return V.writtenTitle;
};

window.Enunciate = /** @param {App.Entity.SlaveState} slave */ function Enunciate(slave) {
	const V = State.variables;
	if (SlaveStatsChecker.checkForLisp(slave)) {
		if (V.PC.customTitleLisp !== undefined)
			V.titleEnunciate = V.PC.customTitleLisp;
		else if (V.PC.title !== 0)
			V.titleEnunciate = "Mathter";
		else
			V.titleEnunciate = "Mithtreth";
		if (V.allowFamilyTitles === 1) {
			if (slave.father === -1) {
				if (slave.actualAge < 4 && slave.physicalAge < 4)
					V.titleEnunciate = "Dadda";
				else if (slave.actualAge < 9)
					V.titleEnunciate = "Daddy";
				else
					V.titleEnunciate = "Dad";
			} else if (slave.mother === -1) {
				if (slave.actualAge < 4 && slave.physicalAge < 4)
					V.titleEnunciate = "Mama";
				else if (slave.actualAge < 9)
					V.titleEnunciate = "Mommy";
				else
					V.titleEnunciate = "Mom";
			} else if (V.PC.mother === slave.ID || V.PC.father === slave.ID) {
				if (V.PC.title === 1)
					V.titleEnunciate = "Thon";
				else if (V.PC.title === 0)
					V.titleEnunciate = "Daughter";
			} else if (areSisters(slave, V.PC) > 0) {
				if (V.PC.title === 1) {
					if (slave.actualAge < 18)
						V.titleEnunciate = "Bro";
					else
						V.titleEnunciate = "Brother";
				} else if (V.PC.title === 0) {
					if (slave.actualAge < 18)
						V.titleEnunciate = "Thith";
					else
						V.titleEnunciate = "Thithter";
				}
			}
		}
		if (slave.custom.titleLisp && slave.custom.titleLisp !== "")
			V.titleEnunciate = slave.custom.titleLisp;
		V.sayEnunciate = "lisp";
		V.sEnunciate = "th";
		V.SEnunciate = "Th";
		V.ssEnunciate = "th";
		V.cEnunciate = "th";
		V.CEnunciate = "Th";
		V.ccEnunciate = "kth";
		V.zEnunciate = "th";
		V.ZEnunciate = "Th";
		V.chEnunciate = "th";
		V.ChEnunciate = "Th";
		V.psEnunciate = "th";
		V.PsEnunciate = "Th";
		V.shEnunciate = "th";
		V.ShEnunciate = "Th";
		V.scEnunciate = "th";
		V.ScEnunciate = "Th";
		V.schEnunciate = "th";
		V.SchEnunciate = "Th";
		V.xEnunciate = "kth";
		V.XEnunciate = "Th";
	} else {
		if (V.PC.customTitle !== undefined)
			V.titleEnunciate = V.PC.customTitle;
		else if (V.PC.title !== 0)
			V.titleEnunciate = "Master";
		else
			V.titleEnunciate = "Mistress";
		if (V.allowFamilyTitles === 1) {
			if (slave.father === -1) {
				if (slave.actualAge < 4 && slave.physicalAge < 4)
					V.titleEnunciate = "Dadda";
				else if (slave.actualAge < 9)
					V.titleEnunciate = "Daddy";
				else
					V.titleEnunciate = "Dad";
			} else if (slave.mother === -1) {
				if (slave.actualAge < 4 && slave.physicalAge < 4)
					V.titleEnunciate = "Mama";
				else if (slave.actualAge < 9)
					V.titleEnunciate = "Mommy";
				else
					V.titleEnunciate = "Mom";
			} else if (V.PC.mother === slave.ID || V.PC.father === slave.ID) {
				if (V.PC.title === 1)
					V.titleEnunciate = "Son";
				else if (V.PC.title === 0)
					V.titleEnunciate = "Daughter";
			} else if (areSisters(slave, V.PC) > 0) {
				if (V.PC.title === 1) {
					if (slave.actualAge < 18)
						V.titleEnunciate = "Bro";
					else
						V.titleEnunciate = "Brother";
				} else if (V.PC.title === 0) {
					if (slave.actualAge < 18)
						V.titleEnunciate = "Sis";
					else
						V.titleEnunciate = "Sister";
				}
			}
		}
		if (slave.custom.title !== undefined && slave.custom.title !== "")
			V.titleEnunciate = slave.custom.title;
		if (V.PC.customTitle !== undefined)
			V.writtenTitle = V.PC.customTitle;
		else if (V.PC.title !== 0)
			V.writtenTitle = "Master";
		else
			V.writtenTitle = "Mistress";
		if (slave.custom.title !== undefined && slave.custom.title !== "" && slave.rudeTitle === 0)
			V.writtenTitle = slave.custom.title;
		V.sayEnunciate = "say";
		V.sEnunciate = "s";
		V.SEnunciate = "S";
		V.ssEnunciate = "ss";
		V.cEnunciate = "c";
		V.CEnunciate = "C";
		V.ccEnunciate = "cc";
		V.zEnunciate = "z";
		V.ZEnunciate = "Z";
		V.chEnunciate = "ch";
		V.ChEnunciate = "Ch";
		V.psEnunciate = "ps";
		V.PsEnunciate = "Ps";
		V.shEnunciate = "sh";
		V.ShEnunciate = "Sh";
		V.scEnunciate = "sc";
		V.ScEnunciate = "Sc";
		V.schEnunciate = "sch";
		V.SchEnunciate = "Sch";
		V.xEnunciate = "x";
		V.XEnunciate = "X";
	}
};

window.fetishChangeChance = /** @param {App.Entity.SlaveState} slave */ function fetishChangeChance(slave) {
	const V = State.variables;
	let chance = 0, sex = 0;

	if (slave.clitSetting !== slave.fetish) {
		if (slave.balls) {
			sex = V.potencyAge - slave.actualAge;
		}
		else if (slave.ovaries || slave.mpreg) {
			sex = V.fertilityAge - slave.actualAge;
		}
		chance = Math.trunc(Math.clamp((slave.devotion/4)-(slave.fetishStrength/4)-(Math.max(sex, 0)*10), 0, 100));
	}

	return chance;
};

window.SlaveFullName = /** @param {App.Entity.SlaveState} slave */ function SlaveFullName(slave) {
	const V = State.variables;
	const pair = slave.slaveSurname ? [slave.slaveName, slave.slaveSurname] : [slave.slaveName];
	if ((V.surnameOrder !== 1 && ["Cambodian", "Chinese", "Hungarian", "Japanese", "Korean", "Mongolian", "Taiwanese", "Vietnamese"].includes(slave.nationality)) || (V.surnameOrder === 2))
		pair.reverse();
	return pair.join(" ");
};

window.SlaveFullBirthName = /** @param {App.Entity.SlaveState} slave */ function SlaveFullBirthName(slave) {
	const V = State.variables;
	const pair = slave.birthSurname ? [slave.birthName, slave.birthSurname] : [slave.birthName];
	if ((V.surnameOrder !== 1 && ["Cambodian", "Chinese", "Hungarian", "Japanese", "Korean", "Mongolian", "Taiwanese", "Vietnamese"].includes(slave.nationality)) || (V.surnameOrder === 2))
		pair.reverse();
	return pair.join(" ");
};

window.PlayerName = function PlayerName() {
	const V = State.variables;
	const names = V.PC.surname ? [V.PC.name, V.PC.surname] : [V.PC.name];
	if ((V.surnameOrder !== 1 && ["Cambodian", "Chinese", "Hungarian", "Japanese", "Korean", "Mongolian", "Taiwanese", "Vietnamese"].includes(V.PC.nationality)) || (V.surnameOrder === 2))
		names.reverse();
	return names.join(" ");
};

window.PCTitle = function PCTitle() {
	const V = State.variables;
	const titles = [];

	V.PCTitle = PlayerName();

	if (V.cheater === 1) {
		V.PCTitle = (`${V.PCTitle } the Cheater`);
	} else if (V.arcologies[0].FSRestart > 10) {
		V.PCTitle = (`${V.PCTitle } of the Societal Elite`);
	} else if (V.rep > 18000) {
		V.PCTitle = (`${V.PCTitle } the Great`);
	} else if (V.rep > 17000) {
		V.PCTitle = (`the exalted ${ V.PCTitle}`);
	} else if (V.rep > 16000) {
		V.PCTitle = (`the illustrious ${ V.PCTitle}`);
	} else if (V.rep > 15000) {
		V.PCTitle = (`the prestigious ${ V.PCTitle}`);
	} else if (V.rep > 14000) {
		V.PCTitle = (`the renowned ${ V.PCTitle}`);
	} else if (V.rep > 13000) {
		V.PCTitle = (`the famed ${ V.PCTitle}`);
	} else if (V.rep > 12000) {
		V.PCTitle = (`the celebrated ${ V.PCTitle}`);
	} else if (V.rep > 11000) {
		V.PCTitle = (`the honored ${ V.PCTitle}`);
	} else if (V.rep > 10000) {
		V.PCTitle = (`the acclaimed ${ V.PCTitle}`);
	} else if (V.rep > 9000) {
		V.PCTitle = (`the eminent ${ V.PCTitle}`);
	} else if (V.rep > 8250) {
		V.PCTitle = (`the prominent ${ V.PCTitle}`);
	} else if (V.rep > 7500) {
		V.PCTitle = (`the distinguished ${ V.PCTitle}`);
	} else if (V.rep > 6750) {
		V.PCTitle = (`the admired ${ V.PCTitle}`);
	} else if (V.rep > 6000) {
		V.PCTitle = (`the esteemed ${ V.PCTitle}`);
	} else if (V.rep > 5250) {
		V.PCTitle = (`the respected ${ V.PCTitle}`);
	} else if (V.rep > 4500) {
		V.PCTitle = (`the known ${ V.PCTitle}`);
	} else if (V.rep > 3750) {
		V.PCTitle = (`the recognized ${ V.PCTitle}`);
	} else if (V.rep > 3000) {
		V.PCTitle = (`the rumored ${ V.PCTitle}`);
	}

	V.PCTitle = (`${V.PCTitle }, `);

	if (V.PC.name === "FC Dev") {
		titles.push("the Creator");
	}

	if (V.plot === 1) {
		if (V.invasionVictory === 3) {
			if (V.PC.title === 1) {
				titles.push("Hero of the City");
			} else {
				titles.push("Heroine of the City");
			}
		} else if (V.invasionVictory === 2) {
			titles.push("Defender of the City");
		}
		if (V.daughtersVictory === 3) {
			titles.push("Destroyer of the Daughters");
		} else if (V.daughtersVictory === 2) {
			if (V.PC.title === 1) {
				titles.push("Victor over the Daughters");
			} else {
				titles.push("Victrix over the Daughters");
			}
		}
	}

	if (V.SF.Active < -1) {
		switch (V.SF.BadOutcome) {
			case "lockdown":
				titles.push("The War Host");
				break;
			case "Revolt":
				titles.push("The Betrayed");
				break;
			case "Exodus":
				titles.push("The Abandoned");
				break;
			default:
				break;
		}
	}

	if (V.mercenaries >= 5) {
		if (V.mercenariesTitle === "Evocati") {
			titles.push(`Princeps of the ${ V.mercenariesTitle}`);
		} else if (V.mercenariesTitle === "Knights") {
			if (V.PC.title === 1) {
				titles.push(`Lord Commander of the ${ V.mercenariesTitle}`);
			} else {
				titles.push(`Lady Commander of the ${ V.mercenariesTitle}`);
			}
		} else if (V.mercenariesTitle === "Immortals") {
			titles.push(`Tyrant of the ${ V.mercenariesTitle}`);
		} else {
			titles.push(`Commander of the ${ V.mercenariesTitle}`);
		}
	} else if (V.mercenaries >= 1) {
		titles.push("Commander of the Mercenaries");
	}

	if (V.dispensary === 1) {
		if (V.PC.title === 1) {
			titles.push("Pharmacologos");
		} else {
			titles.push("Pharmacologes");
		}
	}

	if (V.arcologies[0].FSSupremacist >= V.FSLockinLevel * 0.9) {
		titles.push("Grand Champion of the Blood");
	} else if (V.arcologies[0].FSSupremacist >= V.FSLockinLevel * 0.6) {
		titles.push("Champion of the Blood");
	} else if (V.arcologies[0].FSSupremacist >= V.FSLockinLevel * 0.3) {
		titles.push("Defender of the Blood");
	}

	if (V.arcologies[0].FSSubjugationist >= V.FSLockinLevel * 0.9) {
		titles.push("Grand Overseer of the Inferior Race");
	} else if (V.arcologies[0].FSSubjugationist >= V.FSLockinLevel * 0.6) {
		titles.push("Overseer of the Inferior Race");
	} else if (V.arcologies[0].FSSubjugationist >= V.FSLockinLevel * 0.3) {
		titles.push("Subduer of the Inferior Race");
	}

	if (V.arcologies[0].FSGenderRadicalist >= V.FSLockinLevel * 0.9) {
		titles.push("Buttfucker of All Slaves");
	} else if (V.arcologies[0].FSGenderRadicalist >= V.FSLockinLevel * 0.6) {
		titles.push("Sodomizer of the Traps");
	} else if (V.arcologies[0].FSGenderRadicalist >= V.FSLockinLevel * 0.3) {
		if (V.PC.title === 1) {
			titles.push("Penetrator of the Sissies");
		} else {
			titles.push("Penetratrix of the Sissies");
		}
	}

	if (V.arcologies[0].FSGenderFundamentalist >= V.FSLockinLevel * 0.9) {
		if (V.PC.title === 1) {
			titles.push("Father to the City");
		} else {
			titles.push("Mother to the City");
		}
	} else if (V.arcologies[0].FSGenderFundamentalist >= V.FSLockinLevel * 0.6) {
		titles.push("Defender of Women");
	} else if (V.arcologies[0].FSGenderFundamentalist >= V.FSLockinLevel * 0.3) {
		titles.push("Restorer of Morals");
	}

	if (V.arcologies[0].FSPaternalist >= V.FSLockinLevel * 0.9) {
		if (V.PC.title === 1) {
			titles.push("Protector to All Slaves");
		} else {
			titles.push("Protectrix to All Slaves");
		}
	} else if (V.arcologies[0].FSPaternalist >= V.FSLockinLevel * 0.6) {
		if (V.PC.title === 1) {
			titles.push("Benefactor of Slaves");
		} else {
			titles.push("Benefactrix of Slaves");
		}
	} else if (V.arcologies[0].FSPaternalist >= V.FSLockinLevel * 0.3) {
		titles.push("Pursuer of Justice");
	}

	if (V.arcologies[0].FSRepopulationFocus >= V.FSLockinLevel * 0.9) {
		titles.push("the Savior of the Future");
	} else if (V.arcologies[0].FSRepopulationFocus >= V.FSLockinLevel * 0.6) {
		titles.push("the Holder of the Future");
	} else if (V.arcologies[0].FSRepopulationFocus >= V.FSLockinLevel * 0.3) {
		titles.push("the Repopulist");
	}

	if (V.arcologies[0].FSDegradationist >= V.FSLockinLevel * 0.9) {
		titles.push("Holder of the Rod and the Lash");
	} else if (V.arcologies[0].FSDegradationist >= V.FSLockinLevel * 0.6) {
		titles.push("Subduer of Slaves");
	} else if (V.arcologies[0].FSDegradationist >= V.FSLockinLevel * 0.3) {
		titles.push("Pursuer of Justice");
	}

	if (V.arcologies[0].FSBodyPurist >= V.FSLockinLevel * 0.9) {
		titles.push("the Purifier of the Breasts");
	} else if (V.arcologies[0].FSBodyPurist >= V.FSLockinLevel * 0.6) {
		titles.push("the Discerning");
	} else if (V.arcologies[0].FSBodyPurist >= V.FSLockinLevel * 0.3) {
		titles.push("the Tasteful");
	}

	if (V.arcologies[0].FSAssetExpansionist >= V.FSLockinLevel * 0.9) {
		titles.push("the Expander of the Breasts");
	} else if (V.arcologies[0].FSAssetExpansionist >= V.FSLockinLevel * 0.6) {
		titles.push("the Expander");
	} else if (V.arcologies[0].FSAssetExpansionist >= V.FSLockinLevel * 0.3) {
		if (V.PC.title === 1) {
			titles.push("the Implantor");
		} else {
			titles.push("the Implantrix");
		}
	}

	if (V.arcologies[0].FSPastoralist >= V.FSLockinLevel * 0.9) {
		if (V.PC.title === 1) {
			titles.push("the Master of Stock");
		} else {
			titles.push("the Mistress of Stock");
		}
	} else if (V.arcologies[0].FSPastoralist >= V.FSLockinLevel * 0.6) {
		titles.push("the Rancher");
	} else if (V.arcologies[0].FSPastoralist >= V.FSLockinLevel * 0.3) {
		titles.push("the Farmer");
	}

	if (V.arcologies[0].FSPhysicalIdealist >= V.FSLockinLevel * 0.9) {
		titles.push("beloved of Brodin");
	} else if (V.arcologies[0].FSPhysicalIdealist >= V.FSLockinLevel * 0.6) {
		if (V.PC.title === 1) {
			titles.push("he of the godlike Body");
		} else {
			titles.push("she of the godlike Body");
		}
	} else if (V.arcologies[0].FSPhysicalIdealist >= V.FSLockinLevel * 0.3) {
		titles.push("advancer of Gains");
	}

	if (V.arcologies[0].FSHedonisticDecadence >= V.FSLockinLevel * 0.9) {
		if (V.PC.title === 1) {
			titles.push("Master of Softness");
		} else {
			titles.push("Lady of Softness");
		}
	} else if (V.arcologies[0].FSHedonisticDecadence >= V.FSLockinLevel * 0.6) {
		titles.push("Thickness Enthusiast");
	} else if (V.arcologies[0].FSHedonisticDecadence >= V.FSLockinLevel * 0.3) {
		titles.push("the Feeder");
	}

	if (V.arcologies[0].FSMaturityPreferentialist >= V.FSLockinLevel * 0.9) {
		titles.push("Grand Preserver of MILFS");
	} else if (V.arcologies[0].FSMaturityPreferentialist >= V.FSLockinLevel * 0.6) {
		titles.push("Fucker of MILFS");
	} else if (V.arcologies[0].FSMaturityPreferentialist >= V.FSLockinLevel * 0.3) {
		if (V.PC.title === 1) {
			titles.push("he of the notorious MILF preference");
		} else {
			titles.push("she of the notorious MILF preference");
		}
	}

	if (V.arcologies[0].FSYouthPreferentialist >= V.FSLockinLevel * 0.9) {
		titles.push("Keeper of the Magnificent Young Harem");
	} else if (V.arcologies[0].FSYouthPreferentialist >= V.FSLockinLevel * 0.6) {
		titles.push("Keeper of Virgins");
	} else if (V.arcologies[0].FSYouthPreferentialist >= V.FSLockinLevel * 0.3) {
		titles.push("the Virginbreaker");
	}

	if (V.arcologies[0].FSChattelReligionistLaw === 1) {
		titles.push("the Prophet");
	} else if (V.arcologies[0].FSChattelReligionist >= V.FSLockinLevel * 0.9) {
		titles.push("Keeper of the Blade and Chalice");
	} else if (V.arcologies[0].FSChattelReligionist >= V.FSLockinLevel * 0.6) {
		titles.push("Champion of the Faith");
	} else if (V.arcologies[0].FSChattelReligionist >= V.FSLockinLevel * 0.3) {
		titles.push("the Holy");
	}

	if (V.arcologies[0].FSRomanRevivalist >= V.FSLockinLevel * 0.9) {
		titles.push("First Consul");
	} else if (V.arcologies[0].FSRomanRevivalist >= V.FSLockinLevel * 0.6) {
		titles.push("Aedile");
	} else if (V.arcologies[0].FSRomanRevivalist >= V.FSLockinLevel * 0.3) {
		titles.push("Quaestor");
	}

	if (V.arcologies[0].FSAztecRevivalist >= V.FSLockinLevel * 0.9) {
		titles.push("Tlatcani");
	} else if (V.arcologies[0].FSAztecRevivalist >= V.FSLockinLevel * 0.6) {
		titles.push("Cihuacoatl");
	} else if (V.arcologies[0].FSAztecRevivalist >= V.FSLockinLevel * 0.3) {
		titles.push("Tlatoani");
	}

	if (V.arcologies[0].FSEgyptianRevivalist >= V.FSLockinLevel * 0.9) {
		if (V.PC.title === 1) {
			titles.push("the Living God");
		} else {
			titles.push("the Living Goddess");
		}
	} else if (V.arcologies[0].FSEgyptianRevivalist >= V.FSLockinLevel * 0.6) {
		titles.push("Pharaoh");
	} else if (V.arcologies[0].FSEgyptianRevivalist >= V.FSLockinLevel * 0.3) {
		if (V.PC.title === 1) {
			titles.push("Prince of the Nile");
		} else {
			titles.push("Princess of the Nile");
		}
	}

	if (V.arcologies[0].FSEdoRevivalist >= V.FSLockinLevel * 0.9) {
		if (V.PC.title === 1) {
			titles.push("Emperor and Descendant of Amaterasu");
		} else {
			titles.push("Amaterasu Reborn");
		}
	} else if (V.arcologies[0].FSEdoRevivalist >= V.FSLockinLevel * 0.6) {
		titles.push("Shogun");
	} else if (V.arcologies[0].FSEdoRevivalist >= V.FSLockinLevel * 0.3) {
		titles.push("Daimyo");
	}

	if (V.arcologies[0].FSArabianRevivalist >= V.FSLockinLevel * 0.9) {
		if (V.PC.title === 1) {
			titles.push("Caliph");
		} else {
			titles.push("Handmaiden of Allah");
		}
	} else if (V.arcologies[0].FSArabianRevivalist >= V.FSLockinLevel * 0.6) {
		if (V.PC.title === 1) {
			titles.push("Sultan");
		} else {
			titles.push("Sultana");
		}
	} else if (V.arcologies[0].FSArabianRevivalist >= V.FSLockinLevel * 0.3) {
		titles.push("Beloved of Allah");
	}

	if (V.arcologies[0].FSChineseRevivalist >= V.FSLockinLevel * 0.9) {
		if (V.PC.title === 1) {
			titles.push("Emperor and Holder of the Mandate of Heaven");
		} else {
			titles.push("Empress and Holder of the Mandate of Heaven");
		}
	} else if (V.arcologies[0].FSChineseRevivalist >= V.FSLockinLevel * 0.6) {
		if (V.PC.title === 1) {
			titles.push("Emperor");
		} else {
			titles.push("Empress");
		}
	} else if (V.arcologies[0].FSChineseRevivalist >= V.FSLockinLevel * 0.3) {
		if (V.PC.title === 1) {
			titles.push("Governor of the Province");
		} else {
			titles.push("Governess of the Province");
		}
	}

	if (V.brothelSlaves >= 15) {
		if (V.PC.title === 1) {
			titles.push("Procurator of the Brothel");
		} else {
			titles.push("Procuratrix of the Brothel");
		}
	}

	if (V.clubSlaves >= 15) {
		titles.push("First on the Club");
	}
	if (V.dairySlaves >= 15) {
		titles.push("Keeper of the Cattle");
	}
	if (V.cumSlaves >= 15) {
		if (V.PC.title === 1) {
			titles.push("Extractor of the Ejaculate");
		} else {
			titles.push("Extractrix of the Ejaculate");
		}
	}
	if (V.servantsQuartersSlaves >= 15) {
		if (V.PC.title === 1) {
			titles.push("Director of the Servants");
		} else {
			titles.push("Directrix of the Servants");
		}
	}
	if (V.schoolroomSlaves >= 10) {
		if (V.PC.title === 1) {
			titles.push("Educator of the Slaves");
		} else {
			titles.push("Educatrix of the Slaves");
		}
	}
	if (V.spaSlaves >= 10) {
		titles.push("Order of the Bath");
	}
	if (V.arcadeSlaves >= 15) {
		titles.push("Comptroller of the Arcade");
	}
	if (V.nurseryBabies >= 10) {
		titles.push("Caretaker of the Youth");
	}

	const schoolsPresent = []; const schoolsPerfected = []; let schoolTitle = "";
	if (V.TSS.schoolProsperity >= 10) {
		schoolsPerfected.push("The Slave School");
	} else if (V.TSS.schoolPresent === 1) {
		schoolsPresent.push("The Slave School");
	}
	if (V.GRI.schoolProsperity >= 10) {
		schoolsPerfected.push("The Growth Research Institute");
	} else if (V.GRI.schoolPresent === 1) {
		schoolsPresent.push("The Growth Research Institute");
	}
	if (V.SCP.schoolProsperity >= 10) {
		schoolsPerfected.push("St. Claver Preparatory");
	} else if (V.SCP.schoolPresent === 1) {
		schoolsPresent.push("St. Claver Preparatory");
	}
	if (V.LDE.schoolProsperity >= 10) {
		schoolsPerfected.push("L'École des Enculées");
	} else if (V.LDE.schoolPresent === 1) {
		schoolsPresent.push("L'École des Enculées");
	}
	if (V.TGA.schoolProsperity >= 10) {
		schoolsPerfected.push("The Gymnasium-Academy");
	} else if (V.TGA.schoolPresent === 1) {
		schoolsPresent.push("The Gymnasium-Academy");
	}
	if (V.HA.schoolProsperity >= 10) {
		schoolsPerfected.push("The Hippolyta Academy");
	} else if (V.HA.schoolPresent === 1) {
		schoolsPresent.push("The Hippolyta Academy");
	}
	if (V.TCR.schoolProsperity >= 10) {
		schoolsPerfected.push("The Cattle Ranch");
	} else if (V.TCR.schoolPresent === 1) {
		schoolsPresent.push("The Cattle Ranch");
	}
	if (schoolsPerfected.length > 0) {
		if (V.PC.title === 1) {
			schoolTitle = "Benefactor of ";
		} else {
			schoolTitle = "Benefactrix of ";
		}
		if (schoolsPerfected.length === 1) {
			schoolTitle += schoolsPerfected[0];
		} else if (schoolsPerfected.length === 2) {
			schoolTitle += `${schoolsPerfected[0] } and ${ schoolsPerfected[1]}`;
		} else {
			schoolsPerfected[schoolsPerfected.length - 1] = `and ${ schoolsPerfected[schoolsPerfected.length - 1]}`;
			schoolTitle += schoolsPerfected.join(", ");
		}
		titles.push(schoolTitle);
	}

	if (schoolsPresent.length > 0) {
		schoolTitle = "Supporter of ";
		if (schoolsPresent.length === 1) {
			schoolTitle += schoolsPresent[0];
		} else if (schoolsPresent.length === 2) {
			schoolTitle += `${schoolsPresent[0] } and ${ schoolsPresent[1]}`;
		} else {
			schoolsPresent[schoolsPresent.length - 1] = `and ${ schoolsPresent[schoolsPresent.length - 1]}`;
			schoolTitle += schoolsPresent.join(", ");
		}
		titles.push(schoolTitle);
	}

	if (V.TFS.schoolProsperity >= 10) {
		titles.push("Honorary Sibling of the Futanari Sisters");
	} else if (V.TFS.schoolPresent === 1) {
		if (V.PC.title === 1) {
			titles.push("Protector of the Futanari Sisters");
		} else {
			titles.push("Protectrix of the Futanari Sisters");
		}
	}

	if (V.slaves.length > 50) {
		if (V.PC.title === 1) {
			titles.push("Master of Slaves");
		} else {
			titles.push("Mistress of Slaves");
		}
	} else if (V.slaves.length > 40) {
		titles.push("Holder of Slaves");
	} else if (V.slaves.length > 30) {
		titles.push("Keeper of Slaves");
	} else if (V.slaves.length > 20) {
		titles.push("Manager of Slaves");
	} else if (V.slaves.length > 10) {
		titles.push("owner of slaves");
	}

	if (V.corpValue > 500000) {
		titles.push("Corporate Titan");
	} else if (V.corpValue > 250000) {
		titles.push("corporate innovator");
	} else if (V.corpValue > 100000) {
		titles.push("corporate founder");
	} else if (V.corpValue > 0) {
		if (V.PC.title === 1) {
			titles.push("noted corporate businessman");
		} else {
			titles.push("noted corporate businesswoman");
		}
	}

	if (V.rep > 18000) {
		if (V.PC.title === 1) {
			titles.push("unquestioned Master of the Arcology");
		} else {
			titles.push("unquestioned Mistress of the Arcology");
		}
	} else if (V.rep > 15000) {
		if (V.PC.title === 1) {
			titles.push("Lord of the Arcology");
		} else {
			titles.push("Lady of the Arcology");
		}
	} else if (V.rep > 12000) {
		titles.push("Ruler of the Arcology");
	} else if (V.rep > 9000) {
		titles.push("chief officer of the arcology");
	} else {
		titles.push("owner of the arcology");
	}

	if (titles.length === 1) {
		V.PCTitle += titles[0];
	} else if (titles.length === 2) {
		V.PCTitle += `${titles[0] } and ${ titles[1]}`;
	} else {
		titles[titles.length - 1] = `and ${ titles[titles.length - 1]}`;
		V.PCTitle += titles.join(", ");
	}
};

window.PoliteRudeTitle = /** @param {App.Entity.SlaveState} slave */ function PoliteRudeTitle(slave) {
	const V = State.variables;
	const PC = V.PC;
	const s = V.sEnunciate;
	const ss = V.ssEnunciate;

	let r = "";
	if (slave.nationality === "Japanese") {
		if (slave.trust > 0) {
			r += `${PC.name}${PC.title > 0 ? "kun" : "chan"}`;
		} else {
			r += (PC.surname ? PC.surname : `${PC.name}${s}an`);
		}
	} else {
		if (slave.intelligence+slave.intelligenceImplant < -95) {
			r += V.titleEnunciate;
		} else if (slave.intelligence+slave.intelligenceImplant > 50) {
			r += (PC.title > 0 ? `Ma${s}ter` : `Mi${s}tre${ss}`);
		} else if (slave.trust > 0) {
			r += PC.name;
		} else {
			r += (PC.surname ? PC.surname : PC.name);
		}
	}
	return r;
};

window.SlaveTitle = /** @param {App.Entity.SlaveState} slave */ function SlaveTitle(slave) {
	const V = State.variables;
	let r = "";
	if (V.newDescriptions === 1) {
		if (slave.dick > 0 && slave.balls > 0 && slave.boobs > 300 && slave.vagina > -1 && slave.ovaries === 1) {
			if (jsRandom(1, 100) > 50) {
				r = "futanari";
			} else {
				r = "herm";
			}
		} else if (slave.dick > 0 && slave.balls === 0 && slave.boobs > 300 && slave.vagina > -1 && slave.ovaries === 1) {
			r = "dickgirl";
		} else if (slave.dick > 0 && slave.vagina > -1 && slave.ovaries === 0) {
			r = "shemale";
		} else if (slave.dick > 0 && slave.balls === 0 && slave.vagina === -1 && slave.ovaries === 0) {
			r = "eunuch";
		} else if (slave.dick > 0 && slave.balls > 0 && slave.vagina === -1 && slave.ovaries === 0) {
			if (slave.face > 10 && slave.hips > -1 && slave.shoulders < 1 && slave.faceShape !== "masculine") {
				r = "trap";
			} else if (slave.boobs > 800) {
				r = "tittyboy";
			} else if (slave.dick === 1 && slave.balls === 1) {
				r = "sissy";
			} else if (slave.dick > 1 && slave.balls > 1 && slave.height < 165 && slave.muscles < 5 && slave.visualAge < 19 && slave.faceShape !== "masculine") {
				r = "twink";
			} else if (slave.dick > 1 && slave.balls > 1 && slave.height < 160 && slave.muscles < 5 && slave.visualAge < 19) {
				r = "boytoy";
			} else if (slave.muscles > 95 && slave.height >= 185) {
				r = "titan";
			} else if (slave.muscles > 30) {
				r = "muscleboy";
			} else {
				r = "slaveboy";
			}
		} else if (slave.dick === 0 && slave.balls === 0 && slave.vagina > -1) {
			if ((slave.shoulders > slave.hips || slave.faceShape === "masculine") && slave.boobs < 400 && slave.genes === "XY") {
				r = "cuntboy";
			} else if (slave.ovaries === 0 && slave.genes === "XY") {
				r = "tranny";
			} else if (slave.weight > 10 && slave.boobs > 800 && slave.counter.birthsTotal > 0 && slave.physicalAge > 59) {
				r = "GMILF";
			} else if (slave.weight > 10 && slave.boobs > 800 && slave.counter.birthsTotal > 0 && slave.physicalAge > 35) {
				r = "MILF";
			} else if (slave.lips > 70 && slave.boobs > 2000 && slave.butt > 3) {
				r = "bimbo";
			} else if (slave.hips > 1 && slave.boobs > 2000 && slave.butt > 3 && slave.waist < 50) {
				r = "hourglass";
			} else if (slave.muscles > 95 && slave.height >= 185) {
				r = "amazon";
			} else if (slave.muscles > 30) {
				r = "musclegirl";
			} else {
				r = "slavegirl";
			}
		} else if (slave.dick === 0 && slave.balls === 0 && slave.vagina === -1) {
			r = "neuter";
		} else if (slave.dick === 0 && slave.vagina === -1) {
			r = "ballslave";
		} else {
			r = "slave";
		}

		if (slave.visualAge < 13) {
			if (slave.genes === "XY" && slave.vagina === -1) {
				r = `shota ${ r}`;
			} else {
				r = `loli ${ r}`;
			}
		}

		if (slave.geneticQuirks.albinism === 2) {
			r = `albino ${ r}`;
		}

		if (slave.dick > 9 && slave.balls > 9 && slave.boobs > 12000) {
			r = `hyper ${ r}`;
		}

		if (slave.boobs > 4000 && slave.lactation > 0) {
			if (slave.physicalAge < 13) {
				r = `${r } calf`;
			} else {
				r = `${r } cow`;
			}
		} else if (slave.lactation > 0) {
			r = `milky ${ r}`;
		}

		if (slave.boobs > 20000) {
			r = `supermassive titted ${ r}`;
		} else if (slave.boobs > 10000) {
			r = `giant titted ${ r}`;
		} else if (slave.boobs > 4000) {
			r = `huge titted ${ r}`;
		} else if (slave.boobs > 1000) {
			r = `busty ${ r}`;
		}

		if (slave.dick > 5 && slave.balls > 5) {
			r = `womb filling ${ r}`;
		} else if (slave.dick > 5) {
			r = `well hung ${ r}`;
		}

		if (slave.butt >= 12) {
			r = `colossal assed ${ r}`;
		} else if (slave.butt >= 12) {
			r = `massive assed ${ r}`;
		} else if (slave.butt >= 8) {
			r = `fat assed ${ r}`;
		} else if (slave.butt >= 6) {
			r = `bottom heavy ${ r}`;
		} else if (slave.butt >= 4) {
			r = `big bottomed ${ r}`;
		}

		if (slave.weight > 10 && slave.weight < 100 && slave.boobs > 5000 && slave.butt > 5 && slave.hips >= 2 && slave.bellyPreg >= 30000 && slave.counter.births >= 10) {
			r = `${r } fertility goddess`;
		} else if (slave.counter.births >= 6) {
			r = `${r } broodmother`;
		} else if (slave.counter.births >= 3) {
			r = `${r } breeder`;
		}

		if (slave.indenture > -1) {
			r = `indentured ${ r}`;
		}

		if (slave.preg > slave.pregData.normalBirth/4 && slave.pregKnown === 1) {
			r = `pregnant ${ r}`;
		} else if (slave.bellyFluid >= 5000) {
			r = `bloated ${ r}`;
		} else if (slave.belly >= 5000) {
			r = `gravid ${ r}`;
		}

		if (slave.fuckdoll > 0) {
			r = `${r } fuckdoll`;
		}
	} else {
		r = "slave"; /* I don't tihnk there is an 'else'? */
		if ((slave.dick === 0) && (slave.vagina === -1)) { /* NULLS */
			r = "null";
			if ((slave.lactation > 0) && (slave.boobs > 2000)) {
				r = `${r } cow`;
			} else if ((slave.boobsImplant > 0) && (slave.buttImplant > 0)) {
				r = `${r } bimbo `;
			} else if (slave.boobs > 6000) {
				r = `${r } boob`;
			} else if (slave.butt > 6) {
				r = `${r } ass`;
			} else if ((slave.muscles > 30) && (slave.height < 185)) {
				r = `${r } muscle`;
			}
			if (slave.visualAge > 55) {
				r = `${r }GILF`;
			} else if (slave.visualAge > 35) {
				r = `${r }MILF`;
			} else if (slave.visualAge >= 25) {
				r = `${r }slave`;
			} else {
				r = `${r }girl`;
			}
		}

		if ((slave.dick === 0) && (slave.vagina !== -1)) { /* FEMALES */
			if (slave.visualAge > 55) {
				r = "GILF";
			} else if (slave.visualAge > 35) {
				r = "MILF";
			} else if (slave.visualAge >= 25) {
				r = "slave";
			} else {
				r = "slavegirl";
			}
			if ((slave.muscles > 30) && (slave.height < 185)) {
				r = `muscle ${ r}`;
			} else if ((slave.lactation > 0) && (slave.boobs > 2000)) {
				r = `${r } cow`;
			} else if ((slave.boobsImplant > 0) && (slave.buttImplant > 0)) {
				r = `${r } bimbo`;
			} else if (slave.boobs > 6000) {
				r = `boob${ r}`;
			} else if (slave.butt > 6) {
				r = `ass${ r}`;
			}
		}

		if ((slave.dick !== 0) && (slave.vagina !== -1)) {
			if (slave.balls > 0) { /* FUTANARI: cock & balls & vagina */
				r = "futanari ";
			} else { /* FUTANARI: cock & vagina */
				r = "futa ";
			}
			if ((slave.lactation > 0) && (slave.boobs > 2000)) {
				r = `${r }cow`;
			} else if ((slave.boobsImplant > 0) && (slave.buttImplant > 0)) {
				r = `${r }bimbo `;
			} else if (slave.boobs > 6000) {
				r = `${r }boob`;
			} else if (slave.butt > 6) {
				r = `${r }ass`;
			} else if ((slave.muscles > 30) && (slave.height < 185)) {
				r = `${r }muscle`;
			}
			if (slave.visualAge > 55) {
				r = `${r }GILF`;
			} else if (slave.visualAge > 35) {
				r = `${r }MILF`;
			} else if (slave.visualAge >= 25) {
				r = `${r }slave`;
			} else {
				r = `${r }girl`;
			}
			if (slave.dick > 5 && slave.balls > 5 && slave.boobs > 5000) {
				r = `hyper ${ r}`;
			}
		}

		if ((slave.dick !== 0) && (slave.vagina === -1) && (slave.balls > 0) && (slave.boobs > 300) && (slave.butt > 2)) { /* SHEMALES: cock & balls, T&A above minimum */
			if (slave.visualAge > 55) {
				r = "sheGILF";
			} else if (slave.visualAge > 35) {
				r = "sheMILF";
			} else if (slave.visualAge >= 25) {
				r = "shemale";
			} else {
				r = "tgirl";
			}
			if ((slave.muscles > 30) && (slave.height < 185)) {
				r = `muscle${ r}`;
			} else if ((slave.lactation > 0) && (slave.boobs > 2000)) {
				r = `${r } cow`;
			} else if ((slave.boobsImplant > 0) && (slave.buttImplant > 0)) {
				r = `${r } bimbo`;
			} else if (slave.boobs > 6000) {
				r = `topheavy ${ r}`;
			} else if (slave.butt > 6) {
				r = `bottomheavy ${ r}`;
			}
		}

		if ((slave.boobs < 300) || (slave.butt < 2)) {
			if ((slave.dick !== 0) && (slave.vagina === -1) && (slave.balls > 0)) {
				if ((slave.shoulders < 1) || (slave.muscles <= 30)) {
					if ((slave.faceShape === "masculine") || (slave.faceShape === "androgynous")) { /* SISSIES: feminine shoulders or muscles, masculine faces */
						if (slave.visualAge > 55) {
							r = "sissyGILF";
						} else if (slave.visualAge > 35) {
							r = "sissyMILF";
						} else {
							r = "sissy";
						}
					} else { /* TRAPS: feminine shoulders or muscles, feminine faces */
						if (slave.visualAge > 55) {
							r = "trapGILF";
						} else if (slave.visualAge > 35) {
							r = "trapMILF";
						} else if (slave.visualAge >= 25) {
							r = "trap";
						} else {
							r = "trapgirl";
						}
					}
					if (slave.lactation > 0) {
						r = `${r } cow`;
					} else if ((slave.boobsImplant > 0) && (slave.buttImplant > 0)) {
						r = `${r } bimbo`;
					}
				}
			}
		}

		if ((slave.boobs < 300) || (slave.butt < 2)) {
			if ((slave.dick !== 0) && (slave.vagina === -1) && (slave.balls > 0)) {
				if ((slave.shoulders > 1) || (slave.muscles >= 30)) { /* BITCHES: masculine shoulders or muscles */
					r = "bitch";
					if ((slave.muscles > 30) && (slave.height < 185)) {
						r = `muscle${ r}`;
					} else if (slave.lactation > 0) {
						r = `${r }cow`;
					} else if ((slave.boobsImplant > 0) && (slave.buttImplant > 0)) {
						r = `bimbo ${ r}`;
					}
					if (slave.visualAge > 55) {
						r = `aged ${ r}`;
					} else if (slave.visualAge > 35) {
						r = `mature ${ r}`;
					} else if (slave.visualAge < 25) {
						r = `young ${ r}`;
					}
				}
			}
		}

		if ((slave.dick !== 0) && (slave.vagina === -1) && (slave.balls === 0)) {
			r = "dick";
			if (slave.visualAge > 55) {
				r = `${r }GILF`;
			} else if (slave.visualAge > 35) {
				r = `${r }MILF`;
			} else if (slave.visualAge >= 25) {
				r = `${r }slave`;
			} else {
				r = `${r }girl`;
			}
			if ((slave.muscles > 30) && (slave.height < 185)) {
				r = `muscle${ r}`;
			} else if ((slave.lactation > 0) && (slave.boobs > 2000)) {
				r = `${r } cow`;
			} else if ((slave.boobsImplant > 0) && (slave.buttImplant > 0)) {
				r = `${r } bimbo`;
			} else if (slave.boobs > 6000) {
				r = `boob ${ r}`;
			} else if (slave.butt > 6) {
				r = `ass ${ r}`;
			}
		}

		if ((slave.muscles > 30) && (slave.height > 185)) {
			r = `amazon ${ r}`;
		} else if ((slave.muscles < 30) && (slave.height > 185)) {
			r = `statuesque ${ r}`;
		} else if ((slave.boobs < 800) && (slave.height < 150)) {
			r = `petite ${ r}`;
		} else if ((slave.boobs > 800) && (slave.height < 150)) {
			r = `shortstack ${ r}`;
		}

		if (slave.counter.births >= 5) {
			r = `${r } broodmother`;
		} else if (slave.counter.births >= 2) {
			r = `${r } breeder`;
		}

		if (slave.geneticQuirks.albinism === 2) {
			r = `albino ${ r}`;
		}

		if (slave.indenture > -1) {
			r = `indentured ${ r}`;
		}

		if (slave.preg > slave.pregData.normalBirth/4 && slave.pregKnown === 1) {
			r = `pregnant ${ r}`;
		} else if (slave.bellyFluid >= 5000) {
			r = `bloated ${ r}`;
		} else if (slave.belly >= 5000) {
			r = `gravid ${ r}`;
		}

		if (slave.fuckdoll > 0) {
			r = `${r } fuckdoll`;
		}
	}
	return r;
};

window.DegradingName = /** @param {App.Entity.SlaveState} slave */ function DegradingName(slave) {
	const V = State.variables;
	const leadershipPosition = [
		"be the Attendant",
		"be the Matron",
		"be the Stewardess",
		"be the Milkmaid",
		"be the Farmer",
		"be the DJ",
		"be your Concubine",
		"be the Madam",
		"be the Schoolteacher",
		"be the Wardeness",
		"be the Nurse",
		"be your Head Girl",
		"guard you",
		"recruit girls"];
	const names = [];
	const suffixes = [];

	if (slave.fuckdoll > 0) {
		slave.slaveName = `Fuckdoll No. ${ slave.ID}`;
		slave.slaveSurname = 0;
	} else if (slave.assignment === "work in the dairy" && V.dairyRestraintsSetting >= 2) {
		slave.slaveName = `Bioreactor No. ${ slave.ID}`;
		slave.slaveSurname = 0;
	} else {
		if (V.seeRace === 1) {
			switch (slave.race) {
				case "white":
					names.push("Pale", "White");
					break;
				case "asian":
					names.push("Asian", "Yellow");
					break;
				case "latina":
					names.push("Brown", "Latina");
					break;
				case "black":
					names.push("Black", "Dark");
					break;
				case "pacific islander":
					names.push("Islander", "Pacific", "Sea");
					break;
				case "malay":
					names.push("Cinnamon", "Pinoy", "Spice");
					break;
				case "southern european":
					names.push("Mediterranean", "Olive");
					break;
				case "amerindian":
					names.push("Indian", "Reservation");
					break;
				case "semitic":
					names.push("Semite", "Semitic");
					break;
				case "middle eastern":
					names.push("Arab", "Sand");
					break;
				case "indo-aryan":
					names.push("Brown", "Indian");
					break;
				case "mixed race":
					names.push("Mixed", "Mulatto", "Mutt");
					break;
				default:
					break;
			}
		}
		names.push(slave.hColor);
		if (slave.eyes === -2) {
			names.push("Blind", "Eyeless", "Sightless");
		}
		if (slave.hears === -2) {
			names.push("Deaf", "Earless", "Unhearing");
		}
		if (slave.boobs >= 2000) {
			suffixes.push("Boob", "Boobs", "Titty");
		}
		if (slave.boobs < 500 && slave.butt < 3) {
			names.push("Girly", "Slim", "Thin");
		}
		if (slave.boobs < 300) {
			names.push("Flat");
		}
		if (slave.anus > 2 || slave.vagina > 2) {
			names.push("Gaping", "Hallway", "Slit", "Wideopen");
		}
		if (slave.weight > 160) {
			names.push("Blimp", "Cow", "Fat", "Fatass", "Whale");
		} else if (slave.weight > 30) {
			names.push("Chubby", "Fat", "Whale");
		} else if (slave.weight <= -30) {
			names.push("Bony", "Rail", "Skinny");
		}
		if (slave.muscles > 30) {
			names.push("Huge", "Muscles", "Ripped", "Strong");
		}
		if (slave.fetishKnown === 1) {
			if (slave.fetish === "buttslut") {
				names.push("Anal", "Sodomy");
			}
			if (slave.fetish === "cumslut") {
				names.push("Cum", "Dicksuck", "Sucker");
			}
			if (slave.fetish === "humiliation") {
				names.push("Rape");
			}
			if (slave.fetish === "masochist") {
				names.push("Pain", "Rape", "Struggle");
			}
			if (slave.fetish === "pregnancy") {
				names.push("Fertile");
			}
		}
		if (slave.boobs*slave.lactation > 1000) {
			names.push("Creamy", "Milky");
			suffixes.push("Cow");
		}
		if (slave.skill.oral <= 30 && slave.skill.anal <= 30) {
			names.push("Cheap", "Fail", "Gutter");
		}
		if (slave.nipples === "fuckable") {
			names.push("Nipplefuck", "Nipplecunt");
		} else if (slave.nipples !== "tiny" && slave.nipples !== "cute") {
			names.push("Pointy", "Titclit");
			suffixes.push("Nipples");
		}
		if (slave.visualAge > 35) {
			names.push("Mature");
			suffixes.push("Cougar", "MILF");
		} else if (slave.visualAge < 25) {
			names.push("Girly", "Thin", "Young");
		}
		if (slave.amp === 1) {
			names.push("Stumpy");
			suffixes.push("Stumpy");
		}
		if (slave.boobsImplant > 1000 || slave.buttImplant > 3) {
			names.push("Fake", "Plastic", "Silicone");
		}
		if (slave.dick > 5 && slave.balls > 5) {
			names.push("Potent");
			suffixes.push("Cannon", "Daddy");
		}
		if (slave.preg > slave.pregData.normalBirth/1.33) {
			if (slave.broodmother === 2) {
				names.push("Bursting", "Seeded");
				suffixes.push("Factory", "Nursery");
			} else if (slave.broodmother === 1) {
				names.push("Bloated", "Stuffed");
				suffixes.push("Breeder", "Factory");
			}
		}
		if (slave.bellyPreg >= 450000) {
			names.push("Bulging", "Squirming");
		}
		if (slave.bellyPreg >= 5000) {
			names.push("Preg");
			suffixes.push("Belly", "Mommy");
		}
		if (slave.belly > 150000) {
			suffixes.push("Balloon");
		}
		if (slave.belly > 1500) {
			suffixes.push("Belly");
		}
		if (slave.dick > 0) {
			if (slave.dick > 4) {
				names.push("Dangle", "Hung");
				suffixes.push("Cock", "Dick");
			}
			if (slave.balls === 0) {
				names.push("Cut", "Gelded", "Soft");
			} else {
				names.push("Erect", "Hard", "Stiff");
			}
		}
		if (slave.dick === 1) {
			names.push("Micro", "Tiny");
			suffixes.push("Bitch");
		}
		if (slave.height >= 185) {
			names.push("Tall", "Top");
			suffixes.push("Tower");
		} else if (slave.height < 150) {
			names.push("Stumpy", "Tiny");
			suffixes.push("Shortstack", "Stumpy");
		}
		if (slave.skill.whoring > 95) {
			names.push("Money", "Street");
			suffixes.push("Whore");
		}
		if (slave.skill.entertainment > 95) {
			names.push("Easy", "Club");
			suffixes.push("Slut");
		}
		if (slave.skill.oral > 95) {
			names.push("Suck");
			suffixes.push("Throat");
		}
		if (slave.skill.vaginal > 95) {
			suffixes.push("Channel", "Kegel", "Pussy");
		}
		if (slave.skill.anal > 95) {
			suffixes.push("Asspussy", "Sphincter");
		}
		if (slave.intelligence+slave.intelligenceImplant > 50) {
			names.push("Bright", "Clever", "Smart");
			if (slave.intelligenceImplant >= 15) {
				names.push("College", "Graduate", "Nerdy");
			}
		} else if (slave.intelligence+slave.intelligenceImplant < -50) {
			names.push("Cretin", "Dumb", "Retarded", "Stupid");
		}
		if (slave.vagina === 1 && slave.skill.vaginal <= 10) {
			names.push("Fresh", "New", "Tight");
		}
		if (slave.devotion < -75) {
			names.push("Angry", "Biter", "Caged");
		} else if (slave.devotion < -50) {
			names.push("Cell", "Cuffs");
		} else if (slave.devotion < -20) {
			names.push("Bag", "Box");
		} else if (slave.devotion <= 20) {
			names.push("Sad", "Whiner");
		} else if (slave.devotion > 50) {
			names.push("Prize");
			if (slave.visualAge > 35) {
				names.push("Queen");
			} else if (slave.visualAge < 25) {
				names.push("Princess");
			}
		}
		if (slave.trust < -50) {
			names.push("Screaming");
			suffixes.push("Sobber");
		} else if (slave.trust < -20) {
			names.push("Crying");
			suffixes.push("Meat", "Tears", "Thing", "Weeper");
		} else if (slave.trust < 20) {
			names.push("Begging");
		}

		if (slave.dick === 0) {
			if (slave.vagina === -1) {
				suffixes.push("Null");
			} else {
				if (slave.visualAge < 25) {
					suffixes.push("Girl");
				}
			}
		} else {
			if (slave.vagina !== -1) {
				suffixes.push("Futa");
			} else {
				if (slave.balls > 0) {
					if (slave.boobs > 300 && slave.butt > 2) { /* SHEMALES: cock & balls, T&A above minimum */
						suffixes.push("Shemale");
					} else {
						if (slave.shoulders < 1 && slave.muscles <= 30) {
							if (slave.faceShape === "masculine" || slave.faceShape === "androgynous") { /* SISSIES: feminine shoulders or muscles, masculine faces */
								suffixes.push("Sissy");
							} else { /* TRAPS: feminine shoulders or muscles, feminine faces */
								suffixes.push("Trap");
							}
						} else { /* BITCHES: masculine shoulders or muscles */
							suffixes.push("Bitch");
						}
					}
				} else {
					if (slave.visualAge > 35) {
						suffixes.push("DickMILF");
					} else if (slave.visualAge >= 25) {
						suffixes.push("Dickslave");
					} else {
						suffixes.push("Dickgirl");
					}
				}
			}
		}
		if (slave.anus > 0) {
			suffixes.push("Anus", "Asshole", "Backdoor", "Butt", "Butthole");
		}
		if (slave.anus === 1) {
			suffixes.push("Tightass", "Tightbutt");
		}
		if (slave.vagina > 0) {
			suffixes.push("Cunt", "Pussy", "Vagina");
		}
		if (slave.boobs < 500 && slave.butt < 3 && slave.dick > 0) {
			suffixes.push("Bitch", "Bottom", "Sissy", "Trap");
		}
		if (slave.energy > 95) {
			suffixes.push("Fuck", "Fuckaddict", "Nympho", "Sexaddict");
		}
		if (slave.fetishKnown === 1) {
			if (slave.fetish === "humiliation") {
				suffixes.push("Rapebait", "Showgirl");
			}
			if (slave.fetish === "submissive") {
				suffixes.push("Bottom", "Fuckee", "Rapebait");
			}
			if (slave.fetish === "dom") {
				suffixes.push("Dom", "Fucker", "Top");
			}
			if (slave.fetish === "pregnancy") {
				suffixes.push("Breeder", "Mommy");
			}
			if (slave.fetish === "boobs") {
				suffixes.push("Boob", "Boobie", "Tit", "Titty");
			}
		}
		if (slave.counter.births >= 2) {
			suffixes.push("Breeder");
			if (slave.counter.births >= 5) {
				suffixes.push("Broodmother");
			}
		}
		if (slave.areolae > 2) {
			suffixes.push("Areolas", "Headlights");
		}
		if (slave.lips > 40) {
			suffixes.push("Lips", "Pillows");
		}
		if (slave.labia > 1) {
			suffixes.push("Curtains", "Flower", "Lips");
		}
		if (slave.breedingMark === 1 && V.propOutcome === 1) {
			suffixes.push("Breeder", "Oven", "Womb");
		}
		if (slave.butt > 5) {
			suffixes.push("Ass", "Bottom", "Butt");
		}
		if (slave.vagina === 0) {
			suffixes.push("Virgin");
		}

		slave.slaveName = jsEither(names);
	}
	if (leadershipPosition.includes(slave.assignment)) {
		switch (slave.assignment) {
			case "be the Attendant":
				slave.slaveName = jsEither(["Bath", "Spa"]);
				break;
			case "be the Matron":
				slave.slaveName = jsEither(["Matron", "Nursery"]);
				break;
			case "be the Stewardess":
				slave.slaveName = jsEither(["Maid", "Servant"]);
				break;
			case "be the Milkmaid":
				if (V.cumSlaves > 3) {
					slave.slaveName = jsEither(["Fucker", "Milker"]);
				} else {
					slave.slaveName = jsEither(["Dairy", "Farm"]);
				}
				break;
			case "be the Farmer":
				slave.slaveName = jsEither(["Farmer", "Farmhand"]);
				break;
			case "be the DJ":
				slave.slaveName = jsEither(["Bass", "Booth"]);
				break;
			case "be your Concubine":
				slave.slaveName = jsEither(["Bed", "Master"]);
				break;
			case "be the Madam":
				slave.slaveName = jsEither(["Madam", "Pimp"]);
				break;
			case "be the Schoolteacher":
				slave.slaveName = jsEither(["Classroom", "Teacher"]);
				break;
			case "be the Wardeness":
				slave.slaveName = jsEither(["Jail", "Prison"]);
				break;
			case "be the Nurse":
				slave.slaveName = jsEither(["Clinic", "Nurse"]);
				break;
			case "be your Head Girl":
				slave.slaveName = jsEither(["Chief", "Head"]);
				break;
			case "guard you":
				slave.slaveName = jsEither(["Battle", "Guard"]);
				break;
			case "recruit girls":
				slave.slaveName = jsEither(["Cam", "Recruiter"]);
				break;
			default:
				break;
		}
	}
	const surname = jsEither(suffixes);
	if (typeof surname === "string" && surname.toLowerCase() === slave.slaveName.toLowerCase()) {
		DegradingName(slave);
	}
	slave.slaveName = capFirstChar(slave.slaveName);
	slave.slaveSurname = surname;
};

window.SlaveSort = /** @param {App.Entity.SlaveState[]} slaves */ function SlaveSort(slaves, main = false) {
	const V = State.variables;
	if (main) {
		switch (V.sortSlavesBy) {
			case "name":
				if (V.sortSlavesOrder === "ascending")
					slaves = slaves.sort((a, b) => a.slaveName < b.slaveName ? -1 : 1);
				else
					slaves = slaves.sort((a, b) => a.slaveName > b.slaveName ? -1 : 1);
				break;
			case "assignment":
				if (V.sortSlavesOrder === "ascending")
					slaves = slaves.sort((a, b) => a.assignment < b.assignment ? -1 : 1);
				else
					slaves = slaves.sort((a, b) => a.assignment > b.assignment ? -1 : 1);
				break;
			case "seniority":
				if (V.sortSlavesOrder === "ascending")
					slaves = slaves.sort((a, b) => b.weekAcquired - a.weekAcquired);
				else
					slaves = slaves.sort((a, b) => a.weekAcquired - b.weekAcquired);
				break;
			case "actualAge":
				if (V.sortSlavesOrder === "ascending")
					slaves = slaves.sort((a, b) => a.actualAge - b.actualAge);
				else
					slaves = slaves.sort((a, b) => b.actualAge - a.actualAge);
				break;
			case "visualAge":
				if (V.sortSlavesOrder === "ascending")
					slaves = slaves.sort((a, b) => a.visualAge - b.visualAge);
				else
					slaves = slaves.sort((a, b) => b.visualAge - a.visualAge);
				break;
			case "physicalAge":
				if (V.sortSlavesOrder === "physicalAge")
					slaves = slaves.sort((a, b) => a.physicalAge - b.physicalAge);
				else
					slaves = slaves.sort((a, b) => b.physicalAge - a.physicalAge);
				break;
			default:
				if (V.sortSlavesOrder === "ascending")
					slaves = slaves.sort((a, b) => a.devotion - b.devotion);
				else
					slaves = slaves.sort((a, b) => b.devotion - a.devotion);
				break;
		}
		V.slaveIndices = slaves2indices();
	} else {
		V.slaveIndices = slaves2indices();
		filterInPlace(slaves, s => V.slaveIndices[s] !== undefined);
		slaves.sort((a, b) => V.slaveIndices[a] - V.slaveIndices[b]);
	}
};

window.slaveSortMinor = /** @param {App.Entity.SlaveState[]} slaves */ function slaveSortMinor(slaves) {
	slaves = slaves.sort((a, b) => a.slaveName < b.slaveName ? -1 : 1);
};

window.MenialPopCap = function MenialPopCap() {
	const V = State.variables;
	let popCap = 500;
	let r = "";

	for (let mwi = 20; mwi < V.sectors.length; mwi++) {
		if (V.sectors[mwi].type === "Pens") {
			popCap += 500;
		}
	}
	let overMenialCap = V.menials + V.fuckdolls + V.menialBioreactors - popCap;
	if (overMenialCap > 0) {
		const price = menialSlaveCost(-overMenialCap);
		if (V.menials > 0) {
			if (V.menials > overMenialCap) {
				cashX((overMenialCap * price), "menialTrades");
				V.menialDemandFactor -= overMenialCap;
				V.menials -= overMenialCap;
				overMenialCap = 0;
				r += "You don't have enough room for all your menials and are obliged to sell some.";
			} else {
				cashX((V.menials * price), "menialTrades");
				V.menialDemandFactor -= V.menials;
				overMenialCap -= V.menials;
				V.menials = 0;
				r += "You don't have enough room for your menials and are obliged to sell them.";
			}
		}
		if (overMenialCap > 0 && V.fuckdolls > 0) {
			if (V.fuckdolls > overMenialCap) {
				cashX(overMenialCap * (price * 2), "menialTrades");
				V.menialDemandFactor -= overMenialCap;
				V.fuckdolls -= overMenialCap;
				overMenialCap = 0;
				r += "You don't have enough room for all your Fuckdolls and are obliged to sell some.";
			} else {
				cashX(V.fuckdolls * (price * 2), "menialTrades");
				V.menialDemandFactor -= V.fuckdolls;
				overMenialCap -= V.fuckdolls;
				V.fuckdolls = 0;
				r += "You don't have enough room for your Fuckdolls and are obliged to sell them.";
			}
		}
		if (overMenialCap > 0 && V.menialBioreactors > 0) {
			cashX(overMenialCap * (price - 100), "menialTrades");
			V.menialDemandFactor -= overMenialCap;
			V.menialBioreactors -= overMenialCap;
			r += "You don't have enough room for all your menial bioreactors and are obliged to sell some.";
		}
	}
	V.PopCap = popCap;
	return r;
};

window.faceIncrease = /** @param {App.Entity.SlaveState} slave */ function faceIncrease(slave, amount) {
	const pronouns = getPronouns(slave);
	const his = pronouns.possessive;
	const His = capFirstChar(his);
	let r = "";
	if (slave.face <= -95)
		r += `<span class="green">${His} face is no longer horrifying,</span> and is now merely ugly.`;
	else if (slave.face <= -40 && slave.face + amount > -40)
		r += `<span class="green">${His} face is no longer ugly,</span> and is now merely unattractive.`;
	else if (slave.face <= -10 && slave.face + amount > -10)
		r += `<span class="green">${His} face is no longer unattractive,</span> and is now somewhat tolerable.`;
	else if (slave.face <= 10 && slave.face + amount > 10)
		r += `<span class="green">${His} face is now decently attractive,</span> rather than merely tolerable.`;
	else if (slave.face <= 40 && slave.face + amount > 40)
		r += `<span class="green">${His} face is now quite beautiful,</span> rather than merely pretty.`;
	else if (slave.face <= 95 && slave.face + amount > 95)
		r += `<span class="green">${His} face is now perfect.</span> It's difficult to imagine how it could be any more beautiful.`;
	slave.face = Math.clamp(slave.face + amount, -100, 100);
	if (slave.face > 95) slave.face = 100;
	return r;
};

window.Deadliness = /** @param {App.Entity.SlaveState} slave */ function Deadliness(slave) {
	const V = State.variables;
	let deadliness = 2;

	if (slave.skill.combat > 0) {
		deadliness += 2;
	}

	if (setup.bodyguardCareers.includes(slave.career)) {
		deadliness += 1;
	} else if (slave.skill.bodyguard >= V.masteredXP) {
		deadliness += 1;
	}

	if (slave.muscles > 30 && slave.muscles <= 95) {
		deadliness += 1;
	} else if (slave.muscles > 95 && slave.height >= 185) {
		deadliness += 2;
	} else if (slave.muscles > 95) {
		deadliness -= 1;
	} else if (slave.muscles < -95) {
		deadliness -= 20;
	} else if (slave.muscles < -30) {
		deadliness -= 7;
	} else if (slave.muscles < -5) {
		deadliness -= 3;
	}

	if (slave.height >= 170) {
		deadliness += 1;
	}

	if (slave.health > 50) {
		deadliness += 1;
	}

	if (slave.boobs > 4000) {
		deadliness -= 2;
	} else if (slave.boobs > 2000) {
		deadliness -= 1;
	}

	if (slave.butt > 6) {
		deadliness -= 1;
	}

	if (slave.hips > 2) {
		deadliness -= 1;
	}

	if (slave.weight > 190) {
		deadliness -= 20;
	} else if (slave.weight > 160) {
		deadliness -= 10;
	} else if (slave.weight > 130) {
		deadliness -= 3;
	} else if (slave.weight > 30 || slave.weight < -10) {
		deadliness -= 1;
	}

	if (slave.health < -50) {
		deadliness -= 1;
	}

	if (slave.bellyFluid >= 10000) {
		deadliness -= 3;
	} else if (slave.bellyFluid >= 5000) {
		deadliness -= 2;
	} else if (slave.bellyFluid >= 2000) {
		deadliness -= 1;
	}

	if (slave.pregKnown === 1 || slave.bellyPreg >= 1500 || slave.bellyImplant >= 1500) {
		if (slave.belly >= 750000) {
			deadliness -= 50;
		} else if (slave.belly >= 600000) {
			deadliness -= 25;
		} else if (slave.belly >= 450000) {
			deadliness -= 15;
		} else if (slave.belly >= 300000) {
			deadliness -= 10;
		} else if (slave.belly >= 150000) {
			deadliness -= 8;
		} else if (slave.belly >= 100000) {
			deadliness -= 7;
		} else if (slave.belly >= 10000) {
			deadliness -= 3;
		} else if (slave.belly >= 5000) {
			deadliness -= 2;
		} else {
			deadliness -= 1;
		}
	}

	if (slave.labor === 1) {
		deadliness -= 15;
	} else if (slave.preg >= slave.pregData.normalBirth && slave.pregControl !== "labor suppressors") {
		deadliness -= 5;
	}

	if (slave.balls >= 15) {
		deadliness -= 1;
	}

	if (slave.dick >= 10) {
		deadliness -= 1;
	}

	if (slave.amp === 0) {
		if (!canWalk(slave)) {
			deadliness -= 20;
		}
	} else if (slave.amp === 1) {
		deadliness -= 20;
	} else if (slave.amp === -5) {
		deadliness += 10;
	} else if (slave.amp === -4) {
		deadliness += 5;
	} else {
		deadliness -= 1;
	}

	if (!canSee(slave)) {
		deadliness -= 8;
	} else if ((slave.eyes === -1 && !["corrective contacts", "corrective glasses"].includes(slave.eyewear)) || (slave.eyes === 1 && ["blurring contacts", "blurring glasses"].includes(slave.eyewear))) {
		deadliness -= 1;
	}

	if (!canHear(slave)) {
		deadliness -= 4;
	} else if ((slave.hears === -1 && slave.earwear !== "hearing aids") || (slave.hears === 0 && slave.earwear === "muffling ear plugs")) {
		deadliness -= 1;
	}

	if (slave.tail === "combat") {
		deadliness += 2;
	}

	return Math.max(deadliness, 1);
};


code:
/* eslint-disable no-case-declarations */
/* eslint-disable no-undef */
window.assignJob = function assignJob(slave, job) {
	"use strict";
	const V = State.variables;
	let r = "";

	if (job === "Pit" || job === "Coursing Association")
		return r;

	removeJob(slave, slave.assignment);
	const idx = V.slaveIndices[slave.ID];

	/* use .toLowerCase() to get rid of a few dupe conditions. */
	switch (job.toLowerCase()) {
		case "be confined in the arcade":
		case "arcade":
			slave.assignment = "be confined in the arcade";
			slave.assignmentVisible = 0;
			V.arcadeSlaves++;
			V.ArcadeiIDs.push(slave.ID);
			slave.clothes = "no clothing";
			slave.shoes = "none";
			slave.collar = "none";
			slave.livingRules = "spare";
			break;

		case "work in the brothel":
		case "brothel":
			slave.assignment = "work in the brothel";
			slave.assignmentVisible = 0;
			V.brothelSlaves++;
			V.BrothiIDs.push(slave.ID);
			switch (V.brothelDecoration) {
				case "Degradationist":
				case "standard":
					slave.livingRules = "spare";
					break;
				default:
					slave.livingRules = "normal";
					break;
			}
			break;

		case "be confined in the cellblock":
		case "cellblock":
			slave.assignment = "be confined in the cellblock";
			slave.assignmentVisible = 0;
			V.cellblockSlaves++;
			V.CellBiIDs.push(slave.ID);
			switch (V.cellblockDecoration) {
				case "Paternalist":
					slave.livingRules = "normal";
					break;
				default:
					slave.livingRules = "spare";
					break;
			}
			break;

		case "get treatment in the clinic":
		case "clinic":
			slave.assignment = "get treatment in the clinic";
			slave.assignmentVisible = 0;
			V.clinicSlaves++;
			V.CliniciIDs.push(slave.ID);
			switch (V.clinicDecoration) {
				case "Repopulation Focus":
				case "Eugenics":
				case "Gender Radicalist":
				case "Gender Fundamentalist":
				case "Paternalist":
				case "Maturity Preferentialist":
				case "Youth Preferentialist":
				case "Slimness Enthusiast":
				case "Hedonistic":
					slave.livingRules = "luxurious";
					break;

				case "Roman Revivalist":
				case "Aztec Revivalist":
				case "Egyptian Revivalist":
				case "Arabian Revivalist":
				case "Chinese Revivalist":
				case "Chattel Religionist":
				case "Edo Revivalist":
					slave.livingRules = "normal";
					break;

				default:
					slave.livingRules = "spare";
					break;
			}
			break;

		case "serve in the club":
		case "club":
			slave.assignment = "serve in the club";
			slave.assignmentVisible = 0;
			V.clubSlaves++;
			V.ClubiIDs.push(slave.ID);
			slave.livingRules = "normal";
			break;

		case "work in the dairy":
		case "dairy":
			slave.assignment = "work in the dairy";
			slave.assignmentVisible = 0;
			V.dairySlaves++;
			V.DairyiIDs.push(slave.ID);
			switch (V.dairyDecoration) {
				case "Roman Revivalist":
				case "Aztec Revivalist":
				case "Chinese Revivalist":
				case "Chattel Religionist":
				case "Edo Revivalist":
				case "Arabian Revivalist":
				case "Egyptian Revivalist":
				case "Supremacist":
				case "Subjugationist":
				case "Degradationist":
					slave.livingRules = "spare";
					break;
				default:
					slave.livingRules = "normal";
					break;
			}
			break;

		case "work as a farmhand":
		case "farmyard":
			slave.assignment = "work as a farmhand";
			slave.assignmentVisible = 0;
			V.farmyardSlaves++;
			V.FarmyardiIDs.push(slave.ID);
			switch (V.farmyardDecoration) {
				case "Aztec Revivalist":
				case "Chinese Revivalist":
				case "Chattel Religionist":
				case "Edo Revivalist":
				case "Arabian Revivalist":
				case "Egyptian Revivalist":
				case "Supremacist":
				case "Subjugationist":
				case "Degradationist":
					slave.livingRules = "spare";
					break;
				case "Roman Revivalist":
					slave.livingRules = "luxurious";
					break;
				default:
					slave.livingRules = "normal";
					break;
			}
			break;

		case "live with your head girl":
		case "head girl suite":
		case "hgsuite":
			slave.assignment = "live with your Head Girl";
			slave.assignmentVisible = 0;
			V.HGSuiteSlaves++;
			V.HGSuiteiIDs.push(slave.ID);
			slave.livingRules = "luxurious";
			break;

		case "serve in the master suite":
		case "master suite":
		case "mastersuite":
			slave.assignment = "serve in the master suite";
			slave.assignmentVisible = 0;
			V.masterSuiteSlaves++;
			V.MastSiIDs.push(slave.ID);
			if (V.masterSuiteUpgradeLuxury > 0)
				slave.livingRules = "luxurious";
			else
				slave.livingRules = "spare";
			break;

		case "learn in the schoolroom":
		case "schoolroom":
			slave.assignment = "learn in the schoolroom";
			slave.assignmentVisible = 0;
			V.schoolroomSlaves++;
			V.SchlRiIDs.push(slave.ID);
			slave.livingRules = "normal";
			break;

		case "work as a servant":
		case "servants' quarters":
		case "servantsquarters":
			slave.assignment = "work as a servant";
			slave.assignmentVisible = 0;
			V.servantsQuartersSlaves++;
			V.ServQiIDs.push(slave.ID);
			switch (V.servantsQuartersDecoration) {
				case "Roman Revivalist":
				case "Aztec Revivalist":
				case "Chinese Revivalist":
				case "Chattel Religionist":
				case "Edo Revivalist":
				case "Supremacist":
				case "Subjugationist":
				case "Degradationist":
				case "Arabian Revivalist":
				case "Egyptian Revivalist":
					slave.livingRules = "spare";
					break;
				default:
					slave.livingRules = "normal";
					break;
			}
			break;

		case "rest in the spa":
		case "spa":
			slave.assignment = "rest in the spa";
			slave.assignmentVisible = 0;
			V.spaSlaves++;
			V.SpaiIDs.push(slave.ID);
			switch (V.spaDecoration) {
				case "Chattel Religionist":
				case "Chinese Revivalist":
					slave.livingRules = "normal";
					break;
				case "Degradationist":
					slave.livingRules = "spare";
					break;
				default:
					slave.livingRules = "luxurious";
					break;
			}
			break;

		case "work as a nanny":
		case "nursery":
			slave.assignment = "work as a nanny";
			slave.assignmentVisible = 0;
			V.nurserySlaves++;
			V.NurseryiIDs.push(slave.ID);
			slave.livingRules = "normal";
			break;

		case "be the attendant":
		case "be the matron":
		case "be the dj":
		case "be the madam":
		case "be the milkmaid":
		case "be the farmer":
		case "be the nurse":
		case "be the schoolteacher":
		case "be the stewardess":
		case "be the wardeness":
			slave.assignment = job;
			slave.assignmentVisible = 0; /* non-visible leadership roles */
			slave.livingRules = "luxurious";
			break;

		case "be your concubine":
			slave.assignment = job;
			slave.assignmentVisible = 0; /* non-visible leadership roles */
			if (V.masterSuiteUpgradeLuxury > 0)
				slave.livingRules = "luxurious";
			else
				slave.livingRules = "normal";
			break;

		case "be your head girl":
			slave.assignment = job;
			if (V.HGSuite === 1) {
				slave.livingRules = "luxurious";
			}
			break;

		case "guard you":
			slave.assignment = job;
			if (V.dojo > 1) {
				slave.livingRules = "luxurious";
			}
			if (V.pitBG === 1 && V.fighterIDs.includes(slave.ID))
				V.fighterIDs.delete(slave.ID);
			break;

		case "be your agent":
		case "live with your agent":
			slave.assignment = job;
			slave.assignmentVisible = 0;
			slave.useRulesAssistant = 0; /* non-visible roles exempt from Rules Assistant */
			WombCleanGenericReserve(slave, 'incubator', 9999);
			WombCleanGenericReserve(slave, 'nursery', 9999);
			if (job === "be your agent") {
				V.leaders.push(slave);
			}
			break;

		case "choose her own job":
			slave.assignment = job;
			slave.choosesOwnAssignment = 1; /* removeJob already set assignmentVisible = 1 */
			break;

		default:
			slave.assignment = job; /* removeJob already set assignmentVisible = 1 and choosesOwnAssignment = 0 */
			break;
	}

	if (slave.assignmentVisible === 0 && Array.isArray(V.personalAttention)) {
		const awi = V.personalAttention.findIndex(function(s) { return s.ID === slave.ID; });
		if (awi !== -1) {
			V.personalAttention.deleteAt(awi);
			if (V.personalAttention.length === 0) {
				if (V.PC.career === "escort")
					V.personalAttention = "whoring";
				else if (V.PC.career === "servant")
					V.personalAttention = "upkeep";
				else
					V.personalAttention = "business";
				r += `${slave.slaveName} no longer has your personal attention; you plan to focus on ${V.personalAttention}.`;
			} else
				r += `${slave.slaveName} no longer has your personal attention.`;
		}
	}
	V.JobIDArray = resetJobIDArray();
	if (idx >= 0)
		V.slaves[idx] = slave;

	return r;
};

window.removeJob = function removeJob(slave, assignment) {
	"use strict";
	const V = State.variables;
	let r = "";

	const idx = V.slaveIndices[slave.ID];

	if (assignment === "Pit")
		V.fighterIDs.delete(slave.ID);

	else if (assignment === "Coursing Association")
		V.Lurcher = 0;

	else {
		if (V.HeadGirl !== 0 && slave.ID === V.HeadGirl.ID)
			V.HeadGirl = 0;
		else if (V.Recruiter !== 0 && slave.ID === V.Recruiter.ID)
			V.Recruiter = 0;
		else if (V.Bodyguard !== 0 && slave.ID === V.Bodyguard.ID)
			V.Bodyguard = 0;
		else if (V.Madam !== 0 && slave.ID === V.Madam.ID)
			V.Madam = 0;
		else if (V.DJ !== 0 && slave.ID === V.DJ.ID)
			V.DJ = 0;
		else if (V.Milkmaid !== 0 && slave.ID === V.Milkmaid.ID)
			V.Milkmaid = 0;
		else if (V.Farmer !== 0 && slave.ID === V.Farmer.ID)
			V.Farmer = 0;
		else if (V.Schoolteacher !== 0 && slave.ID === V.Schoolteacher.ID)
			V.Schoolteacher = 0;
		else if (V.Attendant !== 0 && slave.ID === V.Attendant.ID)
			V.Attendant = 0;
		else if (V.Matron !== 0 && slave.ID === V.Matron.ID)
			V.Matron = 0;
		else if (V.Nurse !== 0 && slave.ID === V.Nurse.ID)
			V.Nurse = 0;
		else if (V.Stewardess !== 0 && slave.ID === V.Stewardess.ID)
			V.Stewardess = 0;
		else if (V.Wardeness !== 0 && slave.ID === V.Wardeness.ID)
			V.Wardeness = 0;
		else if (V.Concubine !== 0 && slave.ID === V.Concubine.ID)
			V.Concubine = 0;
		else if (V.Collectrix !== 0 && slave.ID === V.Collectrix.ID)
			V.Collectrix = 0;

		/* use .toLowerCase() to get rid of a few dupe conditions. */
		switch (assignment.toLowerCase()) {
			case "be confined in the arcade":
			case "arcade":
				slave.assignment = "work a glory hole";
				V.ArcadeiIDs.delete(slave.ID);
				V.arcadeSlaves--;
				break;

			case "work in the brothel":
			case "brothel":
				slave.assignment = "whore";
				V.BrothiIDs.delete(slave.ID);
				V.brothelSlaves--;
				break;

			case "be confined in the cellblock":
			case "cellblock":
				slave.assignment = "rest";
				if (slave.inflation > 0) {
					slave.inflation = 0;
					slave.inflationType = "none";
					slave.inflationMethod = 0;
					SetBellySize(slave);
				}
				V.CellBiIDs.delete(slave.ID);
				V.cellblockSlaves--;
				break;

			case "get treatment in the clinic":
			case "clinic":
				slave.assignment = "rest";
				V.CliniciIDs.delete(slave.ID);
				V.clinicSlaves--;
				break;

			case "serve in the club":
			case "club":
				slave.assignment = "serve the public";
				V.ClubiIDs.delete(slave.ID);
				V.clubSlaves--;
				break;

			case "work in the dairy":
			case "dairy":
				slave.assignment = "get milked";
				V.DairyiIDs.delete(slave.ID);
				V.dairySlaves--;
				break;

			case "work as a farmhand":
			case "farmyard":
				slave.assignment = "rest";
				V.FarmyardiIDs.delete(slave.ID);
				V.farmyardSlaves--;
				break;

			case "learn in the schoolroom":
			case "schoolroom":
				slave.assignment = "rest";
				V.SchlRiIDs.delete(slave.ID);
				V.schoolroomSlaves--;
				break;

			case "rest in the spa":
			case "spa":
				slave.assignment = "rest";
				V.SpaiIDs.delete(slave.ID);
				V.spaSlaves--;
				break;

			case "work as a servant":
			case "servants' quarters":
			case "servantsquarters":
				slave.assignment = "be a servant";
				V.ServQiIDs.delete(slave.ID);
				V.servantsQuartersSlaves--;
				break;

			case "serve in the master suite":
			case "master suite":
			case "mastersuite":
				slave.assignment = "please you";
				V.MastSiIDs.delete(slave.ID);
				V.masterSuiteSlaves--;
				break;

			case "live with your head girl":
			case "head girl suite":
			case "hgsuite":
				slave.assignment = "rest";
				V.HGSuiteiIDs.delete(slave.ID);
				V.HGSuiteSlaves--;
				break;

			case "work as a nanny":
			case "nursery":
				slave.assignment = "rest";
				V.NurseryiIDs.delete(slave.ID);
				V.nurserySlaves--;
				break;

			case "be your head girl":
				slave.assignment = "rest";
				if (V.HGSuiteEquality === 0 && V.personalAttention === "HG") {
					if (V.PC.career === "escort")
						V.personalAttention = "whoring";
					else if (V.PC.career === "servant")
						V.personalAttention = "upkeep";
					else
						V.personalAttention = "business";

					r += `You no longer have a slave assigned to be your Head Girl, so you turn your personal attention to focus on ${V.personalAttention}.`;
				}
				break;

			case "be your agent":
			case "live with your agent":
				slave.assignment = "rest";
				const _leaderIndex = V.leaders.findIndex(function(x) { return x.ID === slave.ID; });
				if (_leaderIndex !== -1)
					V.leaders.deleteAt(_leaderIndex);

				if (slave.relationshipTarget > 0) { /* following code assumes there can be at most one companion */
					const _lover = V.slaves.findIndex(function(s) { return haveRelationshipP(s, slave) && s.assignment === "live with your agent"; });
					if (_lover !== -1) {
						V.slaves[_lover].assignment = "rest";
						V.slaves[_lover].assignmentVisible = 1;
					}
				}
				break;

			default:
				slave.assignment = "rest";
				break;
		}

		if (slave.livingRules === "luxurious" && slave.assignmentVisible !== 1)
			slave.livingRules = "normal";

		slave.assignmentVisible = 1;
		slave.choosesOwnAssignment = 0;
		slave.sentence = 0;
	}
	V.JobIDArray = resetJobIDArray();
	if (idx >= 0)
		V.slaves[idx] = slave;

	return r;
};

window.resetJobIDArray = function resetJobIDArray() { /* todo: expand to all assignments */
	const slaves = State.variables.slaves;
	const JobIDArray = {
		"rest": [],
		"please you": [],
		"work a glory hole": [],
		"take classes": [],
		"be a servant": [],
		"whore": [],
		"serve the public": [],
		"get milked": [],
		"stay confined": [],
		"be a subordinate slave": []
	};

	slaves.forEach(function (slave) {
		if (JobIDArray.hasOwnProperty(slave.assignment))
			JobIDArray[slave.assignment].push(slave.ID);
	});

	return JobIDArray;
};

/**
 * Generates string with links for changing slave assignment
 */
App.UI.jobLinks = function () {
	"use strict";
	const facilitiesOrder = [
		/* sorted by improvement before work, within improvement in order of progress, within work alphabetical for facilities*/
		App.Entity.facilities.penthouse,
		App.Entity.facilities.cellblock,
		App.Entity.facilities.nursery,
		App.Entity.facilities.schoolroom,
		App.Entity.facilities.clinic,
		App.Entity.facilities.spa,
		App.Entity.facilities.arcade,
		App.Entity.facilities.brothel,
		App.Entity.facilities.club,
		App.Entity.facilities.dairy,
		App.Entity.facilities.farmyard,
		App.Entity.facilities.masterSuite,
		App.Entity.facilities.servantsQuarters
	];

	return {
		assignments: assignmentLinks,
		transfers: transferLinks
	};

	/**
	 * Generates assignment links
	 * @param {number} index index in the slaves array or -1 for the activeSlave
	 * @param {string} [passage] optional next passage to go to
	 * @param {linkCallback} [callback]
	 * @returns {string}
	 */
	function assignmentLinks(index, passage, callback) {
		let penthouseJobs = App.Entity.facilities.penthouse.assignmentLinks(index, undefined, passage, callback);
		const slave = App.Utils.slaveByIndex(index);

		if (slave.fuckdoll === 0) {
			const assignment = "choose her own job";
			if (slave.assignment !== assignment) {
				const linkAction = callback !== undefined ? callback(assignment) : '';
				penthouseJobs.push(`<<link "Let ${slave.object} choose" ${passage !== undefined ? '"' + passage + '"' : ''}>><<= assignJob(${App.Utils.slaveRefString(index)}, "${assignment}")>>${linkAction}<</link>>`);
			}
		} else {
			penthouseJobs.push(App.UI.disabledLink(`Let ${slave.object} choose`, ["Fuckdolls can't choose their job"]));
		}

		return penthouseJobs.join(" | ");
	}

	function transferLinks(index) {
		/** @type {string[]} */
		const transfers = [];
		const slave = App.Utils.slaveByIndex(index);

		for (const f of facilitiesOrder) {
			if (!f.established) continue;
			const rejects = f.canHostSlave(slave);
			if (rejects.length === 0) {
				transfers.push(f.transferLink(index, undefined, passage()));
			} else {
				transfers.push(App.UI.disabledLink(f.genericName, rejects));
			}
		}

		return transfers.join(' | ');
	}
}();

App.UI.SlaveInteract = {
	fucktoyPref: function () {
		let elem = jQuery('#fucktoypref');
		elem.empty();
		let res = "";
		/** @type {App.Entity.SlaveState} */
		const slave = State.variables.activeSlave;
		if ((slave.assignment === "please you") || (slave.assignment === "serve in the master suite") || (slave.assignment === "be your Concubine")) {
			res += '__Fucktoy use preference__: ' + slave.toyHole + '.';
			/** @type {string[]} */
			let links = [];
			links.push('<<link "Mouth">><<set $activeSlave.toyHole = "mouth">><<replace "#hole">>$activeSlave.toyHole<</replace>><</link>>');
			links.push('<<link "Tits">><<set $activeSlave.toyHole = "boobs">><<replace "#hole">>$activeSlave.toyHole<</replace>><</link>>');
			if ((slave.vagina > 0) && canDoVaginal(slave)) {
				links.push('<<link "Pussy">><<set $activeSlave.toyHole = "pussy">><<replace "#hole">>$activeSlave.toyHole<</replace>><</link>>');
			} else if (slave.vagina === 0) {
				links.push(App.UI.disabledLink("Pussy",
					[`Take ${slave.possessive} virginity before giving ${slave.possessive} pussy special attention`]));
			}
			if ((slave.anus > 0) && canDoAnal(slave)) {
				links.push('<<link "Ass">><<set $activeSlave.toyHole = "ass">><<replace "#hole">>$activeSlave.toyHole<</replace>><</link>>');
			} else {
				links.push(App.UI.disabledLink("Ass",
					[`Take ${slave.possessive} anal virginity before giving ${slave.possessive} ass special attention`]));
			}
			if ((slave.dick > 0) && canPenetrate(slave)) {
				links.push('<<link "Dick">><<set $activeSlave.toyHole = "dick">><<replace "#hole">>$activeSlave.toyHole<</replace>><</link>>');
			}
			links.push(`<<link "No Preference">><<set $activeSlave.toyHole = "all ${slave.possessive} holes">><<replace "#hole">>$activeSlave.toyHole<</replace>><</link>>`);
			res += links.join(' | ') + '
';
		}
		let ins = jQuery(document.createDocumentFragment());
		ins.wiki(res);
		elem.append(ins);
	},

	assignmentBlock: function (blockId) {
		let res = App.UI.jobLinks.assignments(-1, undefined, () => {
			return `<<replace "#assign">>$activeSlave.assignment<</replace>><<replace "#${blockId}">><<= App.UI.SlaveInteract.assignmentBlock("${blockId}")>><<= App.UI.SlaveInteract.fucktoyPref()>><</replace>>`;
		});
		if (State.variables.activeSlave.assignment !== "choose her own job") {
			res += ' |  <<link "Stay on this assignment for another month">><<set $activeSlave.sentence += 4>><<replace "#assign">>$activeSlave.assignment($activeSlave.sentence weeks)<</replace>><</link>>';
		}
		return res;
	}
};

repo_name: CheatDude/fc


code:
/* eslint-disable no-undef */
window.flipColors = function (lightColorMap) {
	if (!window.savedColorMap) {
		window.savedColorMap = setColors(lightColorMap);
	} else {
		restoreColors(window.savedColorMap);
		window.savedColorMap = null;
	}
};

window.setColors = function (colorMap) {
	let originalState = [];
	let props = ["color", "backgroundColor", "backgroundImage"];
	let styleSheetArray = Array.from(document.styleSheets);
	styleSheetArray.forEach(styleSheet => {
		let cssRules = Array.from(styleSheet.cssRules);
		cssRules.forEach(cssRule => {
			if (cssRule.type === 1) {
				props.forEach(propName => {
					let currentValue = cssRule.style[propName];
					if (
						currentValue !== "" &&
						currentValue !== "inherit" &&
						currentValue !== "transparent") {
						let newVal = colorMap[currentValue];
						if (typeof newVal !== "undefined") {
							cssRule.style[propName] = newVal;
							originalState.push(
								{
									element: cssRule,
									propName: propName,
									value: currentValue
								}
							);
						}
					}
				});
			}
		});
	});
	return originalState;
};

window.restoreColors = function(styleMap){
	styleMap.forEach(
		item => {
			item.element.style[item.propName] = item.value;
		}
	);
};


code:
Macro.add("colorinput", {
	handler: function() {
		if (this.args.length < 2) {
			var e = [];
			return this.args.length < 1 && e.push("variable name"), this.args.length < 2 && e.push("default value"), this.error("no " + e.join(" or ") + " specified");
		}
		if ("string" != typeof this.args[0]) return this.error("variable name argument is not a string");
		var varName = this.args[0].trim();
		if ("$" !== varName[0] && "_" !== varName[0]) return this.error('variable name "' + this.args[0] + '" is missing its sigil ($ or _)');
		Config.debug && this.debugView.modes({
			block: true
		});
		var r = Util.slugify(varName);
		var value = this.args[1];
		var inputElement = document.createElement("input"),
			passage = void 0;
		var setargs = null;
		if (this.args.length > 3) {
			passage = this.args[2];
		} else if (this.args.length > 2) {
			passage = this.args[2];
		}
		if (passage !== (void 0) && typeof(passage) === "object") {
			passage = passage.link;
		}
		if (!passage) {
			passage = State.passage;
		}

		function gotoPassage() {
			if (passage) {
				var currentScrollPosition = window.pageYOffset;
				var currentPassage = State.passage;
				if (setargs) {
					Scripting.evalTwineScript(setargs);
				}
				Engine.play(passage);
				if (currentPassage == passage) {
					Scripting.evalJavaScript("window.scrollTo(0, " + currentScrollPosition + ");");
				}
			}
		}

		jQuery(inputElement).attr({
			id: this.name + "-" + r,
			name: this.name + "-" + r,
			type: 'color',
			value: value,
			tabindex: 0
		}).addClass("macro-" + this.name)
			.on("change", function() {
				State.setVar(varName, this.value);
				if (this.value != value) { // If the value has actually changed, reload the page.  Note != and not !== because types might be different
					gotoPassage();
				}
			})
			.appendTo(this.output);
	}
});