code:
:: Datatype Cleanup JS [script]

/*
	This function does not ensure values make sense. For example, it does not fix weird relations/relationships/rivalries/pregnancies/prosthetics.
	It only makes sure most datatypes are correct, and sets to default if not. Number values are clamped to the correct bounds.
	Any values that are supposed to be objects or arrays are not handled (yet).

	A tutorial on how to add to this passage:
		The || operator can be very useful for setting default values. To be precise,
			x = y || z
		is the same thing as
			if (y) {x = y}
			else {x = z}
		This means that if z is the default value, in the ideal case you could write x = x || z. If x is already in use, this won't change it, and if x is not defined it will set it to z.
		However, for example, if x is 0 but the default is -1 this will actually set x to -1! So care must be taken.

		Let's say you want to add slave.value to this function, and you want it to be a number.
		First, you need to take whatever slave.value currently is, and turn it into a number. You can use either +slave.value or Number(slave.value) to do this.
		Second, you need to determine what range to restrict slave.value to. You'll either use Math.max, Math.min, Math.clamp, or none of them.
		Finally, you need to consider the default value if the .max/.min/.clamp returned 0 (or NaN). To make a long story short,
			Use slave.value = Math.max(+slave.value, a) || default; if you need slave.value >= a.
			Use slave.value = Math.min(+slave.value, a) || default; if you need slave.value <= a.
			Use slave.value = Math.clamp(+slave.value, a, b) || default; if you need a <= slave.value <= b.
			Use slave.value = +slave.value || default; if slave.value can be any number.
		The exception to this is if the default != 0. In this case, it's usually good enough to just check if slave.value !== 0 first. The strict equality is important!

		If you want slave.value to be a string, there's no easy tricks to make sure it's already an accepted value. The simplest way is the following
			if (typeof slave.value !== "string") slave.value = default;
*/
window.SlaveDatatypeCleanup = function SlaveDatatypeCleanup (slave) {
	slaveAgeDatatypeCleanup(slave);
	slavePhysicalDatatypeCleanup(slave);
	slaveFaceDatatypeCleanup(slave);
	slaveHairDatatypeCleanup(slave);
	slaveBoobsDatatypeCleanup(slave);
	slaveButtDatatypeCleanup(slave);
	slavePregnancyDatatypeCleanup(slave);
	slaveBellyDatatypeCleanup(slave);
	slaveGenitaliaDatatypeCleanup(slave);
	slaveImplantsDatatypeCleanup(slave);
	slavePiercingsDatatypeCleanup(slave);
	slaveTattooDatatypeCleanup(slave);
	slaveCosmeticsDatatypeCleanup(slave);
	slaveDietDatatypeCleanup(slave);
	slavePornDatatypeCleanup(slave);
	slaveRelationDatatypeCleanup(slave);
	slaveSkillsDatatypeCleanup(slave);
	slaveStatCountDatatypeCleanup(slave);
	slavePreferencesDatatypeCleanup(slave);
	slaveRulesDatatypeCleanup(slave);
	slaveCustomStatsDatatypeCleanup(slave);
	slaveMiscellaneousDatatypeCleanup(slave);
	generatePronouns(slave);
};

window.slaveAgeDatatypeCleanup = function slaveAgeDatatypeCleanup(slave) {
	const V = State.variables;

	slave.birthWeek = Math.clamp(+slave.birthWeek, 0, 51) || 0;
	if (slave.age > 0) {
		slave.actualAge = Math.clamp(+slave.actualAge, V.minimumSlaveAge, Infinity) || slave.age; /* if undefined, this sets to slave.age */
	} else {
		slave.actualAge = Math.clamp(+slave.actualAge, V.minimumSlaveAge, Infinity) || 18;
		slave.age = slave.actualAge;
	}
	slave.visualAge = Math.max(+slave.visualAge, 0) || slave.actualAge;
	slave.physicalAge = Math.max(+slave.physicalAge, 0) || slave.actualAge;
	slave.ovaryAge = Math.max(+slave.ovaryAge, 0) || slave.physicalAge;
	slave.pubertyAgeXX = Math.max(+slave.pubertyAgeXX, 0) || V.fertilityAge;
	slave.pubertyAgeXY = Math.max(+slave.pubertyAgeXY, 0) || V.potencyAge;
	slave.ageAdjust = Math.clamp(+slave.ageAdjust, -40, 40) || 0;
	slave.NCSyouthening = Math.max(+slave.NCSyouthening, 0) || 0;
};

window.slavePhysicalDatatypeCleanup = function slavePhysicalDatatypeCleanup(slave) {
	if (typeof slave.nationality !== "string") {
		slave.nationality = "slave";
	}
	if (typeof slave.race !== "string") {
		nationalityToRace(slave);
	}
	if (typeof slave.origRace !== "string") {
		slave.origRace = slave.race;
	}
	if (typeof slave.skin !== "string") {
		slave.skin = "light";
	}
	if (typeof slave.origSkin !== "string") {
		slave.origSkin = slave.skin;
	}
	if (typeof slave.minorInjury !== "string") {
		slave.minorInjury = 0;
	}
	slave.health = Math.clamp(+slave.health, -100, 100) || 0;
	slave.muscles = Math.clamp(+slave.muscles, -100, 100) || 0;
	slave.weight = Math.clamp(+slave.weight, -100, 200) || 0;
	slave.waist = Math.clamp(+slave.waist, -100, 100) || 0;
	slave.height = Math.round(Math.max(+slave.height, 0)) || Math.round(Height.mean(slave));
	slave.shoulders = Math.clamp(+slave.shoulders, -2, 2) || 0;
	slave.hips = Math.clamp(+slave.hips, -2, 3) || 0;
};

window.slaveFaceDatatypeCleanup = function slaveFaceDatatypeCleanup(slave) {
	slave.face = Math.clamp(+slave.face, -100, 100) || 0;
	if (typeof slave.faceShape !== "string") {
		slave.faceShape = "normal";
	}
	slave.eyes = Math.clamp(+slave.eyes, -3, 1) || 1; /* if 0 or undefined, this sets to 1 */
	if (typeof slave.eyeColor !== "string") {
		slave.eyeColor = "brown";
	}
	if (typeof slave.origEye !== "string") {
		slave.origEye = slave.eyeColor;
	}
	if (typeof slave.pupil !== "string") {
		slave.pupil = "circular";
	}
	if (typeof slave.sclerae !== "string") {
		slave.sclerae = "white";
	}
	if (slave.lips !== 0) {
		slave.lips = Math.clamp(+slave.lips, 0, 100) || 15;
	}
};

window.slaveHairDatatypeCleanup = function slaveHairDatatypeCleanup(slave) {
	if (typeof slave.hColor !== "string") {
		slave.hColor = "brown";
	}
	if (typeof slave.origHColor !== "string") {
		slave.origHColor = slave.hColor;
	}
	if (slave.hLength !== 0) {
		slave.hLength = Math.clamp(+slave.hLength, 0, 300) || 60;
	}
	if (typeof slave.hStyle !== "string") {
		slave.hStyle = "long";
	}
	slave.haircuts = Math.clamp(+slave.haircuts, 0, 1) || 0;
	slave.bald = Math.clamp(+slave.bald, 0, 1) || 0;
	if (typeof slave.pubicHColor !== "string") {
		slave.pubicHColor = slave.hColor;
	}
	if (typeof slave.pubicHStyle !== "string") {
		slave.pubicHStyle = "neat";
	}
	if (typeof slave.underArmHColor !== "string") {
		slave.underArmHColor = "slave.hColor";
	}
	if (typeof slave.underArmHStyle !== "string") {
		slave.underArmHStyle = "waxed";
	}
	if (typeof slave.eyebrowHColor !== "string") {
		slave.eyebrowHColor = "slave.hColor";
	}
	if (typeof slave.eyebrowHStyle !== "string") {
		slave.eyebrowHStyle = "natural";
	}
	if (typeof slave.eyebrowFullness !== "string") {
		slave.eyebrowFullness = "natural";
	}
};

window.slaveBoobsDatatypeCleanup = function slaveBoobsDatatypeCleanup(slave) {
	slave.boobs = Math.max(+slave.boobs, 100) || 200;
	if (typeof slave.boobShape !== "string") {
		slave.boobShape = "normal";
	}
	if (typeof slave.nipples !== "string") {
		slave.nipples = "cute";
	}
	if (typeof slave.nipplesAccessory !== "string") {
		slave.nipplesAccessory = "none";
	}
	slave.areolae = Math.clamp(+slave.areolae, 0, 3) || 0;
	if (typeof slave.areolaeShape !== "string") {
		slave.areolaeShape = "circle";
	}
	slave.lactation = Math.clamp(+slave.lactation, 0, 2) || 0;
	slave.boobsMilk = Math.max(+slave.boobsMilk, 0) || 0;
	slave.lactationAdaptation = Math.clamp(+slave.lactationAdaptation, 0, 100) || 0;
};

window.slaveButtDatatypeCleanup = function slaveButtDatatypeCleanup(slave) {
	if (slave.butt !== 0) {
		slave.butt = Math.clamp(+slave.butt, 0, 20) || 1;
	}
	slave.anus = Math.clamp(+slave.anus, 0, 4) || 0;
	slave.analArea = Math.max(+slave.analArea, 0) || 0;
};

window.slavePregnancyDatatypeCleanup = function slavePregnancyDatatypeCleanup(slave) {
	slave.induce = Math.clamp(+slave.induce, 0, 1) || 0;
	slave.labor = Math.clamp(+slave.labor, 0, 1) || 0;
	slave.cSec = Math.clamp(+slave.cSec, 0, 1) || 0;
	slave.prematureBirth = Math.clamp(+slave.prematureBirth, 0, 1) || 0;
	slave.ovaries = Math.clamp(+slave.ovaries, 0, 1) || 0;
	slave.vasectomy = Math.clamp(+slave.vasectomy, 0, 1) || 0;
	slave.mpreg = Math.clamp(+slave.mpreg, 0, 1) || 0;
	slave.reservedChildren = WombReserveCount(slave, "incubator") || 0;
	slave.reservedChildrenNursery = WombReserveCount(slave, "nursery") || 0;
	if (slave.pregAdaptation !== 0) {
		slave.pregAdaptation = Math.max(+slave.pregAdaptation, 0) || 50;
	}
	slave.ovaImplant = Math.clamp(+slave.ovaImplant, -1, 2) || 0;
	slave.broodmother = Math.clamp(+slave.broodmother, 0, 3) || 0;
	slave.broodmotherFetuses = Math.max(+slave.broodmotherFetuses, 0) || 0;
	slave.broodmotherOnHold = Math.clamp(+slave.broodmotherOnHold, 0, 1) || 0;
	slave.pregSource = +slave.pregSource || 0;
	if (typeof slave.pregControl !== "string") {
		slave.pregControl = "none";
	}
	WombNormalizePreg(slave);
};

window.slaveBellyDatatypeCleanup = function slaveBellyDatatypeCleanup(slave) {
	slave.inflation = Math.clamp(+slave.inflation, 0, 3) || 0;
	if (typeof slave.inflationType !== "string") {
		slave.inflationType = "none";
	}
	slave.inflationMethod = Math.clamp(+slave.inflationMethod, 0, 3) || 0;
	slave.milkSource = Math.max(+slave.milkSource, 0) || 0;
	slave.cumSource = Math.max(+slave.cumSource, 0) || 0;
	slave.burst = Math.clamp(+slave.burst, 0, 1) || 0;
	if (slave.bellyImplant !== 0) {
		slave.bellyImplant = Math.max(+slave.bellyImplant, -1) || -1;
	}
	slave.cervixImplant = Math.clamp(+slave.cervixImplant, 0, 1) || 0;
	slave.bellySag = Math.max(+slave.bellySag, 0) || 0;
	slave.bellySagPreg = Math.max(+slave.bellySagPreg, 0) || slave.bellySag;
	slave.bellyPain = Math.clamp(+slave.bellyPain, 0, 2) || 0;
	SetBellySize(slave);
};

window.slaveGenitaliaDatatypeCleanup = function slaveGenitaliaDatatypeCleanup(slave) {
	slave.vagina = Math.clamp(+slave.vagina, -1, 10) || 0;
	slave.vaginaLube = Math.clamp(+slave.vaginaLube, 0, 2) || 0;
	slave.labia = Math.clamp(+slave.labia, 0, 3) || 0;
	slave.clit = Math.clamp(+slave.clit, 0, 5) || 0;
	slave.foreskin = Math.max(+slave.foreskin, 0) || 0;
	slave.dick = Math.max(+slave.dick, 0) || 0;
	if (slave.dick && slave.prostate !== 0) {
		slave.prostate = Math.clamp(+slave.prostate, 0, 3) || 1;
	} else {
		slave.prostate = Math.clamp(+slave.prostate, 0, 3) || 0;
	}
	slave.balls = Math.max(+slave.balls, 0) || 0;
	slave.scrotum = Math.max(+slave.scrotum, 0) || slave.balls;
};

