App.EndWeek.slaveAssignmentReport = function() {
	const facilities = App.Entity.facilities;
	const arcology = V.arcologies[0];

	// V.nextLink = "Economics";
	// V.nextButton = "Continue";

	const initialEmployeesCount = App.Utils.countFacilityWorkers(); // will be used to show differences after all the assignment changes
	const initialPenthouseTotalEmployeesCount = _countPenthousePopulation();

	/* Spa room */
	if (facilities.spa.established) {
		V.spaSpots = (facilities.spa.capacity - App.Entity.facilities.spa.employeesIDs().size) * 20;
		if (S.Attendant) {
			V.spaSpots = Math.trunc(V.spaSpots * (1 + (S.Attendant.skill.attendant / 400))); // A skilled attendant improves available space by 25%
		}
	}

	/** silent pass for any reassignments before generating reports */
	for (let i = 0; i < V.slaves.length; ++i) {
		// temp
		V.slaves[i].health.illness = 0;
		V.slaves[i].health.tired = 0;
		if (V.slaves[i].choosesOwnAssignment === 1) {
			V.i = i;
			App.UI.DOM.renderPassage("SA chooses own job");
		}
	}

	const res = document.createDocumentFragment();

	App.EndWeek.computeSexualServicesModel(res);

	res.appendChild(document.createElement("br"));
	res.appendChild(document.createElement("br"));

	const skillsToTest = {
		whoring: "whore",
		entertainment: "entertain",
		vaginal: "vaginal",
		anal: "anal",
		oral: "oral"
	};

	for (const slave of V.slaves) {
		for (const sk in skillsToTest) {
			if (_.isNil(slave.skill[sk])) {
				_printSlaveError(`Reset bad ${skillsToTest[sk]} skill`, slave);
				slave.skill[sk] = 0;
			}
		}

		if ((V.seeDicks > 0) && canPenetrate(slave) && App.Utils.hasNonassignmentSex(slave)) {
			V.averageDick += slave.dick, V.slavesWithWorkingDicks++;
		}

		if ((slave.lactation === 1)) {
			slave.lactationDuration--;
		}

		_ensureEmployeeMeetsJobRequirements(slave); // this can fire special slaves

		switch (slave.assignment) {
			case Job.HEADGIRLSUITE:
				if (slave.devotion >= random(-30, 20)) {
					V.HGSlaveSuccess++, V.HGEnergy++;
				} else {
					V.HGSlaveSuccess--;
				}
				break;
			case Job.CONCUBINE:
				V.Concubine = slave, V.fuckSlaves++;
				break;
			case Job.MASTERSUITE:
			case Job.FUCKTOY:
				V.fuckSlaves++;
				break;
		}

		if (slave.bellyPain !== 0) {
			slave.bellyPain = 0;
		}

		/* preg speed and advance*/

		if (slave.preg > 0) {
			let pregSpeed = 1; // base speed is normal
			if (slave.pregControl === "slow gestation") {
				pregSpeed = 0.5;
			} else if (slave.pregControl === "speed up") {
				pregSpeed = 2;
			}

			if (slave.broodmother === 1 && slave.broodmotherOnHold !== 1) { /* broodmother advance block */
				if ((V.week / slave.broodmotherFetuses === Math.round(V.week / slave.broodmotherFetuses)) && slave.broodmotherFetuses < 1) {
					// one fetus in few week - selection and adding
					WombImpregnate(slave, 1, slave.pregSource, 0);
				} else {
					// one or more fetuses in one week
					WombImpregnate(slave, Math.floor(slave.broodmotherFetuses), slave.pregSource, 0); /* really 0, it's will be advanced right few lines down.*/
				}
				if (slave.ovaryAge >= 47) {
					slave.broodmotherOnHold = 1;
					slave.broodmotherCountDown = 37 - WombMinPreg(slave);
				}
			}

			WombProgress(slave, pregSpeed, 1); /* drugs can affect speed of gestation, but not a real time */

			slave.pregKnown = 1;
			slave.pregWeek++;
		}
		if (slave.pregWeek < 0) { // postpartum state
			slave.pregWeek++;
		}

		SetBellySize(slave); /* here will be also set through WombGetVolume .bellyPreg, .pregType, to current values. */

		/* end of preg speed and advance*/

		/* set up sexual need */
		if (slave.devotion >= -50) {
			if (slave.energy > 20) {
				if (slave.physicalAge < slave.pubertyAgeXY && slave.genes === "XY" && slave.energy <= 80) {
					slave.need = slave.energy / 3;
				} else if (slave.physicalAge < slave.pubertyAgeXX && slave.genes === "XX" && slave.energy <= 80) {
					slave.need = slave.energy / 3;
				} else if (slave.physicalAge < 50) {
					slave.need = slave.energy;
				} else {
					slave.need = slave.energy / 5;
				}
				if (slave.balls > 0 && slave.pubertyXY === 1 && slave.physicalAge <= (slave.pubertyAgeXY + 1) && (slave.physicalAge > slave.pubertyAgeXY) && slave.physicalAge < 18) {
					slave.need = (slave.need * 1.25);
				}
				if ((slave.ovaries === 1 || slave.mpreg === 1) && slave.pubertyXX === 1 && slave.physicalAge <= (slave.pubertyAgeXX + 1) && (slave.physicalAge > slave.pubertyAgeXX) && slave.physicalAge < 18) {
					slave.need = (slave.need * 1.25);
				}
				if (slave.diet === "fertility") {
					slave.need += 10;
				}
				if (slave.aphrodisiacs === -1) {
					slave.need = (slave.need * 0.5);
				} else if (slave.aphrodisiacs === 1) {
					slave.need = (slave.need * 1.5);
				} else if (slave.aphrodisiacs === 2) {
					slave.need = (slave.need * 2);
				}
				poorHealthNeedReduction(slave);
				slave.need = Math.round(slave.need);
				slave.needCap = slave.need;
			}
		}

		if (slave.fetish === "mindbroken" && slave.relationship === -3) {
			if (slave.kindness > 0) {
				slave.kindness--;
			}
		}

		if (slave.assignment === Job.AGENT || slave.assignment === Job.AGENTPARTNER) {
			App.SlaveAssignment.agent(slave);
		}
	} // for (const slave of V.slaves)

	if (V.HeadGirl !== 0) {
		V.HGEnergy++;
		const slave = slaveStateById(V.HeadGirl.ID);
		if (V.personalAttention === PersonalAttention.SUPPORTHG) {
			V.HGEnergy++;
			if (slave.trust > 95) {
				V.HGEnergy++;
			}
		}
		if (arcology.FSChineseRevivalistLaw === 1) {
			V.HGEnergy++;
		}
		if (slave.health.tired > 90) {
			V.HGEnergy--;
		}
		if (canAchieveErection(slave)) {
			V.HGCum = 2 + Math.trunc((slave.balls / 5) + (slave.energy / 95) + (slave.health.condition / 95) + (slave.devotion / 95) + (V.reproductionFormula * 5));
		}
	}

	// Stud gets off based on impregnations, so we need to check and see if they actually do anyone
	if (V.StudID) {
		const stud = S.Stud;
		V.StudCum = 2 + Math.trunc(((stud.balls / 5) + (stud.energy / 95) + (stud.health.condition / 95) + (stud.devotion / 95) + (V.reproductionFormula * 5) - (stud.health.tired / 25)) * restEffects(stud, 5));
		if (stud.drugs === "hyper testicle enhancement") {
			V.StudCum += 3;
		} else if (stud.drugs === "testicle enhancement") {
			V.StudCum += 1;
		}
		if (stud.diet === "cum production") {
			V.StudCum += 1;
		}
		let studCumLimit = V.StudCum;
		for (const slave of V.slaves) {
			if (studCumLimit === 0 || stud.need <= 0) {
				break;
			}
			if (canGetPregnant(slave) && canBreed(stud, slave) && slave.ID !== V.StudID) {
				stud.need -= 20;
				if (stud.fetish === "pregnancy") {
					stud.need -= 30;
				}
			}
		}
	}

	if (V.averageDick > 0) {
		V.averageDick = V.averageDick / V.slavesWithWorkingDicks;
	}
	V.freeSexualEnergy = V.PC.sexualEnergy - V.fuckSlaves;
	const penthouseSlaves = App.Entity.facilities.penthouse.employees().length;
	if (V.freeSexualEnergy > 0) {
		if (V.freeSexualEnergy > penthouseSlaves / 2) {
			V.freeSexualEnergy = 3;
		} else if (V.freeSexualEnergy > penthouseSlaves / 4) {
			V.freeSexualEnergy = 2;
		} else {
			V.freeSexualEnergy = 1;
		}
	}

	if (S.HeadGirl) {
		const HGPossibleSlaves = [[], [], [], [], [], []];
		for (const slave of V.slaves) {
			if (!assignmentVisible(slave) || slave.fuckdoll === 1 || slave.ID === V.Bodyguard.ID || slave.ID === V.HeadGirl.ID || slave.fetish === "mindbroken") {
				continue;
			} else if (Array.isArray(V.personalAttention) && V.personalAttention.some(p => p.ID === slave.ID)) {
				continue;
			}

			if ((V.headGirlTrainsHealth && slave.health.condition < -20)) {
				HGPossibleSlaves[0].push({ID: slave.ID, training: "health"});
				continue;
			}

			if (slave.health.tired < 50) {
				const hasParaphilia = (["abusive", "anal addict", "attention whore", "breast growth", "breeder", "cum addict", "malicious", "neglectful", "self hating"].includes(slave.sexualFlaw));
				if ((V.headGirlTrainsParaphilias && hasParaphilia)) {
					HGPossibleSlaves[1].push({ID: slave.ID, training: "paraphilia"});
					continue;
				}

				if (V.headGirlTrainsFlaws || V.headGirlSoftensFlaws) {
					if (slave.behavioralFlaw !== "none" || (slave.sexualFlaw !== "none" && !hasParaphilia)) {
						if (V.headGirlSoftensFlaws) {
							if (slave.devotion > 20) {
								if ((slave.behavioralFlaw !== "none" && slave.behavioralQuirk === "none") || (slave.sexualFlaw !== "none" && slave.sexualQuirk === "none" && !hasParaphilia)) {
									HGPossibleSlaves[3].push({ID: slave.ID, training: "soften"});
								} else {
									HGPossibleSlaves[3].push({ID: slave.ID, training: "flaw"});
								}
								continue;
							}
						} else if (V.headGirlTrainsFlaws) {
							HGPossibleSlaves[2].push({ID: slave.ID, training: "flaw"});
							continue;
						}
					}
				}

				if ((V.headGirlTrainsObedience && slave.devotion <= 20 && slave.trust >= -20)) {
					HGPossibleSlaves[4].push({ID: slave.ID, training: "obedience"});
					continue;
				}

				if ((V.headGirlTrainsSkills)) {
					if ((slave.skill.oral < S.HeadGirl.skill.oral)) {
						HGPossibleSlaves[5].push({ID: slave.ID, training: "oral skill"});
					} else if ((slave.skill.vaginal < S.HeadGirl.skill.vaginal) && (slave.vagina > 0) && (canDoVaginal(slave))) {
						HGPossibleSlaves[5].push({ID: slave.ID, training: "fuck skill"});
					} else if ((slave.skill.anal < S.HeadGirl.skill.anal) && (slave.anus > 0) && (canDoAnal(slave))) {
						HGPossibleSlaves[5].push({ID: slave.ID, training: "anal skill"});
					} else if ((slave.skill.whoring < S.HeadGirl.skill.whoring)) {
						HGPossibleSlaves[5].push({ID: slave.ID, training: "whore skill"});
					} else if ((slave.skill.entertainment < S.HeadGirl.skill.entertainment) && !isAmputee(slave)) {
						HGPossibleSlaves[5].push({ID: slave.ID, training: "entertain skill"});
					}
				}
			}
		}
		V.HGTrainSlavesIDs = HGPossibleSlaves.flatten().slice(0, V.HGEnergy);
	} else {
		V.HGTrainSlavesIDs = [];
	}

	/**
	* Accordion
	* @version 0.7RC
	* @author 000-250-006
	*
	* @param array _facListArr V.args
	*	Multidimensional temporary array
	*	0: The passage name for the facility's report
	*	1: The facility name capitalized (@see todo)
	*	2: max number of slaves allowed in facility - > 0 implies open
	*	3: number of slaves assigned to facility
	*	4: ID of the slave assigned to run the facility ("Boss")
	*	5: Text title of the Boss
	*
	* @todo This is a proof of concept construct, if it works and cuts overhead, intended to create an object
	*	for deeper use in multiple locations, including streamlining reports/facilities code to one widget
	* @todo Figure out if this would be better as an object rather than an array for overhead
	*	StoryInit also?
	* @todo Figure out why we're not using ndef/-1 for a bunch of these story variables. Leaky conditionals
	* @todo Figure out why we're using variable space with capitalized facility names when we can parse it from true name
	*/

	const facListArr = [
		["Arcade Report", App.Entity.facilities.arcade],
		["Brothel Report", App.Entity.facilities.brothel],
		["Cellblock Report", App.Entity.facilities.cellblock],
		["Clinic Report", App.Entity.facilities.clinic],
		["Club Report", App.Entity.facilities.club],
		["Dairy Report", App.Entity.facilities.dairy],
		["Farmyard Report", App.Entity.facilities.farmyard],
		["Schoolroom Report", App.Entity.facilities.schoolroom],
		["Spa Report", App.Entity.facilities.spa],
		["Nursery Report", App.Entity.facilities.nursery],
		["Servants' Quarters Report", App.Entity.facilities.servantsQuarters],
		["Children Report", "Nursery Children", V.nursery, V.nurseryBabies],
		["Incubator Report", App.Entity.facilities.incubator],
		["Master Suite Report", App.Entity.facilities.masterSuite],
		["Penthouse Report", "The Penthouse"],
		["Rules Assistant Report", "Rules Assistant", V.rulesAssistantAuto], /** should be last — may reassign slaves **/
		["Lab Report", "Lab", V.researchLab.level]
	];

	function _getReportElementStats(ar) {
		if (typeof ar[1] == "string") {
			if (ar[1] === "The Penthouse") { // special case because we have to combine several facilities
				return {
					name: ar[1],
					established: 1,
					entriesNumberInitial: initialPenthouseTotalEmployeesCount,
					entriesNumber: _countPenthousePopulation(),
					manager: null
				};
			} else {
				return {
					name: ar[1],
					established: ar[2],
					entriesNumberInitial: null,
					entriesNumber: ar[3],
					manager: null
				};
			}
		} else {
			return {
				name: ar[1].nameCaps,
				established: ar[1].established,
				entriesNumberInitial: initialEmployeesCount[ar[1].desc.baseName],
				entriesNumber: ar[1].hostedSlaves,
				manager: ar[1].manager
			};
		}
	}

	const buttonClasses = V.useAccordion > 0 ? ["buttonBar", "accordion"] : ["buttonBar"]; // Is Accordion turned on?
	const disTxt = V.useAccordion > 0 ? "" : " disabled='disabled'"; // Chunk the row from our array we're working on to make reading code easier, null some text vars we'll need
	for (const facSubArr of facListArr) {
		const reportContent = document.createElement("div");
		App.UI.DOM.includePassage(reportContent, facSubArr[0]);
		if (V.useAccordion === 1) {
			reportContent.className = "accHidden";
		}

		const stats = _getReportElementStats(facSubArr); // needs to be inside the loop after the report passage to get the employees number after re-assignments

		const str = facSubArr[0].replace(/\W+/g, '-').toLowerCase(); // Normalize the passage name to use as an element ID
		if (stats.established) { /** Do we have one of these facilities? */
			if (stats.entriesNumber === 0 && !stats.manager) { // Is there anyone inside the facility?
				// No — it's empty, so we display the heading without a button and with a thinner bar under it
				App.UI.DOM.appendNewElement("strong", res, `${stats.name} Report`);
				App.UI.DOM.appendNewElement("hr", res).style.margin = "0";
				App.UI.DOM.appendNewElement("span", res, `${stats.name} is currently empty`, "gray");
				App.UI.DOM.appendNewElement("br", res);
				App.UI.DOM.appendNewElement("br", res);
				/** Old code: <<= '<div id="button-' + _str + '" class="unStaffed">' + _facSubArr[1] + ' is currently unstaffed</div>'>> */
			} else {
				const btn = App.UI.DOM.appendNewElement("button", res, `${stats.name}  Report`, buttonClasses);
				btn.type = "button" + disTxt;
				btn.id = `button-${str}`;
				if (_.isNil(stats.entriesNumber)) {
					// Yes, display the bar with information
					btn.setAttribute("data-after", '');
				} else {
					// Yes, display the bar with information
					const diffNum = stats.entriesNumber - stats.entriesNumberInitial;
					let diffText = diffNum === 0 ? "" : (diffNum > 0 ? ` (+${diffNum})` : ` (${diffNum})`);
					btn.setAttribute("data-after", `${stats.entriesNumber}${diffText} slave${stats.entriesNumber !== 1 ? 's' : ''} in ${stats.name}`);
				}
			}
			res.appendChild(reportContent);
		}
	}

	return res;

	function _countPenthousePopulation() {
		const fs = App.Entity.facilities;
		return fs.penthouse.employeesIDs().size + fs.headGirlSuite.totalEmployeesCount + fs.armory.totalEmployeesCount;
	}

	function _printSlaveError(warning, slave) {
		const warningLine = App.UI.DOM.appendNewElement("div", res);
		App.UI.DOM.appendNewElement("span", warningLine, warning + `for ${slave.slaveName}.`, "yellow");
		warningLine.appendChild(document.createTextNode(" Report this as a bug if it reoccurs."));
	}

	/**
	 * Check key employees. Fire those who do not satisfy their job requirements
	 * @param {App.Entity.SlaveState} slave
	 */
	function _ensureEmployeeMeetsJobRequirements(slave) {
		switch (slave.assignment) {
			case Job.HEADGIRL:
				V.HeadGirl = slave;
				if (V.HeadGirl.fetish === "mindbroken") {
					_printSlaveUnassignedNote(slave, "is mindbroken");
					V.HeadGirl = 0;
				} else if (!canTalk(V.HeadGirl)) {
					_printSlaveUnassignedNote(slave, "can't give slaves verbal orders");
					V.HeadGirl = 0;
				} else if (!canWalk(V.HeadGirl)) {
					_printSlaveUnassignedNote(slave, "is no longer independently mobile");
					V.HeadGirl = 0;
				} else if (!canHold(V.HeadGirl)) {
					_printSlaveUnassignedNote(slave, "is no longer able to handle your slaves");
					V.HeadGirl = 0;
				} else if (!canSee(V.HeadGirl)) {
					_printSlaveUnassignedNote(slave, "can no longer see");
					V.HeadGirl = 0;
				} else if (!canHear(V.HeadGirl)) {
					_printSlaveUnassignedNote(slave, "can no longer hear");
					V.HeadGirl = 0;
				} else if (V.HeadGirl.preg > 37 && V.HeadGirl.broodmother === 2) {
					_printSlaveUnassignedNote(slave, "spends so much time giving birth and laboring that", `${getPronouns(slave).he} cannot effectively serve as your Head Girl any longer`);
					V.HeadGirl = 0;
				} else if (V.HeadGirl.devotion <= 20) {
					_printSlaveUnassignedNote(slave, "is no longer even accepting of you");
					V.HeadGirl = 0;
				}
				if (V.HeadGirl === 0) {
					removeJob(slave, Job.HEADGIRL);
				}
				break;
			case Job.RECRUITER:
				V.Recruiter = slave;
				if (slave.fetish === "mindbroken") {
					_printSlaveUnassignedNote(slave, "is mindbroken");
					V.Recruiter = 0;
				} else if (!canTalk(slave)) {
					_printSlaveUnassignedNote(slave, "can't verbally entice marks");
					V.Recruiter = 0;
				} else if (slave.preg > 37 && slave.broodmother === 2) {
					_printSlaveUnassignedNote(slave, "spends so much time giving birth and laboring that", `${getPronouns(slave).he} cannot effectively serve as your recruiter any longer`);
					V.Recruiter = 0;
				} else if (!canWalk(slave)) {
					_printSlaveUnassignedNote(slave, "is no longer independently mobile");
					V.Recruiter = 0;
				} else if (!canSee(slave)) {
					_printSlaveUnassignedNote(slave, "can no longer see");
					V.Recruiter = 0;
				} else if (!canHear(V.Recruiter)) {
					_printSlaveUnassignedNote(slave, "an no longer hear");
					V.Recruiter = 0;
				}
				if (V.Recruiter === 0) {
					removeJob(slave, Job.RECRUITER);
				}
				break;
			case Job.MADAM:
				if (V.unMadam === 1) {
					_printSlaveUnassignedNote(slave, "can't give whores verbal orders");
				} else if (V.unMadam === 2) {
					_printSlaveUnassignedNote(slave, "spends so much time giving birth and laboring that", `${getPronouns(slave).he} cannot effectively serve as your Madam any longer`);
				} else if (V.unMadam === 3) {
					_printSlaveUnassignedNote(slave, "is mindbroken");
				} else if (V.unMadam === 4) {
					_printSlaveUnassignedNote(slave, "is no longer independently mobile");
				} else if (V.unMadam === 5) {
					_printSlaveUnassignedNote(slave, "can no longer see");
				} else if (V.unMadam === 6) {
					_printSlaveUnassignedNote(slave, "can no longer hear");
				} else if (V.unMadam === 7) {
					_printSlaveUnassignedNote(slave, `can no longer handle ${getPronouns(slave).his} underlings`);
				}
				if (V.Madam === 0) {
					removeJob(slave, Job.MADAM);
				}
				break;
			case Job.DJ:
				if (V.unDJ === 1) {
					_printSlaveUnassignedNote(slave, "can't speak");
				} else if (V.unDJ === 2) {
					_printSlaveUnassignedNote(slave, "spends so much time giving birth and laboring that", `${getPronouns(slave).he} cannot effectively serve as your DJ any longer`);
				} else if (V.unDJ === 3) {
					_printSlaveUnassignedNote(slave, "is mindbroken");
				} else if (V.unDJ === 4) {
					_printSlaveUnassignedNote(slave, "is no longer independently mobile");
				} else if (V.unDJ === 5) {
					_printSlaveUnassignedNote(slave, "can no longer hear");
				}
				if (V.DJ === 0) {
					removeJob(slave, Job.DJ);
				}
				break;
			case Job.MILKMAID:
				V.Milkmaid = slave;
				if (V.Milkmaid.fetish === "mindbroken") {
					_printSlaveUnassignedNote(slave, "is mindbroken");
					V.Milkmaid = 0;
				} else if (V.Milkmaid.preg > 37 && V.Milkmaid.broodmother === 2) {
					_printSlaveUnassignedNote(slave, "spends so much time giving birth and laboring that", `${getPronouns(slave).he} cannot effectively serve as your Milkmaid any longer`);
					V.Milkmaid = 0;
				} else if (!canWalk(V.Milkmaid)) {
					_printSlaveUnassignedNote(slave, "is no longer independently mobile");
					V.Milkmaid = 0;
				} else if (!canHold(V.Milkmaid)) {
					_printSlaveUnassignedNote(slave, "can no longer handle nor milk your slaves");
					V.Milkmaid = 0;
				} else if (!canSee(V.Milkmaid)) {
					_printSlaveUnassignedNote(slave, "can no longer see");
					V.Milkmaid = 0;
				} else if (!canHear(V.Milkmaid)) {
					_printSlaveUnassignedNote(slave, "can no longer hear");
					V.Milkmaid = 0;
				}
				if (V.Milkmaid === 0) {
					removeJob(slave, Job.MILKMAID);
				}
				break;
			case Job.FARMER:
				V.Farmer = slave;
				if (V.Farmer.fetish === "mindbroken") {
					_printSlaveUnassignedNote(slave, "is mindbroken");
					V.Farmer = 0;
				} else if (V.Farmer.preg > 37 && V.Farmer.broodmother === 2) {
					_printSlaveUnassignedNote(slave, "spends so much time giving birth and laboring that", `${getPronouns(slave).he} cannot effectively serve as your Farmer any longer`);
					V.Farmer = 0;
				} else if (!canWalk(V.Farmer)) {
					_printSlaveUnassignedNote(slave, "is no longer independently mobile");
					V.Farmer = 0;
				} else if (!canHold(V.Farmer)) {
					_printSlaveUnassignedNote(slave, "can no longer grip things");
					V.Farmer = 0;
				} else if (!canSee(V.Farmer)) {
					_printSlaveUnassignedNote(slave, "can no longer see");
					V.Farmer = 0;
				} else if (!canHear(V.Farmer)) {
					_printSlaveUnassignedNote(slave, "can no longer hear");
					V.Farmer = 0;
				}
				if (V.Farmer === 0) {
					removeJob(slave, Job.FARMER);
				}
				break;
			case Job.STEWARD:
				if (!canTalk(slave)) {
					_printSlaveUnassignedNote(slave, "can't give servants verbal orders");
					V.StewardessID = 0;
				} else if (slave.preg > 37 && slave.broodmother === 2) {
					_printSlaveUnassignedNote(slave, "spends so much time giving birth and laboring that", `${getPronouns(slave).he} cannot effectively serve as your Stewardess any longer`);
					V.StewardessID = 0;
				} else if (slave.fetish === "mindbroken") {
					_printSlaveUnassignedNote(slave, "is mindbroken");
					V.StewardessID = 0;
				} else if (!canWalk(slave)) {
					_printSlaveUnassignedNote(slave, "is no longer independently mobile");
					V.StewardessID = 0;
				} else if (!canHold(slave)) {
					_printSlaveUnassignedNote(slave, `can no longer handle ${getPronouns(slave).his} underlings nor effectively clean`);
					V.StewardessID = 0;
				} else if (!canSee(slave)) {
					_printSlaveUnassignedNote(slave, "can no longer see");
					V.StewardessID = 0;
				} else if (!canHear(slave)) {
					_printSlaveUnassignedNote(slave, "can no longer hear");
					V.StewardessID = 0;
				}
				if (V.StewardessID === 0) {
					removeJob(slave, Job.STEWARD);
				}
				break;
			case Job.TEACHER:
				V.Schoolteacher = slave;
				if (!canTalk(slave)) {
					_printSlaveUnassignedNote(slave, "can't give verbal instruction");
					V.Schoolteacher = 0;
				} else if (slave.preg > 37 && slave.broodmother === 2) {
					_printSlaveUnassignedNote(slave, "spends so much time giving birth and laboring that", `${getPronouns(slave).he} cannot effectively serve as your Schoolteacher any longer`);
					V.Schoolteacher = 0;
				} else if (slave.fetish === "mindbroken") {
					_printSlaveUnassignedNote(slave, "is mindbroken");
					V.Schoolteacher = 0;
				} else if (!canSee(slave)) {
					_printSlaveUnassignedNote(slave, "can no longer see");
					V.Schoolteacher = 0;
				} else if (!canHear(slave)) {
					_printSlaveUnassignedNote(slave, "can no longer hear");
					V.Schoolteacher = 0;
				}
				if (V.Schoolteacher === 0) {
					removeJob(slave, Job.TEACHER);
				}
				break;
			case Job.WARDEN:
				V.Wardeness = slave;
				if (!canWalk(slave)) {
					_printSlaveUnassignedNote(slave, "is no longer independently mobile");
					V.Wardeness = 0;
				} else if (!canHold(slave)) {
					_printSlaveUnassignedNote(slave, `can no longer handle ${getPronouns(slave).his} charges`);
					V.Wardeness = 0;
				} else if (slave.preg > 37 && slave.broodmother === 2) {
					_printSlaveUnassignedNote(slave, "spends so much time giving birth and laboring that", `${getPronouns(slave).he} cannot effectively serve as your Wardeness any longer`);
					V.Wardeness = 0;
				} else if (!canSee(slave)) {
					_printSlaveUnassignedNote(slave, "can no longer see");
					V.Wardeness = 0;
				} else if (!canHear(slave)) {
					_printSlaveUnassignedNote(slave, "can no longer hear");
					V.Wardeness = 0;
				}
				if (V.Wardeness === 0) {
					removeJob(slave, Job.WARDEN);
				}
				break;
			case Job.ATTENDANT:
				if (slave.fetish === "mindbroken") {
					_printSlaveUnassignedNote(slave, "is mindbroken");
					V.AttendantID = 0;
				} else if (slave.preg > 37 && slave.broodmother === 2) {
					_printSlaveUnassignedNote(slave, "spends so much time giving birth and laboring that", `${getPronouns(slave).he} cannot effectively serve as your Attendant any longer`);
					V.AttendantID = 0;
				} else if (!canWalk(slave)) {
					_printSlaveUnassignedNote(slave, "is no longer independently mobile");
					V.AttendantID = 0;
				} else if (!canHold(slave)) {
					_printSlaveUnassignedNote(slave, `can no longer support ${getPronouns(slave).his} charges`);
					V.AttendantID = 0;
				} else if (!canHear(slave)) {
					_printSlaveUnassignedNote(slave, "can no longer hear");
					V.AttendantID = 0;
				}
				if (V.AttendantID === 0) {
					removeJob(slave, Job.ATTENDANT);
				}
				break;
			case Job.MATRON:
				V.Matron = slave;
				if (slave.fetish === "mindbroken") {
					_printSlaveUnassignedNote(slave, "is mindbroken");
					V.Matron = 0;
				} else if (slave.preg > 37 && slave.broodmother === 2) {
					_printSlaveUnassignedNote(slave, "spends so much time giving birth and laboring that", `${getPronouns(slave).he} cannot effectively serve as your Matron any longer`);
					V.Matron = 0;
				} else if (!canWalk(slave)) {
					_printSlaveUnassignedNote(slave, "is no longer independently mobile");
					V.Matron = 0;
				} else if (!canHold(slave)) {
					_printSlaveUnassignedNote(slave, "can no longer hold infants");
					V.Matron = 0;
				} else if (!canHear(slave)) {
					_printSlaveUnassignedNote(slave, "can no longer hear");
					V.Matron = 0;
				} else if (!canSee(slave)) {
					_printSlaveUnassignedNote(slave, "can no longer see");
					V.Matron = 0;
				}
				if (V.Matron === 0) {
					removeJob(slave, Job.MATRON);
				}
				break;
			case Job.NURSE:
				V.Nurse = slave;
				if (slave.fetish === "mindbroken") {
					_printSlaveUnassignedNote(slave, "is mindbroken");
					V.Nurse = 0;
				} else if (slave.preg > 37 && slave.broodmother === 2) {
					_printSlaveUnassignedNote(slave, "spends so much time giving birth and laboring that", `${getPronouns(slave).he} cannot effectively serve as your Nurse any longer`);
					V.Nurse = 0;
				} else if (!canWalk(slave)) {
					_printSlaveUnassignedNote(slave, "is no longer independently mobile");
					V.Nurse = 0;
				} else if (!canHold(slave)) {
					_printSlaveUnassignedNote(slave, "can no longer hold onto patients");
					V.Nurse = 0;
				} else if (!canSee(slave)) {
					_printSlaveUnassignedNote(slave, "can no longer see");
					V.Nurse = 0;
				} else if (!canHear(slave)) {
					_printSlaveUnassignedNote(slave, "can no longer hear");
					V.Nurse = 0;
				}
				if (V.Nurse === 0) {
					removeJob(slave, Job.NURSE);
				}
				break;
			case Job.BODYGUARD:
				V.Bodyguard = slave;
				if (slave.fetish === "mindbroken") {
					_printSlaveUnassignedNote(slave, "is mindbroken");
					V.Bodyguard = 0;
				} else if (!canWalk(slave)) {
					_printSlaveUnassignedNote(slave, "is no longer independently mobile");
					V.Bodyguard = 0;
				} else if (!canHold(slave)) {
					_printSlaveUnassignedNote(slave, "is no longer able to hold a weapon");
					V.Bodyguard = 0;
				} else if (slave.preg > 37 && slave.broodmother === 2) {
					_printSlaveUnassignedNote(slave, "spends so much time giving birth and laboring that", `${getPronouns(slave).he} cannot effectively serve as your bodyguard any longer`);
					V.Bodyguard = 0;
				} else if (!canSee(slave)) {
					_printSlaveUnassignedNote(slave, "can no longer see");
					V.Bodyguard = 0;
				} else if (!canHear(slave)) {
					_printSlaveUnassignedNote(slave, "can no longer hear");
					V.Bodyguard = 0;
				}
				if (V.Bodyguard === 0) {
					removeJob(slave, Job.BODYGUARD);
				}
				break;
			case Job.SUBORDINATE:
				if (slave.subTarget === -1) {
					V.StudID = slave.ID;
					if (slave.balls === 0) {
						_printSlaveUnassignedNote(slave, "no longer has sperm", null, "@Stud");
						V.StudID = 0;
					} else if (slave.ballType === "sterile") {
						_printSlaveUnassignedNote(slave, "no longer produces potent sperm", null, "@Stud");
						V.StudID = 0;
					} else if (slave.pubertyXY !== 1) {
						_printSlaveUnassignedNote(slave, "no longer produces mature sperm", null, "@Stud");
						V.StudID = 0;
					} else if (slave.vasectomy === 1) {
						_printSlaveUnassignedNote(slave, "shoots blanks due to a vasectomy", null, "@Stud");
						V.StudID = 0;
					} else if (V.universalRulesImpregnation !== "Stud") {
						_printSlaveUnassignedNote(slave, "is", "no longer needed as a Stud", "@Stud");
					}
					if (V.StudID === 0) {
						slave.subTarget = 0;
					}
				}
		}

		if (slave.ID === V.LurcherID) {
			if (!canWalk(slave)) {
				_printSlaveUnassignedNote(slave, "is no longer able to run", null, Job.LURCHER);
				V.LurcherID = 0;
			} else if (!canHold(slave)) {
				_printSlaveUnassignedNote(slave, "is no longer able to catch the hares", null, Job.LURCHER);
				V.LurcherID = 0;
			} else if (!canHear(slave) && !canSee(slave)) {
				_printSlaveUnassignedNote(slave, "is no longer able to track the hares", null, Job.LURCHER);
				V.LurcherID = 0;
			} else if (slave.bellyPreg >= 60000) {
				_printSlaveUnassignedNote(slave, "is too pregnant to run", null, Job.LURCHER);
				V.LurcherID = 0;
			}
		}

		if (V.fighterIDs.includes(slave)) {
			if (!canWalk(slave)) {
				_printSlaveUnassignedNote(slave, "is no longer independently mobile",
					`and cannot fight any more. ${getPronouns(slave).he} has been removed from ${App.Entity.facilities.pit.name} roster`);
				V.fighterIDs.delete(slave.ID);
			} else if (!canHold(slave)) {
				_printSlaveUnassignedNote(slave, "is no longer able to strike",
					`and cannot fight any more. ${getPronouns(slave).he} has been removed from ${App.Entity.facilities.pit.name} roster`);
				V.fighterIDs.delete(slave.ID);
			}
		}
	}

	/**
	 *
	 * @param {App.Entity.SlaveState} slave
	 * @param {string} condition
	 * @param {string} [outcome]
	 * @param {string} [assignment]
	 */
	function _printSlaveUnassignedNote(slave, condition, outcome, assignment) {
		const cantServeNotes = new Map([
			[Job.HEADGIRL, "cannot serve as your Head Girl any more"],
			[Job.RECRUITER, "and cannot serve as your recruiter any more"],
			[Job.MADAM, "cannot serve as your Madam any more"],
			[Job.DJ, "cannot serve as your DJ any more"],
			[Job.MILKMAID, "cannot serve as your Milkmaid any more"],
			[Job.FARMER, "cannot serve as your Farmer any more"],
			[Job.STEWARD, "cannot serve as your Stewardess any more"],
			[Job.TEACHER, "cannot serve as your Schoolteacher any more"],
			[Job.WARDEN, "cannot serve as your Wardeness any more"],
			[Job.ATTENDANT, "cannot serve as your Attendant any more"],
			[Job.BODYGUARD, " cannot serve as your Bodyguard any more"],
			["@Stud", "cannot serve as a Stud any more"],
			[Job.NURSE, "cannot serve as your Nurse any more"],
			[Job.MATRON, "cannot serve as your Matron any more"],
			[Job.LURCHER, "cannot course as a lurcher"]
		]);

		const warningLine = App.UI.DOM.appendNewElement("div", res);
		App.UI.DOM.appendNewElement("span", warningLine, slave.slaveName, 'slave-name');
		warningLine.appendChild(document.createTextNode(' ' + condition + ' '));
		App.UI.DOM.appendNewElement("span", warningLine, outcome ? outcome : `and ${cantServeNotes[assignment || slave.assignment]}`, "yellow");
		warningLine.appendChild(document.createTextNode("."));
	}
};

src/endWeek/slaveAssignmentReport.js