window.slaveImplantsDatatypeCleanup = function slaveImplantsDatatypeCleanup(slave) {
	slave.ageImplant = Math.clamp(+slave.ageImplant, 0, 1) || 0;
	slave.faceImplant = Math.clamp(+slave.faceImplant, 0, 100) || 0;
	slave.lipsImplant = Math.clamp(+slave.lipsImplant, 0, 100) || 0;
	slave.voiceImplant = Math.clamp(+slave.voiceImplant, -1, 1) || 0;
	slave.boobsImplant = Math.max(+slave.boobsImplant, 0) || 0;
	slave.boobsImplantType = Math.clamp(+slave.boobsImplantType, 0, 1) || 0;
	slave.breastMesh = Math.clamp(+slave.breastMesh, 0, 1) || 0;
	slave.buttImplant = Math.clamp(+slave.buttImplant, 0, 3) || 0;
	slave.buttImplantType = Math.clamp(+slave.buttImplantType, 0, 1) || 0;
	slave.heightImplant = Math.clamp(+slave.heightImplant, -1, 1) || 0;
	slave.earImplant = Math.clamp(+slave.earImplant, 0, 1) || 0;
	slave.shouldersImplant = Math.clamp(+slave.shouldersImplant, -1, 1) || 0;
	slave.hipsImplant = Math.clamp(+slave.hipsImplant, -1, 1) || 0;
};

window.slavePiercingsDatatypeCleanup = function slavePiercingsDatatypeCleanup(slave) {
	slave.earPiercing = Math.clamp(+slave.earPiercing, 0, 2) || 0;
	slave.nosePiercing = Math.clamp(+slave.nosePiercing, 0, 2) || 0;
	slave.eyebrowPiercing = Math.clamp(+slave.eyebrowPiercing, 0, 2) || 0;
	slave.lipsPiercing = Math.clamp(+slave.lipsPiercing, 0, 2) || 0;
	slave.tonguePiercing = Math.clamp(+slave.tonguePiercing, 0, 2) || 0;
	slave.nipplesPiercing = Math.clamp(+slave.nipplesPiercing, 0, 2) || 0;
	slave.areolaePiercing = Math.clamp(+slave.areolaePiercing, 0, 2) || 0;
	slave.corsetPiercing = Math.clamp(+slave.corsetPiercing, 0, 1) || 0;
	slave.navelPiercing = Math.clamp(+slave.navelPiercing, 0, 2) || 0;
	slave.clitPiercing = Math.clamp(+slave.clitPiercing, 0, 3) || 0;
	slave.vaginaPiercing = Math.clamp(+slave.vaginaPiercing, 0, 2) || 0;
	slave.dickPiercing = Math.clamp(+slave.dickPiercing, 0, 2) || 0;
	slave.anusPiercing = Math.clamp(+slave.anusPiercing, 0, 2) || 0;
};

window.slaveTattooDatatypeCleanup = function slaveTattooDatatypeCleanup(slave) {
	if (typeof slave.shouldersTat !== "string") {
		slave.shouldersTat = 0;
	}
	if (typeof slave.lipsTat !== "string") {
		slave.lipsTat = 0;
	}
	if (typeof slave.boobsTat !== "string") {
		slave.boobsTat = 0;
	}
	if (typeof slave.armsTat !== "string") {
		slave.armsTat = 0;
	}
	if (typeof slave.backTat !== "string") {
		slave.backTat = 0;
	}
	if (typeof slave.stampTat !== "string") {
		slave.stampTat = 0;
	}
	if (typeof slave.buttTat !== "string") {
		slave.buttTat = 0;
	}
	if (typeof slave.vaginaTat !== "string") {
		slave.vaginaTat = 0;
	}
	if (typeof slave.dickTat !== "string") {
		slave.dickTat = 0;
	}
	if (typeof slave.anusTat !== "string") {
		slave.anusTat = 0;
	}
	if (typeof slave.legsTat !== "string") {
		slave.legsTat = 0;
	}
	if (typeof slave.bellyTat !== "string") {
		slave.bellyTat = 0;
	}
	if (typeof slave.customTat !== "string") {
		slave.customTat = "";
	}
};

window.slaveCosmeticsDatatypeCleanup = function slaveCosmeticsDatatypeCleanup(slave) {
	slave.makeup = Math.clamp(+slave.makeup, 0, 8) || 0;
	slave.nails = Math.clamp(+slave.nails, 0, 9) || 0;
	slave.scars = Math.clamp(+slave.scars, 0, 6) || 0;
	slave.choosesOwnClothes = Math.clamp(+slave.choosesOwnClothes, 0, 1) || 0;
	if (typeof slave.clothes !== "string") {
		slave.clothes = "no clothing";
	}
	if (typeof slave.collar !== "string") {
		slave.collar = "none";
	}
	if (typeof slave.shoes !== "string") {
		slave.shoes = "none";
	}
	if (typeof slave.eyewear !== "string") {
		slave.eyewear = "none";
	}
	slave.brand = Math.clamp(+slave.brand, 0, 1) || 0;
	if (typeof slave.brandLocation !== "string") {
		slave.brandLocation = 0;
	}
	if (typeof slave.markings !== "string") {
		slave.markings = "none";
	}
	if (typeof slave.bellyAccessory !== "string") {
		slave.bellyAccessory = "none";
	}
	if (typeof slave.vaginalAccessory !== "string") {
		slave.vaginalAccessory = "none";
	}
	if (typeof slave.dickAccessory !== "string") {
		slave.dickAccessory = "none";
	}
	if (typeof slave.legAccessory !== "string") {
		slave.legAccessory = "none";
	}
	if (typeof slave.buttplug !== "string") {
		slave.buttplug = "none";
	}
	if (typeof slave.buttplugAttachment !== "string") {
		slave.buttplugAttachment = "none";
	}
	if (typeof slave.headAccessory !== "string") {
		slave.headAccessory = "none";
	}
	if (typeof slave.rearAccessory !== "string") {
		slave.rearAccessory = "none";
	}
	if (typeof slave.backAccessory !== "string") {
		slave.backAccessory = "none";
	}
};

window.slaveDietDatatypeCleanup = function slaveDietDatatypeCleanup(slave) {
	if (typeof slave.diet !== "string") {
		slave.diet = "healthy";
	}
	slave.dietCum = Math.clamp(+slave.dietCum, 0, 2) || 0;
	slave.dietMilk = Math.clamp(+slave.dietMilk, 0, 2) || 0;
	slave.onDiet = Math.clamp(+slave.onDiet, 0, 1) || 0;
	slave.hormones = Math.clamp(+slave.hormones, -2, 2) || 0;
	slave.hormoneBalance = Math.clamp(+slave.hormoneBalance, -400, 400) || 0;
	if (typeof slave.drugs !== "string") {
		slave.drugs = "no drugs";
	}
	slave.aphrodisiacs = Math.clamp(+slave.aphrodisiacs, 0, 2) || 0;
	slave.curatives = Math.clamp(+slave.curatives, 0, 2) || 0;
};

window.slavePornDatatypeCleanup = function slavePornDatatypeCleanup(slave) {
	slave.pornFeed = Math.clamp(+slave.pornFeed, 0, 1) || 0;
	slave.pornFame = Math.max(+slave.pornFame, 0) || 0;
	slave.pornFameSpending = Math.max(+slave.pornFameSpending, 0) || 0;
	slave.pornPrestige = Math.clamp(+slave.pornPrestige, 0, 3) || 0;
	if (typeof slave.pornPrestigeDesc !== "string") {
		slave.pornPrestigeDesc = 0;
	}
	if (typeof slave.pornFameType !== "string") {
		slave.pornFameType = "none";
	}
	if (typeof slave.pornFocus !== "string") {
		slave.pornFocus = "none";
	}
	slave.pornTypeGeneral = Math.max(+slave.pornTypeGeneral, 0) || 0;
	slave.pornTypeFuckdoll = Math.max(+slave.pornTypeFuckdoll, 0) || 0;
	slave.pornTypeRape = Math.max(+slave.pornTypeRape, 0) || 0;
	slave.pornTypePreggo = Math.max(+slave.pornTypePreggo, 0) || 0;
	slave.pornTypeBBW = Math.max(+slave.pornTypeBBW, 0) || 0;
	slave.pornTypeGainer = Math.max(+slave.pornTypeGainer, 0) || 0;
	slave.pornTypeStud = Math.max(+slave.pornTypeStud, 0) || 0;
	slave.pornTypeLoli = Math.max(+slave.pornTypeLoli, 0) || 0;
	slave.pornTypeDeepThroat = Math.max(+slave.pornTypeDeepThroat, 0) || 0;
	slave.pornTypeStruggleFuck = Math.max(+slave.pornTypeStruggleFuck, 0) || 0;
	slave.pornTypePainal = Math.max(+slave.pornTypePainal, 0) || 0;
	slave.pornTypeTease = Math.max(+slave.pornTypeTease, 0) || 0;
	slave.pornTypeRomantic = Math.max(+slave.pornTypeRomantic, 0) || 0;
	slave.pornTypePervert = Math.max(+slave.pornTypePervert, 0) || 0;
	slave.pornTypeCaring = Math.max(+slave.pornTypeCaring, 0) || 0;
	slave.pornTypeUnflinching = Math.max(+slave.pornTypeUnflinching, 0) || 0;
	slave.pornTypeSizeQueen = Math.max(+slave.pornTypeSizeQueen, 0) || 0;
	slave.pornTypeNeglectful = Math.max(+slave.pornTypeNeglectful, 0) || 0;
	slave.pornTypeCumAddict = Math.max(+slave.pornTypeCumAddict, 0) || 0;
	slave.pornTypeAnalAddict = Math.max(+slave.pornTypeAnalAddict, 0) || 0;
	slave.pornTypeAttentionWhore = Math.max(+slave.pornTypeAttentionWhore, 0) || 0;
	slave.pornTypeBreastGrowth = Math.max(+slave.pornTypeBreastGrowth, 0) || 0;
	slave.pornTypeAbusive = Math.max(+slave.pornTypeAbusive, 0) || 0;
	slave.pornTypeMalicious = Math.max(+slave.pornTypeMalicious, 0) || 0;
	slave.pornTypeSelfHating = Math.max(+slave.pornTypeSelfHating, 0) || 0;
	slave.pornTypeBreeder = Math.max(+slave.pornTypeBreeder, 0) || 0;
	slave.pornTypeSub = Math.max(+slave.pornTypeSub, 0) || 0;
	slave.pornTypeCumSlut = Math.max(+slave.pornTypeCumSlut, 0) || 0;
	slave.pornTypeAnal = Math.max(+slave.pornTypeAnal, 0) || 0;
	slave.pornTypeHumiliation = Math.max(+slave.pornTypeHumiliation, 0) || 0;
	slave.pornTypeBoobs = Math.max(+slave.pornTypeBoobs, 0) || 0;
	slave.pornTypeDom = Math.max(+slave.pornTypeDom, 0) || 0;
	slave.pornTypeSadist = Math.max(+slave.pornTypeSadist, 0) || 0;
	slave.pornTypeMasochist = Math.max(+slave.pornTypeMasochist, 0) || 0;
	slave.pornTypePregnancy = Math.max(+slave.pornTypePregnancy, 0) || 0;
};

window.slaveRelationDatatypeCleanup = function slaveRelationDatatypeCleanup(slave) {
	slave.mother = +slave.mother || 0;
	slave.father = +slave.father || 0;
	if (State.variables.familyTesting == 0) {
		slave.relationTarget = Math.max(+slave.relationTarget, 0) || 0;
	}
	slave.canRecruit = Math.clamp(+slave.canRecruit, 0, 1) || 0;
	slave.relationship = Math.clamp(+slave.relationship, -3, 5) || 0;
	slave.relationshipTarget = Math.max(+slave.relationshipTarget, 0) || 0;
	slave.rivalryTarget = Math.max(+slave.rivalryTarget, 0) || 0;
	slave.rivalry = Math.clamp(+slave.rivalry, 0, 3) || 0;
};

window.slaveSkillsDatatypeCleanup = function slaveSkillsDatatypeCleanup(slave) {
	slave.oralSkill = Math.clamp(+slave.oralSkill, 0, 100) || 0;
	slave.vaginalSkill = Math.clamp(+slave.vaginalSkill, 0, 100) || 0;
	slave.analSkill = Math.clamp(+slave.analSkill, 0, 100) || 0;
	slave.whoreSkill = Math.clamp(+slave.whoreSkill, 0, 100) || 0;
	slave.entertainSkill = Math.clamp(+slave.entertainSkill, 0, 100) || 0;
	slave.combatSkill = Math.clamp(+slave.combatSkill, 0, 1) || 0;
	slave.skillHG = Math.clamp(+slave.skillHG, 0, 200) || 0;
	slave.skillRC = Math.clamp(+slave.skillRC, 0, 200) || 0;
	slave.skillBG = Math.clamp(+slave.skillBG, 0, 200) || 0;
	slave.skillMD = Math.clamp(+slave.skillMD, 0, 200) || 0;
	slave.skillDJ = Math.clamp(+slave.skillDJ, 0, 200) || 0;
	slave.skillNU = Math.clamp(+slave.skillNU, 0, 200) || 0;
	slave.skillTE = Math.clamp(+slave.skillTE, 0, 200) || 0;
	slave.skillAT = Math.clamp(+slave.skillAT, 0, 200) || 0;
	slave.skillMT = Math.clamp(+slave.skillMT, 0, 200) || 0;
	slave.skillST = Math.clamp(+slave.skillST, 0, 200) || 0;
	slave.skillMM = Math.clamp(+slave.skillMM, 0, 200) || 0;
	slave.skillFA = Math.clamp(+slave.skillFA, 0, 200) || 0;
	slave.skillWA = Math.clamp(+slave.skillWA, 0, 200) || 0;
	slave.skillS = Math.clamp(+slave.skillS, 0, 200) || 0;
	slave.skillE = Math.clamp(+slave.skillE, 0, 200) || 0;
	slave.skillW = Math.clamp(+slave.skillW, 0, 200) || 0;
};

window.slaveStatCountDatatypeCleanup = function slaveStatCountDatatypeCleanup(slave) {
	slave.oralCount = Math.max(+slave.oralCount, 0) || 0;
	slave.vaginalCount = Math.max(+slave.vaginalCount, 0) || 0;
	slave.analCount = Math.max(+slave.analCount, 0) || 0;
	slave.publicCount = Math.max(+slave.publicCount, 0) || 0;
	slave.mammaryCount = Math.max(+slave.mammaryCount, 0) || 0;
	slave.penetrativeCount = Math.max(+slave.penetrativeCount, 0) || 0;
	slave.pitKills = Math.max(+slave.pitKills, 0) || 0;
	slave.milk = Math.max(+slave.milk, 0) || 0;
	slave.cum = Math.max(+slave.cum, 0) || 0;
	slave.births = Math.max(+slave.births, 0) || 0;
	slave.birthsTotal = Math.max(+slave.birthsTotal, 0) || slave.births;
	slave.laborCount = Math.max(+slave.laborCount, 0) || slave.birthsTotal;
	slave.slavesFathered = Math.max(+slave.slavesFathered, 0) || 0;
	slave.PCChildrenFathered = Math.max(+slave.PCChildrenFathered, 0) || 0;
	slave.slavesKnockedUp = Math.max(+slave.slavesKnockedUp, 0) || 0;
	slave.PCKnockedUp = Math.max(+slave.PCKnockedUp, 0) || 0;
	slave.bodySwap = Math.max(+slave.bodySwap, 0) || 0;
};

window.slavePreferencesDatatypeCleanup = function slavePreferencesDatatypeCleanup(slave) {
	slave.energy = Math.clamp(+slave.energy, 0, 100) || 0;
	slave.need = Math.max(+slave.need, 0) || 0;
	slave.attrXY = Math.clamp(+slave.attrXY, 0, 100) || 0;
	slave.attrXX = Math.clamp(+slave.attrXX, 0, 100) || 0;
	slave.attrKnown = Math.clamp(+slave.attrKnown, 0, 1) || 0;
	slave.fetishStrength = Math.clamp(+slave.fetishStrength, 0, 100) || 0;
	slave.fetishKnown = Math.clamp(+slave.fetishKnown, 0, 1) || 0;
};

window.slaveRulesDatatypeCleanup = function slaveRulesDatatypeCleanup(slave) {
	if (typeof slave.standardPunishment !== "string") {
		slave.standardPunishment = "situational";
	}
	if (typeof slave.standardReward !== "string") {
		slave.standardReward = "situational";
	}
	if (slave.useRulesAssistant !== 0) {
		slave.useRulesAssistant = 1;
	}
	slave.choosesOwnAssignment = Math.clamp(+slave.choosesOwnAssignment, 0) || 0;
	slave.HGExclude = Math.clamp(+slave.HGExclude, 0, 1) || 0;
	slave.choosesOwnChastity = Math.clamp(+slave.choosesOwnChastity, 0, 1) || 0;
	slave.breedingMark = Math.clamp(+slave.breedingMark, 0, 1) || 0;
	slave.rudeTitle = Math.clamp(+slave.rudeTitle, 0, 1) || 0;
};

window.slaveCustomStatsDatatypeCleanup = function slaveCustomStatsDatatypeCleanup(slave) {
	if (typeof slave.customLabel !== "string") {
		slave.customLabel = "";
	}
	if (typeof slave.customDesc !== "string") {
		slave.customDesc = "";
	}
	if (typeof slave.customTitle !== "string") {
		slave.customTitle = "";
	}
	if (typeof slave.customTitleLisp !== "string") {
		slave.customTitleLisp = "";
	}
	if (typeof slave.customImage !== "string") {
		slave.customImage = 0;
	}
};

window.slaveMiscellaneousDatatypeCleanup = function slaveMiscellaneousDatatypeCleanup(slave) {
	slave.weekAcquired = Math.max(+slave.weekAcquired, 0) || 0;
	slave.newGamePlus = Math.clamp(+slave.newGamePlus, 0, 1) || 0;
	slave.prestige = Math.clamp(+slave.prestige, 0, 3) || 0;
	slave.devotion = Math.clamp(+slave.devotion, -100, 100) || 0;
	slave.oldDevotion = Math.clamp(+slave.oldDevotion, -100, 100) || 0;
	slave.trust = Math.clamp(+slave.trust, -100, 100) || 0;
	slave.oldTrust = Math.clamp(+slave.oldTrust, -100, 100) || 0;
	slave.fuckdoll = Math.clamp(+slave.fuckdoll, 0, 100) || 0;
	slave.chem = Math.max(+slave.chem, 0) || 0;
	slave.addict = Math.max(+slave.addict, 0) || 0;
	slave.intelligence = Math.clamp(+slave.intelligence, -100, 100) || 0;
	slave.intelligenceImplant = Math.clamp(+slave.intelligenceImplant, 0, 30) || 0;
	slave.premature = Math.clamp(+slave.premature, 0, 1) || 0;
	slave.tankBaby = Math.clamp(+slave.tankBaby, 0, 2) || 0;
	slave.subTarget = Math.max(+slave.subTarget, 0) || 0;
	slave.sentence = Math.max(+slave.sentence, 0) || 0;
	slave.training = Math.clamp(+slave.training, 0, 150) || 0;
	if (slave.indenture !== 0) {
		slave.indenture = Math.max(+slave.indenture, -1) || -1;
	}
	slave.indentureRestrictions = Math.clamp(+slave.indentureRestriction, 0, 2) || 0;
	slave.tired = Math.clamp(+slave.tired, 0, 1) || 0;
	slave.hears = Math.clamp(+slave.hears, -2, 0) || 0;
	if (typeof slave.earwear !== "string") {
		slave.earwear = "none";
	}
	slave.heels = Math.clamp(+slave.heels, 0, 1) || 0;
	slave.amp = Math.clamp(+slave.amp, -5, 1) || 0;
	slave.PLimb = Math.clamp(+slave.PLimb, 0, 1) || 0;
	if (slave.voice !== 0) {
		slave.voice = Math.clamp(+slave.voice, 0, 3) || 1;
	}
	slave.electrolarynx = Math.clamp(+slave.electrolarynx, 0, 1) || 0;
	slave.accent = Math.clamp(+slave.accent, 0, 3) || 0;
	slave.missingEyes = Math.clamp(+slave.missingEyes, 0, 3) || 0;
	slave.missingArms = Math.clamp(+slave.missingArms, 0, 3) || 0;
	slave.missingLegs = Math.clamp(+slave.missingLegs, 0, 3) || 0;
	if (typeof slave.ballType !== "string") {
		slave.ballType = "human";
	}
	if (typeof slave.eggType !== "string") {
		slave.eggType = "human";
	}
	if (typeof slave.origBodyOwner !== "string") {
		slave.origBodyOwner = "";
	}
	slave.origBodyOwnerID = Math.max(+slave.origBodyOwnerID, 0) || 0;
	if (typeof slave.death !== "string") {
		slave.death = "";
	}
};

/* a lot of this may need to be removed */
window.ChildDatatypeCleanup = function ChildDatatypeCleanup(child) {
	childAgeDatatypeCleanup(child);
	childPhysicalDatatypeCleanup(child);
	childFaceDatatypeCleanup(child);
	childHairDatatypeCleanup(child);
	childBoobsDatatypeCleanup(child);
	childButtDatatypeCleanup(child);
	childPregnancyDatatypeCleanup(child);
	childBellyDatatypeCleanup(child);
	childGenitaliaDatatypeCleanup(child);
	childImplantsDatatypeCleanup(child);
	childPiercingsDatatypeCleanup(child);
	childTattooDatatypeCleanup(child);
	childCosmeticsDatatypeCleanup(child);
	childDietDatatypeCleanup(child);
	childPornDatatypeCleanup(child);
	childRelationDatatypeCleanup(child);
	childSkillsDatatypeCleanup(child);
	childStatCountDatatypeCleanup(child);
	childPreferencesDatatypeCleanup(child);
	childRulesDatatypeCleanup(child);
	childCustomStatsDatatypeCleanup(child);
	childMiscellaneousDatatypeCleanup(child);
	generatePronouns(child);
};

window.childAgeDatatypeCleanup = function childAgeDatatypeCleanup(child) {
	const V = State.variables;

	child.birthWeek = Math.clamp(+child.birthWeek, 0, 51) || 0;
	if (child.age > 0) {
		child.actualAge = Math.clamp(+child.actualAge, V.minimumChildAge, Infinity) || child.age; /* if undefined, this sets to child.age */
	} else {
		child.actualAge = Math.clamp(+child.actualAge, V.minimumChildAge, Infinity) || 18;
		child.age = child.actualAge;
	}
	child.visualAge = Math.max(+child.visualAge, 0) || child.actualAge;
	child.physicalAge = Math.max(+child.physicalAge, 0) || child.actualAge;
	child.ovaryAge = Math.max(+child.ovaryAge, 0) || child.physicalAge;
	child.pubertyAgeXX = Math.max(+child.pubertyAgeXX, 0) || V.fertilityAge;
	child.pubertyAgeXY = Math.max(+child.pubertyAgeXY, 0) || V.potencyAge;
};

window.childPhysicalDatatypeCleanup = function childPhysicalDatatypeCleanup(child) {
	if (typeof child.nationality !== "string") {
		child.nationality = "child";
	}
	if (typeof child.race !== "string") {
		nationalityToRace(child);
	}
	if (typeof child.origRace !== "string") {
		child.origRace = child.race;
	}
	if (typeof child.skin !== "string") {
		child.skin = "light";
	}
	if (typeof child.origSkin !== "string") {
		child.origSkin = child.skin;
	}
	if (typeof child.minorInjury !== "string") {
		child.minorInjury = 0;
	}
	child.health = Math.clamp(+child.health, -100, 100) || 0;
	child.muscles = Math.clamp(+child.muscles, -100, 100) || 0;
	child.weight = Math.clamp(+child.weight, -100, 200) || 0;
	child.waist = Math.clamp(+child.waist, -100, 100) || 0;
	child.height = Math.round(Math.max(+child.height, 0)) || Math.round(Height.mean(child));
	child.shoulders = Math.clamp(+child.shoulders, -2, 2) || 0;
	child.hips = Math.clamp(+child.hips, -2, 3) || 0;
};

window.childFaceDatatypeCleanup = function childFaceDatatypeCleanup(child) {
	child.face = Math.clamp(+child.face, -100, 100) || 0;
	if (typeof child.faceShape !== "string") {
		child.faceShape = "normal";
	}
	child.eyes = Math.clamp(+child.eyes, -3, 1) || 1; /* if 0 or undefined, this sets to 1 */
	if (typeof child.eyeColor !== "string") {
		child.eyeColor = "brown";
	}
	if (typeof child.origEye !== "string") {
		child.origEye = child.eyeColor;
	}
	if (typeof child.pupil !== "string") {
		child.pupil = "circular";
	}
	if (typeof child.sclerae !== "string") {
		child.sclerae = "white";
	}
	if (child.lips !== 0) {
		child.lips = Math.clamp(+child.lips, 0, 100) || 15;
	}
};

window.childHairDatatypeCleanup = function childHairDatatypeCleanup(child) {
	if (typeof child.hColor !== "string") {
		child.hColor = "brown";
	}
	if (typeof child.origHColor !== "string") {
		child.origHColor = child.hColor;
	}
	if (child.hLength !== 0) {
		child.hLength = Math.clamp(+child.hLength, 0, 300) || 60;
	}
	if (typeof child.hStyle !== "string") {
		child.hStyle = "long";
	}
	child.haircuts = Math.clamp(+child.haircuts, 0, 1) || 0;
	child.bald = Math.clamp(+child.bald, 0, 1) || 0;
	if (typeof child.pubicHColor !== "string") {
		child.pubicHColor = child.hColor;
	}
	if (typeof child.pubicHStyle !== "string") {
		child.pubicHStyle = "neat";
	}
	if (typeof child.underArmHColor !== "string") {
		child.underArmHColor = "child.hColor";
	}
	if (typeof child.underArmHStyle !== "string") {
		child.underArmHStyle = "waxed";
	}
	if (typeof child.eyebrowHColor !== "string") {
		child.eyebrowHColor = "child.hColor";
	}
	if (typeof child.eyebrowHStyle !== "string") {
		child.eyebrowHStyle = "natural";
	}
	if (typeof child.eyebrowFullness !== "string") {
		child.eyebrowFullness = "natural";
	}
};

window.childBoobsDatatypeCleanup = function childBoobsDatatypeCleanup(child) {
	child.boobs = Math.max(+child.boobs, 100) || 200;
	if (typeof child.boobShape !== "string") {
		child.boobShape = "normal";
	}
	if (typeof child.nipples !== "string") {
		child.nipples = "cute";
	}
	if (typeof child.nipplesAccessory !== "string") {
		child.nipplesAccessory = "none";
	}
	child.areolae = Math.clamp(+child.areolae, 0, 3) || 0;
	if (typeof child.areolaeShape !== "string") {
		child.areolaeShape = "circle";
	}
	child.lactation = Math.clamp(+child.lactation, 0, 2) || 0;
	child.lactationAdaptation = Math.clamp(+child.lactationAdaptation, 0, 100) || 0;
};

window.childButtDatatypeCleanup = function childButtDatatypeCleanup(child) {
	if (child.butt !== 0) {
		child.butt = Math.clamp(+child.butt, 0, 20) || 1;
	}
	child.anus = Math.clamp(+child.anus, 0, 4) || 0;
	child.analArea = Math.max(+child.analArea, 0) || 0;
};

window.childPregnancyDatatypeCleanup = function childPregnancyDatatypeCleanup(child) {
	child.induce = Math.clamp(+child.induce, 0, 1) || 0;
	child.labor = Math.clamp(+child.labor, 0, 1) || 0;
	child.cSec = Math.clamp(+child.cSec, 0, 1) || 0;
	child.prematureBirth = Math.clamp(+child.prematureBirth, 0, 1) || 0;
	child.ovaries = Math.clamp(+child.ovaries, 0, 1) || 0;
	child.vasectomy = Math.clamp(+child.vasectomy, 0, 1) || 0;
	child.mpreg = Math.clamp(+child.mpreg, 0, 1) || 0;
	child.reservedChildren = WombReserveCount(child, "incubator") || 0;
	child.reservedChildrenNursery = WombReserveCount(child, "nursery") || 0;
	if (child.pregAdaptation !== 0) {
		child.pregAdaptation = Math.max(+child.pregAdaptation, 0) || 50;
	}
	child.pregSource = +child.pregSource || 0;
	if (typeof child.pregControl !== "string") {
		child.pregControl = "none";
	}
	WombNormalizePreg(child);
};

window.childBellyDatatypeCleanup = function childBellyDatatypeCleanup(child) {
	child.bellySag = Math.max(+child.bellySag, 0) || 0;
	child.bellySagPreg = Math.max(+child.bellySagPreg, 0) || child.bellySag;
	SetBellySize(child);
};

window.childGenitaliaDatatypeCleanup = function childGenitaliaDatatypeCleanup(child) {
	child.vagina = Math.clamp(+child.vagina, -1, 10) || 0;
	child.vaginaLube = Math.clamp(+child.vaginaLube, 0, 2) || 0;
	child.labia = Math.clamp(+child.labia, 0, 3) || 0;
	child.clit = Math.clamp(+child.clit, 0, 5) || 0;
	child.foreskin = Math.max(+child.foreskin, 0) || 0;
	child.dick = Math.max(+child.dick, 0) || 0;
	if (child.dick && child.prostate !== 0) {
		child.prostate = Math.clamp(+child.prostate, 0, 3) || 1;
	} else {
		child.prostate = Math.clamp(+child.prostate, 0, 3) || 0;
	}
	child.balls = Math.max(+child.balls, 0) || 0;
	child.scrotum = Math.max(+child.scrotum, 0) || child.balls;
};

window.childImplantsDatatypeCleanup = function childImplantsDatatypeCleanup(child) {
	child.ageImplant = Math.clamp(+child.ageImplant, 0, 1) || 0;
	child.faceImplant = Math.clamp(+child.faceImplant, 0, 100) || 0;
	child.lipsImplant = Math.clamp(+child.lipsImplant, 0, 100) || 0;
	child.voiceImplant = Math.clamp(+child.voiceImplant, -1, 1) || 0;
	child.boobsImplant = Math.max(+child.boobsImplant, 0) || 0;
	child.boobsImplantType = Math.clamp(+child.boobsImplantType, 0, 1) || 0;
	child.breastMesh = Math.clamp(+child.breastMesh, 0, 1) || 0;
	child.buttImplant = Math.clamp(+child.buttImplant, 0, 3) || 0;
	child.buttImplantType = Math.clamp(+child.buttImplantType, 0, 1) || 0;
	child.earImplant = Math.clamp(+child.earImplant, 0, 1) || 0;
};

window.childPiercingsDatatypeCleanup = function childPiercingsDatatypeCleanup(child) {
	child.earPiercing = Math.clamp(+child.earPiercing, 0, 2) || 0;
	child.nosePiercing = Math.clamp(+child.nosePiercing, 0, 2) || 0;
	child.eyebrowPiercing = Math.clamp(+child.eyebrowPiercing, 0, 2) || 0;
	child.lipsPiercing = Math.clamp(+child.lipsPiercing, 0, 2) || 0;
	child.tonguePiercing = Math.clamp(+child.tonguePiercing, 0, 2) || 0;
	child.nipplesPiercing = Math.clamp(+child.nipplesPiercing, 0, 2) || 0;
	child.areolaePiercing = Math.clamp(+child.areolaePiercing, 0, 2) || 0;
	child.corsetPiercing = Math.clamp(+child.corsetPiercing, 0, 1) || 0;
	child.navelPiercing = Math.clamp(+child.navelPiercing, 0, 2) || 0;
	child.clitPiercing = Math.clamp(+child.clitPiercing, 0, 3) || 0;
	child.vaginaPiercing = Math.clamp(+child.vaginaPiercing, 0, 2) || 0;
	child.dickPiercing = Math.clamp(+child.dickPiercing, 0, 2) || 0;
	child.anusPiercing = Math.clamp(+child.anusPiercing, 0, 2) || 0;
};

window.childTattooDatatypeCleanup = function childTattooDatatypeCleanup(child) {
	if (typeof child.shouldersTat !== "string") {
		child.shouldersTat = 0;
	}
	if (typeof child.lipsTat !== "string") {
		child.lipsTat = 0;
	}
	if (typeof child.boobsTat !== "string") {
		child.boobsTat = 0;
	}
	if (typeof child.armsTat !== "string") {
		child.armsTat = 0;
	}
	if (typeof child.backTat !== "string") {
		child.backTat = 0;
	}
	if (typeof child.stampTat !== "string") {
		child.stampTat = 0;
	}
	if (typeof child.buttTat !== "string") {
		child.buttTat = 0;
	}
	if (typeof child.vaginaTat !== "string") {
		child.vaginaTat = 0;
	}
	if (typeof child.dickTat !== "string") {
		child.dickTat = 0;
	}
	if (typeof child.anusTat !== "string") {
		child.anusTat = 0;
	}
	if (typeof child.legsTat !== "string") {
		child.legsTat = 0;
	}
	if (typeof child.bellyTat !== "string") {
		child.bellyTat = 0;
	}
	if (typeof child.customTat !== "string") {
		child.customTat = "";
	}
};

window.childCosmeticsDatatypeCleanup = function childCosmeticsDatatypeCleanup(child) {
	child.makeup = Math.clamp(+child.makeup, 0, 8) || 0;
	child.nails = Math.clamp(+child.nails, 0, 9) || 0;
	child.scars = Math.clamp(+child.scars, 0, 6) || 0;
	child.choosesOwnClothes = Math.clamp(+child.choosesOwnClothes, 0, 1) || 0;
	if (typeof child.clothes !== "string") {
		child.clothes = "no clothing";
	}
	if (typeof child.collar !== "string") {
		child.collar = "none";
	}
	if (typeof child.shoes !== "string") {
		child.shoes = "none";
	}
	if (typeof child.eyewear !== "string") {
		child.eyewear = "none";
	}
	child.brand = Math.clamp(+child.brand, 0, 1) || 0;
	if (typeof child.brandLocation !== "string") {
		child.brandLocation = 0;
	}
	if (typeof child.markings !== "string") {
		child.markings = "none";
	}
	if (typeof child.bellyAccessory !== "string") {
		child.bellyAccessory = "none";
	}
	if (typeof child.vaginalAccessory !== "string") {
		child.vaginalAccessory = "none";
	}
	if (typeof child.dickAccessory !== "string") {
		child.dickAccessory = "none";
	}
	if (typeof child.legAccessory !== "string") {
		child.legAccessory = "none";
	}
	if (typeof child.buttplug !== "string") {
		child.buttplug = "none";
	}
	if (typeof child.buttplugAttachment !== "string") {
		child.buttplugAttachment = "none";
	}
	if (typeof child.headAccessory !== "string") {
		child.headAccessory = "none";
	}
	if (typeof child.rearAccessory !== "string") {
		child.rearAccessory = "none";
	}
	if (typeof child.backAccessory !== "string") {
		child.backAccessory = "none";
	}
};

window.childDietDatatypeCleanup = function childDietDatatypeCleanup(child) {
	if (typeof child.diet !== "string") {
		child.diet = "healthy";
	}
	child.dietCum = Math.clamp(+child.dietCum, 0, 2) || 0;
	child.dietMilk = Math.clamp(+child.dietMilk, 0, 2) || 0;
	child.onDiet = Math.clamp(+child.onDiet, 0, 1) || 0;
	child.hormones = Math.clamp(+child.hormones, -2, 2) || 0;
	child.hormoneBalance = Math.clamp(+child.hormoneBalance, -400, 400) || 0;
	if (typeof child.drugs !== "string") {
		child.drugs = "no drugs";
	}
	child.aphrodisiacs = Math.clamp(+child.aphrodisiacs, 0, 2) || 0;
	child.curatives = Math.clamp(+child.curatives, 0, 2) || 0;
};

window.childPornDatatypeCleanup = function childPornDatatypeCleanup(child) {
	child.pornFeed = Math.clamp(+child.pornFeed, 0, 1) || 0;
	child.pornFame = Math.max(+child.pornFame, 0) || 0;
	child.pornFameSpending = Math.max(+child.pornFameSpending, 0) || 0;
	child.pornPrestige = Math.clamp(+child.pornPrestige, 0, 3) || 0;
	if (typeof child.pornPrestigeDesc !== "string") {
		child.pornPrestigeDesc = 0;
	}
	if (typeof child.pornFameType !== "string") {
		child.pornFameType = "none";
	}
	if (typeof child.pornFocus !== "string") {
		child.pornFocus = "none";
	}
	child.pornTypeGeneral = Math.max(+child.pornTypeGeneral, 0) || 0;
	child.pornTypeFuckdoll = Math.max(+child.pornTypeFuckdoll, 0) || 0;
	child.pornTypeRape = Math.max(+child.pornTypeRape, 0) || 0;
	child.pornTypePreggo = Math.max(+child.pornTypePreggo, 0) || 0;
	child.pornTypeBBW = Math.max(+child.pornTypeBBW, 0) || 0;
	child.pornTypeGainer = Math.max(+child.pornTypeGainer, 0) || 0;
	child.pornTypeStud = Math.max(+child.pornTypeStud, 0) || 0;
	child.pornTypeLoli = Math.max(+child.pornTypeLoli, 0) || 0;
	child.pornTypeDeepThroat = Math.max(+child.pornTypeDeepThroat, 0) || 0;
	child.pornTypeStruggleFuck = Math.max(+child.pornTypeStruggleFuck, 0) || 0;
	child.pornTypePainal = Math.max(+child.pornTypePainal, 0) || 0;
	child.pornTypeTease = Math.max(+child.pornTypeTease, 0) || 0;
	child.pornTypeRomantic = Math.max(+child.pornTypeRomantic, 0) || 0;
	child.pornTypePervert = Math.max(+child.pornTypePervert, 0) || 0;
	child.pornTypeCaring = Math.max(+child.pornTypeCaring, 0) || 0;
	child.pornTypeUnflinching = Math.max(+child.pornTypeUnflinching, 0) || 0;
	child.pornTypeSizeQueen = Math.max(+child.pornTypeSizeQueen, 0) || 0;
	child.pornTypeNeglectful = Math.max(+child.pornTypeNeglectful, 0) || 0;
	child.pornTypeCumAddict = Math.max(+child.pornTypeCumAddict, 0) || 0;
	child.pornTypeAnalAddict = Math.max(+child.pornTypeAnalAddict, 0) || 0;
	child.pornTypeAttentionWhore = Math.max(+child.pornTypeAttentionWhore, 0) || 0;
	child.pornTypeBreastGrowth = Math.max(+child.pornTypeBreastGrowth, 0) || 0;
	child.pornTypeAbusive = Math.max(+child.pornTypeAbusive, 0) || 0;
	child.pornTypeMalicious = Math.max(+child.pornTypeMalicious, 0) || 0;
	child.pornTypeSelfHating = Math.max(+child.pornTypeSelfHating, 0) || 0;
	child.pornTypeBreeder = Math.max(+child.pornTypeBreeder, 0) || 0;
	child.pornTypeSub = Math.max(+child.pornTypeSub, 0) || 0;
	child.pornTypeCumSlut = Math.max(+child.pornTypeCumSlut, 0) || 0;
	child.pornTypeAnal = Math.max(+child.pornTypeAnal, 0) || 0;
	child.pornTypeHumiliation = Math.max(+child.pornTypeHumiliation, 0) || 0;
	child.pornTypeBoobs = Math.max(+child.pornTypeBoobs, 0) || 0;
	child.pornTypeDom = Math.max(+child.pornTypeDom, 0) || 0;
	child.pornTypeSadist = Math.max(+child.pornTypeSadist, 0) || 0;
	child.pornTypeMasochist = Math.max(+child.pornTypeMasochist, 0) || 0;
	child.pornTypePregnancy = Math.max(+child.pornTypePregnancy, 0) || 0;
};

window.childRelationDatatypeCleanup = function childRelationDatatypeCleanup(child) {
	child.mother = +child.mother || 0;
	child.father = +child.father || 0;
	if (State.variables.familyTesting == 0) {
		child.relationTarget = Math.max(+child.relationTarget, 0) || 0;
	}
	child.canRecruit = Math.clamp(+child.canRecruit, 0, 1) || 0;
	child.relationship = Math.clamp(+child.relationship, -3, 5) || 0;
	child.relationshipTarget = Math.max(+child.relationshipTarget, 0) || 0;
	child.rivalryTarget = Math.max(+child.rivalryTarget, 0) || 0;
	child.rivalry = Math.clamp(+child.rivalry, 0, 3) || 0;
};

window.childSkillsDatatypeCleanup = function childSkillsDatatypeCleanup(child) {
	child.oralSkill = Math.clamp(+child.oralSkill, 0, 100) || 0;
	child.vaginalSkill = Math.clamp(+child.vaginalSkill, 0, 100) || 0;
	child.analSkill = Math.clamp(+child.analSkill, 0, 100) || 0;
	child.whoreSkill = Math.clamp(+child.whoreSkill, 0, 100) || 0;
	child.entertainSkill = Math.clamp(+child.entertainSkill, 0, 100) || 0;
	child.combatSkill = Math.clamp(+child.combatSkill, 0, 1) || 0;
	child.skillHG = Math.clamp(+child.skillHG, 0, 200) || 0;
	child.skillRC = Math.clamp(+child.skillRC, 0, 200) || 0;
	child.skillBG = Math.clamp(+child.skillBG, 0, 200) || 0;
	child.skillMD = Math.clamp(+child.skillMD, 0, 200) || 0;
	child.skillDJ = Math.clamp(+child.skillDJ, 0, 200) || 0;
	child.skillNU = Math.clamp(+child.skillNU, 0, 200) || 0;
	child.skillTE = Math.clamp(+child.skillTE, 0, 200) || 0;
	child.skillAT = Math.clamp(+child.skillAT, 0, 200) || 0;
	child.skillMT = Math.clamp(+child.skillMT, 0, 200) || 0;
	child.skillST = Math.clamp(+child.skillST, 0, 200) || 0;
	child.skillMM = Math.clamp(+child.skillMM, 0, 200) || 0;
	child.skillFA = Math.clamp(+child.skillFA, 0, 200) || 0;
	child.skillWA = Math.clamp(+child.skillWA, 0, 200) || 0;
	child.skillS = Math.clamp(+child.skillS, 0, 200) || 0;
	child.skillE = Math.clamp(+child.skillE, 0, 200) || 0;
	child.skillW = Math.clamp(+child.skillW, 0, 200) || 0;
};

window.childStatCountDatatypeCleanup = function childStatCountDatatypeCleanup(child) {
	child.oralCount = Math.max(+child.oralCount, 0) || 0;
	child.vaginalCount = Math.max(+child.vaginalCount, 0) || 0;
	child.analCount = Math.max(+child.analCount, 0) || 0;
	child.publicCount = Math.max(+child.publicCount, 0) || 0;
	child.mammaryCount = Math.max(+child.mammaryCount, 0) || 0;
	child.penetrativeCount = Math.max(+child.penetrativeCount, 0) || 0;
	child.pitKills = Math.max(+child.pitKills, 0) || 0;
	child.milk = Math.max(+child.milk, 0) || 0;
	child.cum = Math.max(+child.cum, 0) || 0;
	child.births = Math.max(+child.births, 0) || 0;
	child.birthsTotal = Math.max(+child.birthsTotal, 0) || child.births;
	child.laborCount = Math.max(+child.laborCount, 0) || child.birthsTotal;
	child.childsFathered = Math.max(+child.childsFathered, 0) || 0;
	child.PCChildrenFathered = Math.max(+child.PCChildrenFathered, 0) || 0;
	child.childsKnockedUp = Math.max(+child.childsKnockedUp, 0) || 0;
	child.PCKnockedUp = Math.max(+child.PCKnockedUp, 0) || 0;
	child.bodySwap = Math.max(+child.bodySwap, 0) || 0;
};

window.childPreferencesDatatypeCleanup = function childPreferencesDatatypeCleanup(child) {
	child.energy = Math.clamp(+child.energy, 0, 100) || 0;
	child.need = Math.max(+child.need, 0) || 0;
	child.attrXY = Math.clamp(+child.attrXY, 0, 100) || 0;
	child.attrXX = Math.clamp(+child.attrXX, 0, 100) || 0;
	child.attrKnown = Math.clamp(+child.attrKnown, 0, 1) || 0;
	child.fetishStrength = Math.clamp(+child.fetishStrength, 0, 100) || 0;
	child.fetishKnown = Math.clamp(+child.fetishKnown, 0, 1) || 0;
};

window.childRulesDatatypeCleanup = function childRulesDatatypeCleanup(child) {
	child.breedingMark = Math.clamp(+child.breedingMark, 0, 1) || 0;
	child.rudeTitle = Math.clamp(+child.rudeTitle, 0, 1) || 0;
};

window.childCustomStatsDatatypeCleanup = function childCustomStatsDatatypeCleanup(child) {
	if (typeof child.customLabel !== "string") {
		child.customLabel = "";
	}
	if (typeof child.customDesc !== "string") {
		child.customDesc = "";
	}
	if (typeof child.customTitle !== "string") {
		child.customTitle = "";
	}
	if (typeof child.customTitleLisp !== "string") {
		child.customTitleLisp = "";
	}
	if (typeof child.customImage !== "string") {
		child.customImage = 0;
	}
};

window.childMiscellaneousDatatypeCleanup = function childMiscellaneousDatatypeCleanup(child) {
	child.weekAcquired = Math.max(+child.weekAcquired, 0) || 0;
	child.prestige = Math.clamp(+child.prestige, 0, 3) || 0;
	child.devotion = Math.clamp(+child.devotion, -100, 100) || 0;
	child.oldDevotion = Math.clamp(+child.oldDevotion, -100, 100) || 0;
	child.trust = Math.clamp(+child.trust, -100, 100) || 0;
	child.oldTrust = Math.clamp(+child.oldTrust, -100, 100) || 0;
	child.chem = Math.max(+child.chem, 0) || 0;
	child.addict = Math.max(+child.addict, 0) || 0;
	child.intelligence = Math.clamp(+child.intelligence, -100, 100) || 0;
	child.intelligenceImplant = Math.clamp(+child.intelligenceImplant, 0, 30) || 0;
	child.premature = Math.clamp(+child.premature, 0, 1) || 0;
	child.training = Math.clamp(+child.training, 0, 150) || 0;
	child.tired = Math.clamp(+child.tired, 0, 1) || 0;
	child.hears = Math.clamp(+child.hears, -2, 0) || 0;
	if (typeof child.earwear !== "string") {
		child.earwear = "none";
	}
	if (child.voice !== 0) {
		child.voice = Math.clamp(+child.voice, 0, 3) || 1;
	}
	child.electrolarynx = Math.clamp(+child.electrolarynx, 0, 1) || 0;
	child.accent = Math.clamp(+child.accent, 0, 3) || 0;
};

window.PCDatatypeCleanup = function PCDatatypeCleanup() {
	const V = State.variables;
	const PC = V.PC;

	if (PC.title !== 0) {
		PC.title = Math.clamp(+PC.title, 0, 1) || 1;
	}
	if (PC.dick !== 0) {
		PC.dick = Math.clamp(+PC.dick, 0, 1) || 1;
	}
	PC.vagina = Math.clamp(+PC.vagina, 0, 1) || 0;
	PC.belly = Math.max(+PC.belly, 0) || 0;
	PC.pregMood = Math.clamp(+PC.pregMood, 0, 2) || 0;
	PC.labor = Math.clamp(+PC.labor, 0, 1) || 0;
	PC.births = Math.max(+PC.births, 0) || 0;
	PC.boobs = Math.clamp(+PC.boobs, 0, 1) || 0;
	PC.boobsBonus = Math.clamp(+PC.boobsBonus, -3, 3) || 0;
	PC.boobsImplant = Math.clamp(+PC.boobsImplant, 0, 1) || 0;
	PC.butt = Math.clamp(+PC.butt, 0, 3) || 0;
	PC.buttImplant = Math.clamp(+PC.buttImplant, 0, 1) || 0;
	PC.balls = Math.clamp(+PC.balls, 0, 3) || 0;
	PC.ballsImplant = Math.clamp(+PC.ballsImplant, 0, 4) || 0;
	PC.degeneracy = Math.max(+PC.degeneracy, 0) || 0;
	PC.birthWeek = Math.clamp(+PC.birthWeek, 0, 51) || 0;
	if (PC.sexualEnergy !== 0 ) {
		PC.sexualEnergy = +PC.sexualEnergy || 4;
	}
	PC.refreshmentType = Math.clamp(+PC.refreshmentType, 0, 6) || 0;
	PC.trading = Math.clamp(+PC.trading, -100, 100) || 0;
	PC.warfare = Math.clamp(+PC.warfare, -100, 100) || 0;
	PC.slaving = Math.clamp(+PC.slaving, -100, 100) || 0;
	PC.engineering = Math.clamp(+PC.engineering, -100, 100) || 0;
	PC.medicine = Math.clamp(+PC.medicine, -100, 100) || 0;
	PC.hacking = Math.clamp(+PC.hacking, -100, 100) || 0;
	PC.cumTap = Math.max(+PC.cumTap, 0) || 0;
	PC.mother = +PC.mother || 0;
	PC.father = +PC.father || 0;
	PC.birthElite = Math.max(+PC.birthElite, 0) || 0;
	PC.birthMaster = Math.max(+PC.birthMaster, 0) || 0;
	PC.birthDegenerate = Math.max(+PC.birthDegenerate, 0) || 0;
	PC.birthClient = Math.max(+PC.birthClient, 0) || 0;
	PC.birthOther = Math.max(+PC.birthOther, 0) || 0;
	PC.birthArcOwner = Math.max(+PC.birthArcOwner, 0) || 0;
	PC.birthCitizen = Math.max(+PC.birthCitizen, 0) || 0;
	PC.birthSelf = Math.max(+PC.birthSelf, 0) || 0;
	PC.birthLab = Math.max(+PC.birthLab, 0) || 0;
	PC.slavesFathered = Math.max(+PC.slavesFathered, 0) || 0;
	PC.slavesKnockedUp = Math.max(+PC.slavesKnockedUp, 0) || 0;
	PC.intelligence = 100;
	PC.face = 100;
	PC.actualAge = Math.clamp(+PC.actualAge, 14, 80) || 35;
	PC.physicalAge = Math.clamp(+PC.physicalAge, 14, 80) || PC.actualAge;
	PC.visualAge = Math.clamp(+PC.visualAge, 14, 80) || PC.actualAge;
	PC.ovaryAge = Math.clamp(+PC.ovaryAge, 14, 80) || PC.physicalAge;
	if (V.playerAging !== 0) {
		V.playerAging = Math.clamp(+V.playerAging, 0, 2) || 2;
	}
	PC.newVag = Math.clamp(+PC.newVag, 0, 1) || 0;
	PC.reservedChildren = WombReserveCount(PC, "incubator") || 0;
	PC.reservedChildrenNursery = WombReserveCount(PC, "nursery") || 0;
	PC.fertDrugs = Math.clamp(+PC.fertDrugs, 0, 1) || 0;
	PC.forcedFertDrugs = Math.max(+PC.forcedFertDrugs, 0) || 0;
	PC.staminaPills = Math.clamp(+PC.staminaPills, 0, 1) || 0;
	PC.storedCum = Math.max(+PC.storedCum, 0) || 0;
	PC.mpreg = 0; /* So knockMeUp() may be used with the PC */

	PC.lactation = Math.max(+PC.lactation, 0) || 0;
	PC.lactationDuration = Math.max(+PC.lactationDuration, 0) || 0;

	if (PC.age !== undefined) {
		delete PC.age;
	}
	if (PC.indenture !== undefined) {
		delete PC.indenture;
	}
	if (PC.indentureRestrictions !== undefined) {
		delete PC.indentureRestrictions;
	}

	/* None of these are in use */
	PC.bellyPreg = PC.belly;
	PC.ageImplant = 0;
	PC.voiceImplant = 0;
	PC.accent = 0;
	PC.shoulders = 0;
	PC.shouldersImplant = 0;
};

window.ArcologyDatatypeCleanup = function ArcologyDatatypeCleanup() {
	const V = State.variables;

	V.ACitizens = Math.max(+V.ACitizens, 0) || 0;
	V.ASlaves = Math.max(+V.ASlaves, 0) || 0;
	V.shelterAbuse = Math.max(+V.shelterAbuse, 0) || 0;

	V.arcologies[0].prosperity = Math.clamp(+V.arcologies[0].prosperity, 1, 300) || 1;
	V.AProsperityCap = Math.max(+V.AProsperityCap, 0) || 0;
	V.arcologies[0].ownership = Math.clamp(+V.arcologies[0].ownership, 0, 100) || 0;
	V.arcologies[0].minority = Math.clamp(+V.arcologies[0].minority, 0, 100) || 0;

	V.economy = Math.max(+V.economy, 20) || 100;
	V.difficultySwitch = Math.clamp(+V.difficultySwitch, 0, 1) || 0;
	V.localEcon = Math.max(+V.localEcon, 20) || V.economy;
	V.econRate = Math.clamp(+V.econRate, 1, 4) || 2;
	V.slaveCostFactor = Math.max(+V.slaveCostFactor, 0) || 1;
	if (V.menialSupplyFactor !== 0) {
		V.menialSupplyFactor = Math.clamp(+V.menialSupplyFactor, -50000, 50000) || (1 - V.slaveCostFactor) * 400 * 1000 * 0.5; /* (1 - slaveCostFactor) * price elasticity * base price * 0.5 */
	}
	if (V.menialDemandFactor !== 0) {
		V.menialDemandFactor = Math.clamp(+V.menialDemandFactor, -50000, 50000) || -V.menialSupplyFactor;
	}
	V.slaveCostRandom = Math.clamp(+V.slaveCostRandom, -3, 3) || 0;
	V.demandTimer = Math.max(+V.demandTimer, 0) || 0;
	V.elapsedDemandTimer = Math.max(+V.elapsedDemandTimer, 0) || 0;
	V.supplyTimer = Math.max(+V.supplyTimer, 0) || 0;
	V.elapsedSupplyTimer = Math.max(+V.elapsedSupplyTimer, 0) || 0;
	V.deltaSupply = Math.clamp(+V.deltaSupply, -3000, 3000) || 0;
	V.deltaDemand = Math.clamp(+V.deltaDemand, -3000, 3000) || 0;
	V.econWeatherDamage = Math.max(+V.econWeatherDamage, 0) || 0;
	V.disasterResponse = Math.clamp(+V.disasterResponse, 0, 2) || 0;
	V.GDP = Math.max(+V.GDP, 1) || 278.6;
	V.NPCSlaves = Math.max(+V.NPCSlaves, 0) || 0;
	V.helots = Math.max(+V.helots, 0) || 0;
	V.fuckdolls  = Math.max(+V.fuckdolls , 0) || 0;
	V.menialBioreactors  = Math.max(+V.menialBioreactors , 0) || 0;

	V.foodCost = Math.trunc(2500/V.economy);
	V.drugsCost = Math.trunc(10000/V.economy);
	V.rulesCost = Math.trunc(10000/V.economy);
	V.modCost = Math.trunc(5000/V.economy);
	V.surgeryCost = Math.trunc(30000/V.economy);
	V.facilityCost = +V.facilityCost || 100;
	V.policyCost = +V.policyCost || 5000;

	V.TSS.studentsBought = Math.max(+V.TSS.studentsBought, 0) || 0;
	V.TSS.schoolProsperity = Math.clamp(+V.TSS.schoolProsperity, -10, 10) || 0;
	V.GRI.studentsBought = Math.max(+V.GRI.studentsBought, 0) || 0;
	V.GRI.schoolProsperity = Math.clamp(+V.GRI.schoolProsperity, -10, 10) || 0;
	V.SCP.studentsBought = Math.max(+V.SCP.studentsBought, 0) || 0;
	V.SCP.schoolProsperity = Math.clamp(+V.SCP.schoolProsperity, -10, 10) || 0;
	V.LDE.studentsBought = Math.max(+V.LDE.studentsBought, 0) || 0;
	V.LDE.schoolProsperity = Math.clamp(+V.LDE.schoolProsperity, -10, 10) || 0;
	V.TGA.studentsBought = Math.max(+V.TGA.studentsBought, 0) || 0;
	V.TGA.schoolProsperity = Math.clamp(+V.TGA.schoolProsperity, -10, 10) || 0;
	V.HA.studentsBought = Math.max(+V.HA.studentsBought, 0) || 0;
	V.HA.schoolProsperity = Math.clamp(+V.HA.schoolProsperity, -10, 10) || 0;
	V.TCR.studentsBought = Math.max(+V.TCR.studentsBought, 0) || 0;
	V.TCR.schoolProsperity = Math.clamp(+V.TCR.schoolProsperity, -10, 10) || 0;
	V.TFS.studentsBought = Math.max(+V.TFS.studentsBought, 0) || 0;
	V.TFS.schoolProsperity = Math.clamp(+V.TFS.schoolProsperity, -10, 10) || 0;
};

window.FacilityNameCleanup = function FacilityNameCleanup() {
	const V = State.variables;
	V.arcologies[0].name = V.arcologies[0].name || "Arcology X-4";
	V.brothelName = V.brothelName || "the Brothel";
	V.brothelNameCaps = V.brothelNameCaps || "The Brothel";
	V.dairyName = V.dairyName || "the Dairy";
	V.dairyNameCaps = V.dairyNameCaps || "The Dairy";
	V.clubName = V.clubName || "the Club";
	V.clubNameCaps = V.clubNameCaps || "The Club";
	V.servantsQuartersName = V.servantsQuartersName || "the Servants' Quarters";
	V.servantsQuartersNameCaps = V.servantsQuartersNameCaps || "The Servants' Quarters";
	V.schoolroomName = V.schoolroomName || "the Schoolroom";
	V.schoolroomNameCaps = V.schoolroomNameCaps || "The Schoolroom";
	V.spaName = V.spaName || "the Spa";
	V.spaNameCaps = V.spaNameCaps || "The Spa";
	V.nurseryName = V.nurseryName || "the Nursery";
	V.nurseryNameCaps = V.nurseryNameCaps || "The Nursery";
	V.clinicName = V.clinicName || "the Clinic";
	V.clinicNameCaps = V.clinicNameCaps || "The Clinic";
	V.arcadeName = V.arcadeName || "the Arcade";
	V.arcadeNameCaps = V.arcadeNameCaps || "The Arcade";
	V.cellblockName = V.cellblockName || "the Cellblock";
	V.cellblockNameCaps = V.cellblockNameCaps || "The Cellblock";
	V.masterSuiteName = V.masterSuiteName || "the Master Suite";
	V.masterSuiteNameCaps = V.masterSuiteNameCaps || "The Master Suite";
	V.HGSuiteName = V.HGSuiteName || "the Head Girl Suite";
	V.HGSuiteNameCaps = V.HGSuiteNameCaps || "The Head Girl Suite";
	V.pitName = V.pitName || "the Pit";
	V.pitNameCaps = V.pitNameCaps || "The Pit";
	V.incubatorName = V.incubatorName || "the Incubator";
	V.incubatorNameCaps = V.incubatorNameCaps || "The Incubator";
	V.farmyardName = V.farmyardName || "the Farmyard";
	V.farmyardNameCaps = V.farmyardNameCaps || "The Farmyard";
};


code:
:: EconomyJS [script]

window.LivingRule = Object.freeze({LUXURIOUS: 'luxurious', NORMAL: 'normal', SPARE: 'spare'});
window.Job = Object.freeze({
	DAIRY: 'work in the dairy', MILKMAID: 'be the Milkmaid', MASTER_SUITE: 'serve in the master suite', CONCUBINE: 'be your Concubine',
	BABY_FACTORY: 'labor in the production line', BROTHEL: 'work in the brothel', MADAM: 'be the Madam', ARCADE: 'be confined in the arcade',
	SERVANT: 'work as a servant', SERVER: 'be a servant', STEWARD: 'be the Stewardess', CLUB: 'serve in the club', DJ: 'be the DJ',
	JAIL: 'be confined in the cellblock', WARDEN: 'be the Wardeness', CLINIC: 'get treatment in the clinic', NURSE: 'be the Nurse',
	HGTOY: 'live with your Head Girl', SCHOOL: 'learn in the schoolroom', TEACHER: 'be the Schoolteacher', SPA: 'rest in the spa', ATTEND: 'be the Attendant',
	NANNY: 'work as a nanny', MATRON: 'be the Matron', FARMYARD: 'work as a farmhand', FARMER: 'be the Farmer', REST: 'rest'});
window.PersonalAttention = Object.freeze({TRADE: 'trading', WAR: 'warfare', SLAVING: 'slaving', ENGINEERING: 'engineering', MEDICINE: 'medicine', MAID: 'upkeep', HACKING: 'hacking'});

window.getCost = function(array) {
	var rulesCost = State.variables.rulesCost;
	var foodCost = State.variables.foodCost;
	var drugsCost = State.variables.drugsCost;
	var facilityCost = State.variables.facilityCost;
	var localEcon = State.variables.localEcon;
	var brothel = State.variables.brothel;
	var arcade = State.variables.arcade;
	var club = State.variables.club;
	var dairy = State.variables.dairy;
	var farmyard = State.variables.farmyard;
	var servantsQuarters = State.variables.servantsQuarters;
	var nursery = State.variables.nursery;
	var incubator = State.variables.incubator;
	var mercCosts = State.variables.mercenaries * 2000;
	var policyCost = State.variables.policyCost;
	var costs = (brothel * facilityCost)
		+ (arcade * facilityCost * 0.5)
		+ (club * facilityCost)
		+ (dairy * facilityCost)
		+ (nursery * facilityCost)
		+ (farmyard * facilityCost)
		+ (State.variables.incubator * facilityCost * 10);
	var secExpCost = 0;
	var soldierMod = 0;

	//facility expenses
	costs += (0.1 * State.variables.brothelUpgradeDrugs * brothel * facilityCost)
	+ (0.2 * State.variables.arcadeUpgradeInjectors * arcade * facilityCost)
	+ (0.2 * State.variables.arcadeUpgradeCollectors * arcade * facilityCost)
	+ (0.2 * State.variables.clubUpgradePDAs * club * facilityCost)
	+ (0.2 * State.variables.dairyFeedersUpgrade * dairy * facilityCost)
	+ (0.1 * State.variables.dairyPregUpgrade * dairy * facilityCost)
	+ (0.2 * State.variables.dairyStimulatorsUpgrade * facilityCost)
	+ (0.2 * State.variables.servantsQuartersUpgradeMonitoring * servantsQuarters * facilityCost)
	+ (0.2 * State.variables.incubatorUpgradeWeight * incubator * facilityCost)
	+ (0.2 * State.variables.incubatorUpgradeMuscles * incubator * facilityCost)
	+ (0.2 * State.variables.incubatorUpgradeReproduction * incubator * facilityCost)
	+ (0.2 * State.variables.incubatorUpgradeGrowthStims * incubator * facilityCost)
	+ (0.5 * State.variables.incubatorUpgradeSpeed * incubator * facilityCost);

	if(dairy > 0) {
		costs += ((State.variables.bioreactorsXY + State.variables.bioreactorsXX + State.variables.bioreactorsHerm + State.variables.bioreactorsBarren) * 100);
	}
	if(brothel > 0) {
		costs += State.variables.brothelAdsSpending;
	}
	if(club > 0) {
		costs += State.variables.clubAdsSpending;
	}
	if(incubator > 0) {
		costs += ((State.variables.incubatorWeightSetting + State.variables.incubatorMusclesSetting + State.variables.incubatorReproductionSetting + State.variables.incubatorGrowthStimsSetting) * 500);
	}
	if(State.variables.masterSuitePregnancySlaveLuxuries === 1) {
		costs += 500;
	}
	if(State.variables.masterSuitePregnancyFertilitySupplements === 1) {
		costs += 1000;
	}

	//security expansion
	if(State.variables.secExp == 1) {
		if(State.variables.edictsUpkeep > 0) {
			secExpCost += State.variables.edictsUpkeep;
		}
		if(State.variables.SFSupportUpkeep > 0) {
			secExpCost += State.variables.SFSupportUpkeep;
		}
		if(State.variables.propHub > 0) {
			secExpCost += State.variables.propHubUpkeep;
		}
		if(State.variables.secHQ > 0) {
			secExpCost += State.variables.secHQUpkeep + 20 * state.variables.secHelots;
		}
		if(State.variables.secBarracks > 0) {
			secExpCost += State.variables.secBarracksUpkeep;
		}
		if(State.variables.riotCenter > 0) {
			secExpCost += State.variables.riotUpkeep;
		}
		if(State.variables.soldierWages == 0) {
			soldierMod = 1;
		}
		else if(State.variables.soldierWages == 1) {
			soldierMod = 1.5;
		}
		else {
			soldierMod = 2;
		}
		if (State.variables.militiaUnits != null) {
			for (var i = 0; i < State.variables.militiaUnits.length; i++) {
				if( !(State.variables.militiaUnits[i] === null) ){
					secExpCost += State.variables.militiaUnits[i].troops * State.variables.soldierUpkeep * soldierMod;
				}
			}
		}
		if (State.variables.slaveUnits != null) {
			for (var i = 0; i < State.variables.slaveUnits.length; i++) {
				if( !( State.variables.slaveUnits[i] === null) ){
					secExpCost += State.variables.slaveUnits[i].troops * State.variables.soldierUpkeep * 0.5 * soldierMod;
				}
			}
		}
		if (State.variables.mercUnits != null) {
			for (var i = 0; i < State.variables.mercUnits.length; i++) {
				if( !(State.variables.mercUnits[i] === null) ){
					secExpCost += State.variables.mercUnits[i].troops * State.variables.soldierUpkeep * 1.5 * soldierMod;
				}
			}
		}
		costs += secExpCost;
	}

	//general arcology costs
	costs += (State.variables.girls * (250 + (50000 / localEcon)));

	if(State.variables.arcologies[0].FSRepopulationFocusLaw === 1 && State.variables.PC.pregKnown == 1) {
		costs -= 500;
	}

	costs += State.variables.citizenOrphanageTotal * 100;
	costs += State.variables.privateOrphanageTotal * 500;
	if(State.variables.breederOrphanageTotal > 0) {
		costs += 50;
	}

	if(State.variables.peacekeepers !== 0 && State.variables.peacekeepers.undermining !== 0) {
		costs += State.variables.peacekeepers.undermining;
	}

	if(State.variables.mercenaries > 0) {
		if(State.variables.barracks) {
			mercCosts *= 0.5;
		}
		if((State.variables.PC.warfare >= 100) || (State.variables.PC.career === 'arcology owner')) {
			mercCosts *= 0.5;
		}
		costs += mercCosts;
	}

	costs += State.variables.FSSpending;

	//slave expenses
	for (var slave of array) {
		costs += getSlaveCost(slave);
		if(slave.assignment === Job.SERVANT || slave.assignment === Job.SERVER) {
			if(slave.trust < -20) {
				costs -= rulesCost * 4;
			} else if(slave.devotion < -20) {
				if (slave.trust >= 20) {
					costs -= rulesCost / 2;
				} else {
					costs -= rulesCost * 2;
				}
			} else if(slave.devotion <= 20) {
				costs -= rulesCost * 3;
			} else if(slave.devotion <= 50) {
				costs -= rulesCost * 4;
			} else {
				costs -= rulesCost * 5;
			}
			if(slave.fetish === 'submissive') {
				costs -= rulesCost;
			} else if(slave.fetish === 'dom') {
				costs += rulesCost;
			}
			if(slave.relationship < -1) {
				costs -= rulesCost;
			}
			if(slave.energy < 20) {
				costs -= rulesCost;
			} else if(slave.energy < 40) {
				costs -= rulesCost / 2;
			}
			if(slave.lactation > 0) {
				costs -= 25;
			}
			if(slave.assignment === Job.SERVANT) {
				costs -= rulesCost;
			}
			if(setup.servantCareers.includes(slave.career) || slave.skillS >= State.variables.masteredXP) {
				costs -= rulesCost;
			}
		}
	}

	// policy and other expenses
	if(State.variables.Recruiter !== 0) {
		costs += 250;
	}
	if(State.variables.TSS.schoolPresent === 1) {
		costs += 1000;
	}
	if(State.variables.GRI.schoolPresent === 1) {
		costs += 1000;
	}
	if(State.variables.SCP.schoolPresent === 1) {
		costs += 1000;
	}
	if(State.variables.LDE.schoolPresent === 1) {
		costs += 1000;
	}
	if(State.variables.TGA.schoolPresent === 1) {
		costs += 1000;
	}
	if(State.variables.HA.schoolPresent === 1) {
		costs += 1000;
	}
	if(State.variables.TCR.schoolPresent === 1) {
		costs += 1000;
	}
	if((State.variables.TFS.schoolPresent === 1) && ((State.variables.PC.dick === 0) || (State.variables.PC.vagina === 0) || (State.variables.PC.boobs === 0))) {
		costs += 1000;
	}
	if(State.variables.TSS.subsidize !== 0) {
		costs += 1000;
	}
	if(State.variables.GRI.subsidize !== 0) {
		costs += 1000;
	}
	if(State.variables.SCP.subsidize !== 0) {
		costs += 1000;
	}
	if(State.variables.LDE.subsidize !== 0) {
		costs += 1000;
	}
	if(State.variables.TGA.subsidize !== 0) {
		costs += 1000;
	}
	if(State.variables.HA.subsidize !== 0) {
		costs += 1000;
	}
	if(State.variables.TCR.subsidize !== 0) {
		costs += 1000;
	}
	if(State.variables.TFS.subsidize !== 0) {
		costs += 1000;
	}

	if(State.variables.alwaysSubsidizeGrowth === 1) {
		costs += policyCost;
	}
	if(State.variables.alwaysSubsidizeRep === 1) {
		costs += policyCost;
	}
	if(State.variables.RegularParties === 1) {
		costs += policyCost;
	}

	if(State.variables.ProImmigrationCash === 1) {
		costs += policyCost;
	}
	if(State.variables.AntiEnslavementCash === 1) {
		costs += policyCost;
	}

	if(State.variables.CoursingAssociation === 1) {
		costs += 1000;
	}

	if(State.variables.PC.actualAge >= State.variables.IsInPrimePC && State.variables.PC.actualAge < State.variables.IsPastPrimePC) {
	if(State.variables.personalAttention === PersonalAttention.TRADE) {
		costs += 10000*State.variables.AgeEffectOnTrainerPricingPC;
	} else if(State.variables.personalAttention === PersonalAttention.WAR) {
		costs += 10000*State.variables.AgeEffectOnTrainerPricingPC;
	} else if(State.variables.personalAttention === PersonalAttention.SLAVING) {
		costs += 10000*State.variables.AgeEffectOnTrainerPricingPC;
	} else if(State.variables.personalAttention === PersonalAttention.ENGINEERING) {
		costs += 10000*State.variables.AgeEffectOnTrainerPricingPC;
	} else if(State.variables.personalAttention === PersonalAttention.MEDICINE) {
		costs += 10000*State.variables.AgeEffectOnTrainerPricingPC;
	} else if(State.variables.personalAttention === PersonalAttention.HACKING) {
		costs += 10000*State.variables.AgeEffectOnTrainerPricingPC;
	}
	}

	if(State.variables.cyberMod !== 0 && State.variables.researchLab.built === 'true') {
		costs += ((100 * State.variables.researchLab.maxSpace) + (300 * State.variables.researchLab.hired) + (100 * State.variables.researchLab.hired));
	}

	//player expenses

	if(State.variables.PC.preg === -1) {
		costs += 25;
	} else if(State.variables.PC.fertDrugs === 1) {
		costs += 50;
	} else if(State.variables.PC.preg >= 16) {
		costs += 100;
	}
	if(State.variables.PC.staminaPills === 1) {
		costs += 50;
	}

	if(State.variables.PC.career === 'servant') {
		if(State.variables.personalAttention === PersonalAttention.MAID) {
			if(State.variables.PC.belly >= 5000) {
				costs *= 0.80;
			} else {
				costs *= 0.75;
			}
		} else {
			costs *= 0.9;
		}
	}

	if(State.variables.secExp == 1) {
		if(State.variables.terrain === 'oceanic' || State.variables.terrain === 'marine') {
			if(State.variables.docks > 0) {
				costs *= (1 - State.variables.docks * 0.05);
			}
		} else if(State.variables.railway > 0) {
			costs *= (1 - State.variables.railway * 0.05);
		}
	}

	if(State.variables.SF.Toggle && State.variables.SF.Active >= 1) {
		if(State.variables.SF.Subsidy) {
			costs += Math.ceil( (10000*(State.variables.SFUnit.Troops/10))+(1+(State.variables.arcologies[0].prosperity/100))+(1+(State.variables.SF.Units/100)) );
		}
		if(State.variables.SF.Bonus) {
			const T = State.temporary;
			Count();
			costs += Math.ceil(T.SFCashBonus);
		}
	}
	if(State.variables.econWeatherDamage && State.variables.disasterResponse > 0) {
		costs += Math.trunc(State.variables.disasterResponse * 200000 / State.variables.localEcon);
	}
	if(State.variables.antiWeatherFreeze > 0) {
		costs += Math.trunc(State.variables.antiWeatherFreeze * 200000 / State.variables.localEcon);
	}
	// clean up
	if(costs < 0) {
		costs = 0;
	} else {
		costs = Math.ceil(costs);
	}

	return costs;
}

window.getSlaveCost = function(s) {
	if(!s) { return 0; }
	// Data duplicated from Cost Report
	var cost = 0;
	var rulesCost = State.variables.rulesCost;
	var foodCost = State.variables.foodCost;
	var drugsCost = State.variables.drugsCost;

	// Living expenses
	switch(s.assignment) {
	case Job.ARCADE:
		cost += rulesCost * .75;
		break;
	case Job.DAIRY:
		if(State.variables.dairyRestraintsSetting >= 2) {
			cost += rulesCost * .75;
		} else if(s.livingRules == LivingRule.NORMAL) {
			cost += rulesCost * 1.5;
		} else if(State.variables.dairyDecoration === 'Degradationist') {
			cost += rulesCost * .90;
		} else {
			cost += rulesCost;
		}
		break;
	case Job.BROTHEL:
		if(s.livingRules == LivingRule.NORMAL) {
			cost += rulesCost * 1.5;
		} else {
			cost += rulesCost;
		}
		break;
	case Job.SCHOOL: case Job.CLUB:
		cost += rulesCost * 1.5;
		break;
	case Job.CLINIC:
		if(s.livingRules === LivingRule.LUXURIOUS) {
			cost += rulesCost * 2;
		} else if(s.livingRules == LivingRule.NORMAL) {
			cost += rulesCost * 1.5;
		} else {
			cost += rulesCost;
		}
		break;
	case Job.SPA: case Job.NANNY:
		if(s.livingRules === LivingRule.LUXURIOUS) {
			cost += rulesCost * 1.75;
		} else if(s.livingRules == LivingRule.NORMAL) {
			cost += rulesCost * 1.5;
		} else {
			cost += rulesCost;
		}
		break;
	case Job.SERVANT:
		if(s.livingRules == LivingRule.NORMAL) {
			cost += rulesCost * 1.5;
		} else {
			if(State.variables.servantsQuartersDecoration === 'Degradationist') {
				cost += rulesCost * .90;
			} else {
				cost += rulesCost;
			}
		}
		break;
	case Job.JAIL:
		if(s.livingRules == LivingRule.NORMAL) {
			cost += rulesCost * 1.25;
		} else {
			cost += rulesCost * .90;
		}
		break;
	case Job.MADAM: case Job.DJ: case Job.NURSE: case Job.WARDEN:
	case Job.ATTEND: case Job.STEWARD: case Job.MILKMAID: case Job.TEACHER:
	case Job.MATRON:
		cost += rulesCost * 2;
		break;
	default:
		if(s.livingRules === LivingRule.LUXURIOUS) {
			cost += rulesCost * (s.relationship >= 4 ? 3 : 4);
		} else if(s.livingRules == LivingRule.NORMAL) {
			cost += rulesCost * 2;
		} else {
			cost += rulesCost;
		}
		break;
	}

	// Food
	cost += foodCost * 4;
	switch(s.diet) {
		case 'fattening': case 'muscle building':
			cost += foodCost;
			break;
		case 'restricted': case 'slimming':
			cost -= foodCost;
			break;
	}
	if(s.weight > 130) {
		cost += foodCost * 2;
	} else if(s.weight > 50) {
		cost += foodCost;
	} else if(s.weight < -50) {
		cost -= foodCost;
	}
	if(s.drugs === 'appetite suppressors') {
		cost -= foodCost;
	}
	if(s.lactation > 0) {
		cost += foodCost * s.lactation * (1 + Math.trunc(s.boobs/10000));
	}
	if(s.preg > s.pregData.normalBirth/8) {
		if(s.assignment === Job.DAIRY && State.variables.dairyFeedersSetting > 0) {
			// Extra feeding costs to support pregnancy are covered by dairy feeders.
			// TODO: Include them here anyway?
		} else if((s.assignment === Job.MASTER_SUITE || s.assignment === Job.CONCUBINE)
			&& State.variables.masterSuiteUpgradePregnancy === 1) {
			// Extra feeding costs to support pregnancy are covered by master suite luxuries.
			// TODO: Include them here anyway?
		} else {
			cost += foodCost * s.pregType * (s.pregControl === 'speed up' ? 3 : 1);
			if (s.pregType >= 100) {
				cost += foodCost * 5 * s.pregType * (s.pregControl === 'speed up' ? 3 : 1);
			} else if (s.pregType >= 50) {
				cost += foodCost * 3 * s.pregType * (s.pregControl === 'speed up' ? 3 : 1);
			} else if (s.pregType >= 30) {
				cost += foodCost * 2 * s.pregType * (s.pregControl === 'speed up' ? 3 : 1);
			} else if (s.pregType >= 10) {
				cost += foodCost * s.pregType * (s.pregControl === 'speed up' ? 3 : 1);
			}
		}
	}
	if(s.diet === 'XX' || s.diet === 'XY' || s.diet === 'fertility') {
		cost += 25;
	} else if(s.diet === 'cleansing') {
		cost += 50;
	} else if(s.diet === 'XXY') {
		cost += 75;
	}

	// Accessibility costs
	if(State.variables.boobAccessibility !== 1 && s.boobs > 20000
		&& (s.assignment != Job.DAIRY || State.variables.dairyRestraintsSetting < 2) && (s.assignment != Job.ARCADE)) {
		cost += 50;
	}
	if(State.variables.pregAccessibility !== 1
		&& (s.belly >= 60000) && s.assignment != Job.BABY_FACTORY && (s.assignment != Job.DAIRY || State.variables.dairyRestraintsSetting < 2) && (s.assignment != Job.ARCADE)) {
		cost += 100;
	}
	if(State.variables.dickAccessibility != 1 && s.dick > 45 && (s.assignment != Job.DAIRY || State.variables.dairyRestraintsSetting < 2) && (s.assignment != Job.ARCADE)) {
		cost += 50;
	}
	if(State.variables.ballsAccessibility != 1 && s.balls > 90 && (s.assignment != Job.DAIRY || State.variables.dairyRestraintsSetting < 2) && (s.assignment != Job.ARCADE)) {
		cost += 50;
	}
	if(State.variables.buttAccessibility != 1 && s.butt > 15 && (s.assignment != Job.DAIRY || State.variables.dairyRestraintsSetting < 2) && (s.assignment != Job.ARCADE)) {
		cost += 50;
	}
	if(!canSee(s) && (s.assignment != Job.DAIRY || State.variables.dairyRestraintsSetting < 2) && (s.assignment != Job.ARCADE)) {
		cost += 50;
	} else if(s.eyes <= -1 && s.eyewear !== 'corrective glasses' && s.eyewear !== 'corrective contacts') {
		cost += 25;
	} else if(s.eyewear === 'blurring glasses' || s.eyewear === 'blurring contacts') {
		cost += 25;
	}
	if(!canHear(s) && (s.assignment != Job.DAIRY || State.variables.dairyRestraintsSetting < 2) && (s.assignment != Job.ARCADE)) {
		cost += 40;
	} else if(s.hears <= -1 && s.earwear !== 'hearing aids') {
		cost += 15;
	} else if(s.earwear === 'muffling ear plugs') {
		cost += 15;
	}
	if((s.assignment !== Job.DAIRY || State.variables.dairyRestraintsSetting < 2) && (s.assignment !== Job.ARCADE)) {
		if(s.amp !== 0) {
			if(s.amp === 1) {
				cost += rulesCost;
			} else {
				cost += rulesCost / 2;
			}
		} else if(!canWalk(s)) {
			cost += rulesCost;
		}
	}

	// Maintenance
	if(s.boobs > 10000 && s.boobsImplantType === 1) {
		cost += 50;
	}
	if(s.butt > 10 && s.buttImplantType === 1) {
		cost += 50;
	}
	if((s.assignment !== Job.DAIRY || State.variables.dairyRestraintsSetting < 2) && (s.assignment !== Job.ARCADE)) {
		if(s.preg > s.pregData.minLiveBirth && State.variables.universalRulesBirthing === 1) {
			cost += 50;
		}
	}

	// Retirement account
	if(State.variables.CitizenRetirement === 1) {
		cost += 250;
	}

	// Enemas
	if(s.inflation === 3) {
		switch(s.inflationType) {
		case 'water':
			cost += 100;
			break;
		case 'food':
			cost += (foodCost * 4);
			break;
		case 'curative': case 'aphrodisiac': case 'tightener':
			cost += (100 + (drugsCost * 2));
			break;
		}
	} else if(s.inflation === 2) {
		switch(s.inflationType) {
		case 'water':
			cost += 50;
			break;
		case 'food':
			cost += (foodCost * 2);
			break;
		case 'curative': case 'aphrodisiac': case 'tightener':
			cost += (50 + (drugsCost * 2));
			break;
		}
	} else if(s.inflation === 1) {
		switch(s.inflationType) {
		case 'water':
			cost += 25;
			break;
		case 'food':
			cost += (foodCost);
			break;
		case 'curative': case 'aphrodisiac': case 'tightener':
			cost += (25 + (drugsCost * 2));
			break;
		}
	}

	// Drugs
	switch(s.drugs) {
	case 'anti-aging cream':
		cost += drugsCost * 10;
		break;
	case 'female hormone injections': case 'male hormone injections': case 'intensive breast injections':
	case 'intensive butt injections': case 'intensive penis enhancement': case 'intensive testicle enhancement':
	case 'intensive lip injections': case 'hyper breast injections': case 'hyper butt injections':
	case 'hyper penis enhancement': case 'hyper testicle enhancement': case 'hyper lip injections':
	case 'growth stimulants':
		cost += drugsCost * 5;
		break;
	case 'sag-B-gone':
		cost += Math.trunc(drugsCost * .1);
		break;
	case 'no drugs': case 'none':
		break;
	default:
		cost += drugsCost * 2;
		break;
	}
	if(s.curatives > 0 && s.assignmentVisible === 1) {
		cost += drugsCost * s.curatives;
	}
	if(s.aphrodisiacs !== 0) {
		cost += Math.trunc(drugsCost * Math.abs(s.aphrodisiacs));
	}
	if(s.hormones !== 0) {
		cost += Math.trunc((drugsCost * Math.abs(s.hormones) * 0.5));
	}
	if(s.bodySwap > 0) {
		cost += Math.trunc((drugsCost * s.bodySwap * 10));
	}
	if(s.preg === -1 && isFertile(s)) {
		cost += Math.trunc((drugsCost * 0.5));
	}

	// Promotion costs
	if(State.variables.studio === 1) {
		if(s.pornFameSpending > 0) {
			cost += (s.pornFameSpending/State.variables.PCSlutContacts);
		}
	}

	if(isNaN(cost)) {
		throw new Error('Cost calculation for slave ' + s.slaveName + ' (' + s.ID + ') failed.');
	}
	return cost;
};

// Supply and Demand for slaves (linear, simple)
// PC buying slaves reduces supply, selling slaves reduces demand.

window.menialSlaveCost = function(q) {
	if(!q) {
		q = 0;
	}
	var demand = State.variables.menialDemandFactor;
	var supply = State.variables.menialSupplyFactor;
	var baseCost = 1000;
	var random = State.variables.slaveCostRandom;
	return (Math.trunc(baseCost + demand / 400 - supply / 400 + q / 400) + random);
};

window.getSlaveStatisticData = function(s, facility) {
	if(!s || !facility) {
		// Base data, even without facility
		return {
			ID: s.ID, slaveName: s.slaveName, customLabel: s.customLabel,
			income: 0, adsIncome: 0, rep: 0, cost: getSlaveCost(s),
			customers: 0 /* brothel, club, ... */
		};
	}

	if(!facility.income) {
		facility.income = new Map();
	}

	if(facility.income.has(s.ID)) {
		return facility.income.get(s.ID);
	} else {
		var data = {
			ID: s.ID, slaveName: s.slaveName, customLabel: s.customLabel,
			income: 0, adsIncome: 0, rep: 0, cost: getSlaveCost(s),
			customers: 0 /* brothel, club, ... */
		};
		facility.income.set(s.ID, data);
		return data;
	}
};

window.initFacilityStatistics = function(facility) {
	facility = facility || {};
	facility.adsIncome = 0;
	facility.maintenance = 0;
	facility.totalIncome = 0;
	facility.totalExpenses = 0;
	facility.profit = 0;
	facility.income = new Map();
	return facility;
};

Number.prototype.toFixedHTML = function() {
	return commaNum(Number.prototype.toFixed.apply(this, arguments)).replace(/\.0+$/, '<span style="opacity: 0.3">$&</span>');
};