code:
/**
 * @param {FC.GingeredSlave} slave
 * @param {FC.Desc.LongSlaveOptions} params
 * @returns {DocumentFragment}
 */
App.Desc.longSlave = function(slave, {descType, market = 0, marketText, noArt, links} = {}) {
	const {
		He, His, him, he, his
	} = getPronouns(slave);
	let el = new DocumentFragment();
	let span;
	let r = new SpacedTextAccumulator();
	SlaveStatClamp(slave);

	descType = descType || (market ? DescType.MARKET : DescType.NORMAL);

	if (!noArt) {
		if (!V.seeCustomImagesOnly || V.seeCustomImagesOnly && slave.custom.image && slave.custom.image.filename !== "") {
			App.Events.drawEventArt(el, slave);
		}
	}

	// Name
	r.push(App.UI.DOM.makeElement("span", `${SlaveFullName(slave)}`, ["slave", "name", "simple"]));

	// Label
	if (slave.custom.label) {
		r.push(App.UI.DOM.combineNodes("(",
			App.UI.DOM.makeElement('span', slave.custom.label, "custom-label"),
			")"));
	}

	if (market && market !== "starting") {
		if (applyLawCheck(market)) {
			r.push(`has passed inspection to be sold in your arcology.`);
		} else {
			r.push(`is for sale and is available to inspect.`);
		}
		if (marketText) {
			r.push(marketText);
		}
		r.push(reportGingering(slave));
		r.toParagraph();

		r.push(App.UI.DOM.makeElement("span", `${slave.slaveName}`, "name"));
	}

	r.push(`is`);
	// Devotion
	span = document.createElement('span');

	if (slave.devotion < -95) {
		r.push("a");
		span.className = "devotion hateful";
		span.textContent = "hate-filled,";
	} else if (slave.devotion < -50) {
		r.push("a");
		span.className = "devotion hateful";
		span.textContent = "hateful,";
	} else if (slave.devotion < -20) {
		r.push("a");
		span.className = "devotion resistant";
		span.textContent = "reluctant,";
	} else if (slave.devotion <= 20) {
		r.push("a");
		span.className = "devotion ambivalent";
		span.textContent = "hesitant,";
	} else if (slave.devotion <= 50) {
		r.push("an");
		span.className = "devotion accept";
		span.textContent = "accepting,";
	} else if (slave.devotion <= 95) {
		r.push("a");
		span.className = "devotion devoted";
		span.textContent = "devoted,";
	} else {
		r.push("a");
		span.className = "devotion worship";
		span.textContent = "worshipful,";
	}
	r.push(span);

	// Trust
	span = document.createElement('span');
	if (slave.trust < -95) {
		span.className = "trust terrified";
		span.textContent = "abjectly terrified";
	} else if (slave.trust < -50) {
		span.className = "trust terrified";
		span.textContent = "terrified";
	} else if (slave.trust < -20) {
		span.className = "trust frightened";
		span.textContent = "frightened";
	} else if (slave.trust < 20) {
		span.className = "trust fearful";
		span.textContent = "fearful";
	} else if (slave.trust <= 50) {
		if (slave.devotion < -20) {
			span.className = "defiant careful";
			span.textContent = "careful";
		} else {
			span.className = "trust careful";
			span.textContent = "careful";
		}
	} else if (slave.trust < 95) {
		if (slave.devotion < -20) {
			span.className = "defiant bold";
			span.textContent = "bold";
		} else {
			span.className = "trust trusting";
			span.textContent = "trusting";
		}
	} else {
		if (slave.devotion < -20) {
			span.className = "defiant full";
			span.textContent = "defiant";
		} else {
			span.className = "trust prof-trusting";
			span.textContent = "profoundly trusting";
		}
	}
	r.push(span);

	// Slave's Title, ex:"pregnant big bottomed busty milky hourglass broodmother"
	r.push(App.UI.DOM.makeElement("span", `${SlaveTitle(slave)}.`, ["si-slave-title"]));

	// ID
	if (V.debugMode || V.cheatMode) {
		r.push(`${His} ID is ${slave.ID}.`);
	}
	// Slave array index
	if (V.debugMode) {
		if (descType !== DescType.MARKET) {
			r.push(`${His} index in the slave array is currently ${getSlaveIndex(slave.ID)}.`);
		}
	}

	// Indenture
	if (slave.indenture > -1) {
		r.push(`${His}`);
		if (slave.indentureRestrictions > 1) {
			r.push(`restrictive`);
		} else if (slave.indentureRestrictions > 0) {
			r.push(`protective`);
		} else {
			r.push(`unrestricted`);
		}
		r.push(`indenture`);
		if (slave.indenture > 1) {
			r.push(`has ${slave.indenture} weeks left to run.`);
		} else if (slave.indenture > 0) {
			r.push(`expires next week.`);
		} else {
			r.push(`expires this week.`);
		}
	}

	r.push(...App.Desc.sceneIntro(slave, descType, links));
	r.push(App.Desc.name(slave));
	r.push(App.Desc.ageAndHealth(slave));

	const clinicNameCaps = capFirstChar(V.clinicName);
	if (descType !== DescType.MARKET) {
		if (V.clinic !== 0 && V.clinicUpgradeScanner === 1) {
			if (slave.chem > 15) {
				r.push(`${clinicNameCaps}'s scanners score long term carcinogenic buildup in ${his} body at`,
					App.UI.DOM.makeElement("span", `${Math.ceil(slave.chem / 10)}.`, "cyan"));
			} else {
				r.push(`${clinicNameCaps}'s scanners confirm that ${he} has good prospects for long term health.`);
			}
		}

		r.push(App.Desc.geneticQuirkAssessment(slave));
	}

	r.push(App.Desc.mind(slave, descType));

	if (descType === DescType.NORMAL) {
		if (canSee(slave)) {
			if (slave.attrKnown === 1) {
				if ((slave.assignment !== Job.DAIRY) || (V.dairyRestraintsSetting > 1)) {
					if ((slave.attrXX > 85) && (V.PC.boobs >= 400)) {
						r.push(`${His} attraction to women is obvious: ${he} can't seem to stop staring at your breasts.`);
					} else if ((slave.attrXY > 85) && (V.PC.dick !== 0)) {
						r.push(`${His} attraction to men is obvious: ${he} can't seem to stop glancing down at your package.`);
					} else if ((slave.attrXY > 85) && V.PC.title === 1 && (V.PC.boobs < 300)) {
						r.push(`${His} attraction to men is obvious: ${he} can't seem to stop checking out your broad chest.`);
					}
				}
			}
		}
	}

	r.push(App.Desc.family(slave, links));

	r.push(...App.Desc.relationRival(slave, links));

	if (slave.bodySwap > 0) {
		if (slave.origBodyOwner !== "") {
			r.push(`${He} currently possesses ${slave.origBodyOwner}'s body.`);
		}
		if (slave.fetish !== Fetish.MINDBROKEN && slave.fuckdoll === 0 && slave.origBodyOwnerID > 0) {
			const owner = getSlave(slave.origBodyOwnerID);
			if (owner !== undefined) {
				r.push(`${He} is fully aware that`,
					links ? App.UI.DOM.referenceSlaveWithPreview(owner, SlaveFullName(owner)) : SlaveFullName(owner), `
					is in ${his} old body.`);
			}
		}
	}

	r.toParagraph();

	if (descType !== DescType.MARKET || market === "starting" || market === "special") {
		let origin = slave.origin;
		if (origin === "$auto") {
			origin = App.StartingGirls.playerOrigin(slave).preview;
		}
		if (origin !== "") {
			r.push(pronounsForSlaveProp(slave, origin));
		}
	}

	r.push(App.Desc.career(slave));

	r.push(App.Desc.prestige(slave));

	r.push(App.Desc.skills(slave));

	if (slave.custom.desc !== "" && slave.custom.desc) {
		r.push(pronounsForSlaveProp(slave, slave.custom.desc));
	}

	if (V.arcologies[0].FSGenderFundamentalistLawBeauty + V.arcologies[0].FSGenderRadicalistLawBeauty > 0) {
		if (genderLawPass(slave) === 1) {
			r.push(`${His} body is a perfect example of the fashionable feminine ideal.`);
		}
	} else if (V.arcologies[0].FSSlimnessEnthusiastLaw === 1) {
		if (slimLawPass(slave) === 1) {
			r.push(`${His} body is a perfect example of the fashionable ideal flat body.`);
		}
	} else if (V.arcologies[0].FSHedonisticDecadenceLaw2 === 1) {
		if (slave.boobs >= 2000 && slave.butt >= 5 && slave.weight > 95) {
			r.push(`${His} body is a perfect example of the fashionable plump body.`);
		}
	}

	if (V.arcologies[0].FSRestartSMR > 0 && V.arcologies[0].FSRestart > 80 && (slave.dick === 0) && (slave.balls === 0) && (slave.ovaries === 0) && (slave.mpreg === 0) && (slave.vagina < 0)) {
		r.push(`${His} body is a perfect example of a subhuman who has accepted ${his} place in society.`);
	}

	if (V.arcologies[0].FSIntellectualDependencyLawBeauty === 1) {
		r.push(`${He} currently is graded`);
		switch (Math.clamp(bimboScore(slave), 0, 6)) {
			case 6:
				r.push(`an S-class`);
				break;
			case 5:
				r.push(`an A-class`);
				break;
			case 4:
				r.push(`a B-class`);
				break;
			case 3:
				r.push(`a C-class`);
				break;
			case 2:
				r.push(`a D-class`);
				break;
			case 1:
				r.push(`an E-class`);
				break;
			default:
				r.push(`an F-class`);
		}
		r.push(`bimbo by societal trends.`);
	}

	/* Needs contemplation. Slightly redundant with descriptionsWidgets.
	if(slave.visualAge === V.idealAge) {
		if(slave.actualAge === V.idealAge) {
			r.push(`${He} is ${slave.actualAge},`);
		} else {
			r.push(`${He} appears to be ${slave.visualAge},`);
		}
		if(V.idealAge === 18) {
			r.push(`and many still find this age especially attractive due to old world tradition.`);
		} else {
			r.push(`and many in the arcology find this age especially attractive.`);
		}
	} else if (slave.visualAge !== slave.actualAge && slave.visualAge === V.idealAge - 1) {
		r.push(`${He} appears to be ${slave.visualAge}, which is nearly the ideal, but as ${he} is actually ${slave.actualAge}, this can sometimes be cause for confusion regarding the appropriate level of enthusiasm society should have for ${him}.`);
	} else if(slave.visualAge === V.idealAge - 1) {
		if(slave.actualAge === V.idealAge - 1) {
			r.push(`${He} is ${slave.actualAge},`);
		} else {
			r.push(`${He} appears to be ${slave.visualAge},`);
		}
		if(V.idealAge === 18) {
			r.push(`and many are already looking forward to ${his} birthday with great anticipation due to old world tradition.`);
		} else {
			r.push(`and many in the arcology are already looking forward to ${his} birthday with great anticipation.`);
		}
	} else if(slave.actualAge === V.idealAge && slave.visualAge !== V.idealAge) {
		r.push(`${He} is ${slave.actualAge}, a fact that many in the arcology find appealing`);
		if(V.idealAge === 18) {
			r.push(`because of old world tradition,`);
		}
		r.push(`but due to ${his} appearing to be ${slave.visualAge}, there is less enthusiasm for ${him} than there might otherwise be.`);
	}
	*/

	if (V.showScores !== 0) {
		r.push(`Currently, ${he} has an`);

		// Beauty
		r.push(App.UI.DOM.makeElement("span", `attractiveness score`, ["pink", "bold"]));
		r.push(App.UI.DOM.makeElement("span", `of`, ["pink"]));
		r.push(BeautyTooltip(slave), `and a`);

		// Fresult
		r.push(App.UI.DOM.makeElement("span", `sexual score`, ["lightcoral", "bold"]));
		r.push(App.UI.DOM.makeElement("span", `of`, ["lightcoral"]));
		r.push(App.UI.DOM.combineNodes(FResultTooltip(slave), App.UI.DOM.makeElement("span", `.`, ["lightcoral"])));

		if (slave.assignment === Job.BODYGUARD || V.cheatMode || V.debugMode) {
			r.push(`${His} deadliness is`, App.UI.DOM.combineNodes(DeadlinessTooltip(slave), "."));
		}
	}

	r.toParagraph();

	r.push(App.Desc.limbs(slave));

	if (V.showClothing === 1 && descType !== DescType.MARKET) {
		r.push(App.Desc.clothing(slave));
		r.push(App.Desc.armwear(slave));

		if (V.showBodyMods === 1) {
			r.push(App.Desc.clothingCorset(slave));
		}

		r.push(`${He}`);
	} else {
		r.push(`${slave.slaveName}`);
	}

	r.push(App.Desc.dimensions(slave));
	r.push(App.Desc.bodyguard(slave));

	if ((slave.counter.pitWins + slave.counter.pitLosses) > 0) {
		const wins = slave.counter.pitWins;
		const losses = slave.counter.pitLosses;

		r.push(`${He} has participated in ${numberWithPluralOne(wins + losses, "pit fight")},`);
		if (wins > 0) {
			if (losses > 0) {
				r.push(`with ${numberWithPluralOne(wins, "win")} and ${numberWithPluralOne(losses, "loss", "losses")}.`);
			} else {
				if (wins > 2) {
					r.push(`all of`);
				} else if (wins > 1) {
					r.push(`both of`);
				} // omit for wins === 1
				r.push(`which ${he} won.`);
			}
		} else {
			if (losses > 2) {
				r.push(`all of`);
			} else if (losses > 1) {
				r.push(`both of`);
			} // omit for losses === 1
			r.push(`which ${he} lost.`);
		}
	}

	if (slave.counter.pitKills > 0) {
		r.push(`${slave.counter.pitKills} slaves have died by ${his} hand in pit fights.`);
	}

	r.push(App.Desc.piercing(slave, "corset"));
	r.push(App.Desc.pregnancy(slave, descType));
	r.push(App.Desc.legs(slave));
	r.push(App.Desc.mods(slave, "thigh"));
	r.push(App.Desc.mods(slave, "calf"));
	r.push(App.Desc.mods(slave, "ankle"));
	r.push(App.Desc.mods(slave, "foot"));
	r.push(App.Desc.heels(slave, descType));
	r.push(App.Desc.skin(slave, descType));

	if (descType !== DescType.MARKET || market === "starting") {
		r.push(App.Desc.accent(slave));
	}

	let scarCounter = 0;
	const scars = App.Medicine.Modification.scarRecord(slave);
	for (let scarName in scars) {
		if (slave.ID === V.BodyguardID && scarCounter > 1) {
			r.push(`${His} scars make ${him} look even more menacing than ${he} actually is.`);
			break;
		} else if ((slave.ID === V.BodyguardID) && scars[scarName].menacing > 0) {
			r.push(`${His} menacing scar makes ${him} look terrifying.`);
			break;
		} else if ((slave.ID === V.WardenessID) && scarCounter > 1) {
			r.push(`${His} scars make ${him} look like ${he}'s in the right place.`);
			break;
		}
		scarCounter++;
	}

	if (slave.fuckdoll === 0) {
		if (slave.markings === "birthmark" && slave.prestige === 0 && slave.porn.prestige < 2) {
			r.push(`${He} has a large, liver-colored birthmark, detracting from ${his} beauty.`);
		}
		if (slave.skin === "sun tanned") {
			if ((slave.rules.release.slaves === 1) || App.Utils.hasFamilySex(slave)) {
				if (slave.fetishStrength > 60 && slave.fetishKnown === 1) {
					r.push(`${His} tan is slightly uneven, since ${he} enjoys`);
					if (slave.fetish === "buttslut") {
						r.push(`letting other tanned slaves share a tanning bed with ${him} so they can sodomize ${him} while ${he} tans.`);
					} else if (slave.fetish === "cumslut") {
						r.push(`letting other tanned slaves share a tanning bed with ${him} so they get oral from ${him} while ${he} tans.`);
					} else if (slave.fetish === "sadist") {
						r.push(`forcing inferior slaves into the tanning beds with ${him} so ${he} can sodomize them while ${he} tans.`);
					} else if (slave.fetish === "dom") {
						r.push(`bringing other slaves into the tanning beds with ${him} so ${he} can fuck them while ${he} tans.`);
					} else if ((slave.fetish === "masochist") || (slave.fetish === Fetish.SUBMISSIVE)) {
						r.push(`letting other slaves into the tanning beds with ${him} so they can fuck ${him} while ${he} tans.`);
					} else if (slave.fetish === "boobs") {
						r.push(`bringing other slaves into the tanning beds with ${him} so ${he} can tittyfuck them while ${he} tans.`);
					} else if ((slave.fetish === "pregnancy") && (jsRandom(0, 99) < V.seeDicks)) {
						r.push(`letting slaves with dicks into the tanning beds with ${him} so they can cum inside ${him} while ${he} tans.`);
					} else {
						r.push(`bringing other slaves into the tanning beds with ${him} to have sex while ${he} tans.`);
					}
				}
			}
		}

		// Describe any brands that are not directly addressed elsewhere in longSlave
		r.push(App.Desc.mods(slave, "extra"));
	}

	if (V.showClothing === 1 && descType !== DescType.MARKET) {
		r.push(App.Desc.ears(slave));
		r.push(App.Desc.upperFace(slave));
		r.push(App.Desc.hair(slave));
	} else {
		r.push(`${His} hair is`);
		if (slave.hColor !== slave.eyebrowHColor) {
			r.push(`${slave.hColor}, with ${slave.eyebrowHColor} eyebrows.`);
		} else {
			r.push(`${slave.hColor}.`);
		}
	}

	if (slave.fuckdoll === 0) {
		if (App.Data.misc.redheadColors.includes(slave.hColor)) {
			if (slave.hLength >= 10) {
				if (slave.markings === "freckles" || slave.markings === "heavily freckled") {
					if (App.Medicine.Modification.naturalSkins.includes(slave.skin) && skinToneLevel(slave.skin).isBetween(5, 10)) {
						r.push(`It goes perfectly with ${his} ${slave.skin} skin and freckles.`);
					}
				}
			}
		}

		const pubertyAge = Math.min(slave.pubertyAgeXX, slave.pubertyAgeXY);
		if (slave.race === "catgirl") {
			if (slave.underArmHStyle === "bushy") {
				r.push(`${His} underarm fur is especially bushy and untamed.`);
			} else if (slave.underArmHStyle === "waxed" || slave.underArmHStyle === "hairless" || slave.underArmHStyle === "shaved" || slave.underArmHStyle === "bald") {
				r.push(`${His} underarm fur is trim and smooth.`);
			} else {
				r.push(`${His} ${slave.skin} underarm fur is quite regular along ${his} fuzzy body.`);
			}
		} else if (slave.physicalAge < pubertyAge - 2) {
			r.push(`${He} is too sexually immature to have armpit hair.`);
		} else if (slave.underArmHStyle === "hairless") {
			r.push(`${His} armpits are perfectly smooth and naturally hairless.`);
		} else if (slave.underArmHStyle === "bald") {
			r.push(`${His} armpits no longer grow hair, leaving them smooth and hairless.`);
		} else if (slave.underArmHStyle === "waxed") {
			if (slave.assignment === Job.DAIRY && V.dairyRestraintsSetting > 1) {
				r.push(`${His} armpit hair has been removed to prevent chafing.`);
			} else {
				r.push(`${His} armpits are waxed and smooth.`);
			}
		} else if (slave.physicalAge < pubertyAge - 1) {
			r.push(`${He} has a few ${slave.underArmHColor} wisps of armpit hair.`);
		} else if (slave.physicalAge < pubertyAge) {
			r.push(`${He} is on the verge of puberty and has a small patch of ${slave.underArmHColor} armpit hair.`);
		} else if (slave.underArmHStyle === "shaved") {
			r.push(`${His} armpits appear hairless, but closer inspection reveals light, ${slave.underArmHColor} stubble.`);
		} else if (slave.underArmHStyle === "neat") {
			r.push(`${His} armpit hair is neatly trimmed`);
			if (!hasBothArms(slave)) {
				r.push(`since`);
				if (hasAnyArms(slave)) {
					r.push(`at least half`);
				} else {
					r.push(`it`);
				}
				r.push(`is always in full view.`);
			} else {
				r.push(`to not be visible unless ${he} lifts ${his} arms.`);
			}
		} else if (slave.underArmHStyle === "bushy") {
			r.push(`${His} ${slave.underArmHColor} armpit hair has been allowed to grow freely,`);
			if (!hasAnyArms(slave)) {
				r.push(`creating two bushy patches under where ${his} arms used to be.`);
			} else {
				r.push(`so it can be seen poking out from under ${his}`);
				if (hasBothArms(slave)) {
					r.push(`arms`);
				} else {
					r.push(`arm`);
				}
				r.push(`at all times.`);
			}
		}
	}

	if (slave.voice === 0) {
		r.push(`${He} is`, App.UI.DOM.makeElement('span', "completely silent,", "pink"));
		r.push(`which is understandable, since ${he}'s`, App.UI.DOM.makeElement("span", "mute.", "red"));
	} else if (slave.lips > 95) {
		r.push(`${He} is`, App.UI.DOM.makeElement('span', "effectively mute,", "pink"));
		r.push(`since ${his} lips are so large that ${he} can no longer speak intelligibly. ${He} can still`);
		if (slave.devotion > 50) {
			r.push(`moan`);
		} else if (slave.devotion > 20) {
			r.push(`whimper`);
		} else {
			r.push(`scream`);
		}
		r.push(`through them, though.`);
	}

	if (V.showBodyMods === 1) {
		if (slave.fuckdoll > 0) {
			if (slave.piercing.ear.weight + slave.piercing.eyebrow.weight + slave.piercing.nose.weight > 0) {
				r.push(`The piercings on ${his} head run through ${his} suit, helping secure the material to ${his} head.`);
			}
		} else {
			r.push(App.Desc.mods(slave, "ear"));
			r.push(App.Desc.mods(slave, "nose"));
			r.push(App.Desc.mods(slave, "eyebrow"));
			r.push(App.Desc.mods(slave, "cheek"));
			r.push(App.Desc.mods(slave, "neck"));
			if (slave.custom.tattoo !== "" && slave.custom.tattoo) {
				r.push(pronounsForSlaveProp(slave, slave.custom.tattoo));
			}
		}
	}

	r.push(App.Desc.horns(slave));
	r.push(App.Desc.face(slave));
	r.push(App.Desc.mouth(slave));

	if (V.showClothing === 1 && descType !== DescType.MARKET) {
		if (slave.fuckdoll === 0) {
			r.push(App.Desc.collar(slave));
			r.push(App.Desc.faceAccessory(slave));
			r.push(App.Desc.mouthAccessory(slave));
			if (slave.relationship > 4) {
				if (hasAnyArms(slave)) {
					r.push(`${He} has a simple gold band on the little finger of ${his}`);
					if (!hasLeftArm(slave)) {
						r.push(`right`);
					} else {
						r.push(`left`);
					}
					r.push(`hand.`);
				} else {
					r.push(`${He} has a simple gold band on a length of chain around ${his} neck.`);
				}
			} else if (slave.relationship === -3) {
				if (hasAnyArms(slave)) {
					r.push(`${He} has a simple steel band on the little finger of ${his}`);
					if (!hasLeftArm(slave)) {
						r.push(`right`);
					} else {
						r.push(`left`);
					}
					r.push(`hand.`);
				} else {
					r.push(`${He} has a simple steel band on a length of cord around ${his} neck.`);
				}
			}
		}
	}

	if (slave.fuckdoll === 0) {
		r.push(App.Desc.nails(slave));
	}
	r.push(App.Desc.mods(slave, "back"));
	r.push(App.Desc.mods(slave, "shoulder"));
	r.push(App.Desc.mods(slave, "upper arm"));
	r.push(App.Desc.mods(slave, "lower arm"));
	r.push(App.Desc.mods(slave, "hand"));
	r.push(App.Desc.mods(slave, "wrist"));

	if (slave.fuckdoll === 0) {
		if (slave.minorInjury !== 0) {
			if (slave.minorInjury !== "sore ass") {
				r.push(`${He} is sporting a`);
				span = document.createElement('span');
				span.className = "red";
				span.textContent = `${slave.minorInjury},`;
				r.push(span);
				r.push(`covered by makeup.`);
			}
		}
	}
	if (slave.health.illness > 0) {
		if (slave.fuckdoll === 0) {
			r.push(`${He}`);
		} else {
			r.push(`${His} suit reports that ${he}`);
		}
		span = document.createElement('span');
		if (slave.health.illness === 1) {
			if (slave.fuckdoll === 0) {
				r.push(`is`);
				span.className = "red";
				span.textContent = `feeling under the weather.`;
				r.push(span);
			} else {
				r.push(`has`);
				span.className = "red";
				span.textContent = `fallen ill.`;
				r.push(span);
			}
		} else if (slave.health.illness === 2) {
			r.push(`is`);
			span.className = "red";
			span.textContent = `somewhat ill.`;
			r.push(span);
		} else if (slave.health.illness === 3) {
			r.push(`is`);
			span.className = "red";
			span.textContent = `sick.`;
			r.push(span);
		} else if (slave.health.illness === 4) {
			r.push(`is`);
			span.className = "red";
			span.textContent = `very sick.`;
			r.push(span);
		} else if (slave.health.illness === 5) {
			r.push(`is`);
			span.className = "red";
			span.textContent = `terribly ill.`;
			r.push(span);
		}
	}

	r.toParagraph();
	// Calling all boob widgets
	r.push(App.Desc.boobs(slave, descType));
	r.push(App.Desc.boobsShape(slave));
	r.push(App.Desc.boobsExtra(slave, descType));
	r.push(App.Desc.mods(slave, "chest"));
	r.push(App.Desc.mods(slave, "breast"));
	r.push(App.Desc.shoulders(slave));
	if (slave.appendages !== "none" || slave.wingsShape !== "none") {
		r.push(App.Desc.upperBack(slave));
	}
	r.push(App.Desc.nipples(slave, descType));
	r.push(App.Desc.mods(slave, "nipple"));
	r.push(App.Desc.areola(slave, descType));
	r.push(App.Desc.mods(slave, "areolae"));
	r.push(App.Desc.belly(slave, descType));
	r.push(App.Desc.mods(slave, "belly"));
	r.push(App.Desc.butt(slave, descType));

	r.toParagraph();

	r.push(App.Desc.crotch(slave, descType));
	r.push(App.Desc.dick(slave, descType));
	r.push(App.Desc.vagina(slave));
	r.push(App.Desc.anus(slave, descType));

	r.toParagraph();

	if (slave.fuckdoll === 0) {
		r.push(App.Desc.drugs(slave));
		r.toParagraph();
	}

	el.append(r.container());

	// clear sale and law flags, if set

	return el;

	/** Reports detected gingering status for a slave
	 * @param {FC.GingeredSlave} slave
	 */
	function reportGingering(slave) {
		let t = "";
		if (slave.gingering) {
			if (slave.gingering.detection === "slaver") {
				switch (slave.gingering.type) {
					case "antidepressant":
						t += `${He} is acting dazed and unfocused. ${He}'s obviously been given antidepressants to make ${him} appear less fearful, and will be considerably less trusting than ${he} seems.`;
						break;
					case "depressant":
						t += `${He} is acting languid and drugged. ${He}'s obviously been given a depressant to make ${him} appear less hateful, and will be considerably less accepting of slavery than ${he} seems.`;
						break;
					case "stimulant":
						t += `${He} is acting twitchy and hyperactive. ${He}'s obviously been given a stimulant to make ${him} seem healthier and more energetic, and is a lot less healthy than ${he} looks.`;
						break;
					case "vasoconstrictor":
						t += `${His} lips have the slightest blue tinge, making it obvious ${he}'s been given a vasoconstrictor. ${His} cock is a lot less of a girldick than it looks right now.`;
						break;
					case "vasodilator":
						t += `${He} has an impressive erection, but it seems quite unconnected to the rest of ${him}, as if ${he} doesn't know what to do with it. ${He}'s obviously been given a vasodilator to make ${his} dick seem a little less pathetic.`;
						break;
					case "aphrodisiac":
						t += `${His} pupils are slightly dilated, ${his} breath comes in fast pants, and ${his} skin is flushed. ${He}'s obviously been given as big of a dose of aphrodisiacs as ${he} can handle without a heart attack.`;
						break;
					default:
						t += `${He} is acting oddly, presenting ${his} ass in an awkward way and acting uncomfortable. ${He}'s obviously had an irritant shoved up ${his} butt to make ${him} act like an anal whore.`;
				}
				t += ` It's a trick you're very familiar with, given your <span class="skill player">training as a slaver.</span>`;
			} else if (slave.gingering.detected) {
				switch (slave.gingering.type) {
					case "antidepressant":
						t += `${He} is acting dazed and unfocused, like ${he}'s been given antidepressants to make ${him} appear less fearful. ${He} may be considerably less trusting than ${he} seems. `;
						break;
					case "depressant":
						t += `${He} is acting languid and drugged, like ${he}'s been given a depressant to make ${him} appear less hateful. ${He} may be considerably less accepting of slavery than ${he} seems. `;
						break;
					case "stimulant":
						t += `${He} is acting twitchy and hyperactive, like ${he}'s been given a stimulant to make ${him} seem healthier and more energetic. ${He} may be considerably less vital than ${he} seems. `;
						break;
					case "vasoconstrictor":
						t += `${His} lips have the slightest blue tinge, suggesting that ${he} may have been given a vasoconstrictor. If ${he} has, ${his} cock may be considerably less feminine and demure than it now seems. `;
						break;
					case "vasodilator":
						t += `${He} has an impressive erection, but it seems quite unconnected to the rest of ${him}, as if ${he} doesn't know what to do with it. ${He} may have been given a vasodilator. If ${he} has, ${his} cock may be considerably less impressive than it now seems. `;
						break;
					case "aphrodisiac":
						t += `${His} pupils are slightly dilated, ${his} breath comes in fast pants, and ${his} skin is flushed. These are the characteristic symptoms of a dose of aphrodisiacs limited only by a desire to avoid giving ${him} a heart attack. `;
						break;
					default:
						t += `${He} is acting oddly, presenting ${his} ass in an awkward way and acting uncomfortable. ${He} may be considerably less interested in anal sex than ${he} seems. `;
				}
				if (slave.gingering.detection === "mercenary") {
					t += `The nervous seller confirms this in response to a direct inquiry. Your intimidating reputation from your <span class="skill player">extensive combat training</span> has its uses.`;
				} else if (slave.gingering.detection === "force") {
					t += `The nervous seller confirms this in response to a direct inquiry. Your reputation as a <span class="skill player"> ${PCTitle() ? "man" : "woman"} of blood</span> has its uses.`;
				}
			}
		}
		return t;
	}
};


code:
/**
 * @param {App.Entity.SlaveState} slave
 * @param {DescType} descType
 * @returns {string}
 */
App.Desc.mind = function(slave, descType) {
	const r = [];
	const {
		he, him, his, He, His, hers, himself
	} = getPronouns(slave);
	if (slave.fuckdoll === 0) {
		r.push(App.Desc.eyes(slave, descType));

		if (slave.fetish === Fetish.MINDBROKEN) {
			r.push(`<span class="coral">${His} mind is fundamentally broken;</span> everything ${he} experiences will quickly be forgotten.`);
		} else {
			r.push(behavioralFlaws());
			r.push(behavioralQuirks());
			r.push(sexualFlaws());
			r.push(sexualQuirk());
			r.push(fetish());
		}
		r.push(attraction());
	} else {
		r.push(`It's impossible to tell what intelligence or inclinations a Fuckdoll might have by looking at it, but the most recent records indicate that this one is`);
		if (slave.intelligence + slave.intelligenceImplant > 95) {
			r.push(`<span class="deepskyblue">brilliant</span>`);
		} else if (slave.intelligence + slave.intelligenceImplant > 50) {
			r.push(`<span class="deepskyblue">highly intelligent</span>`);
		} else if (slave.intelligence + slave.intelligenceImplant > 15) {
			r.push(`of <span class="deepskyblue">above average intelligence</span>`);
		} else if (slave.intelligence + slave.intelligenceImplant >= -15) {
			r.push(`of average intelligence`);
		} else if (slave.intelligence + slave.intelligenceImplant >= -50) {
			r.push(`of <span class="orangered">below average intelligence</span>`);
		} else if (slave.intelligence + slave.intelligenceImplant >= -95) {
			r.push(`<span class="orangered">very stupid</span>`);
		} else if (slave.intelligence + slave.intelligenceImplant >= -100) {
			r.push(`<span class="orangered">a moron</span>`);
		}
		if (slave.intelligence >= -15) {
			if (slave.intelligenceImplant < 15) {
				r.push(`but is uneducated.`);
			} else if (slave.intelligenceImplant >= 30) {
				r.push(`and is well educated.`);
			} else {
				r.push(`and is educated.`);
			}
		} else {
			if (slave.intelligenceImplant < 15) {
				r.push(`and is uneducated.`);
			} else if (slave.intelligenceImplant >= 30) {
				r.push(`but is well educated.`);
			} else {
				r.push(`but is educated.`);
			}
		}

		if (slave.behavioralFlaw !== "none" || slave.sexualFlaw !== "none" || slave.behavioralQuirk !== "none" || slave.sexualQuirk !== "none") {
			if (slave.behavioralFlaw !== "none" || slave.sexualFlaw !== "none") {
				r.push(`${His} remaining mental flaws are likewise impossible to discern, but if ${he} was allowed out of ${his} suit, this Fuckdoll would probably still`);
				if (slave.behavioralFlaw !== "none") {
					switch (slave.behavioralFlaw) {
						case "hates men":
							r.push(`<span class="red">hate men</span>`);
							break;
						case "hates women":
							r.push(`<span class="red">hate women</span>`);
							break;
						case "gluttonous":
							r.push(`be a <span class="red">stress eater</span>`);
							break;
						default:
							r.push(`be <span class="red">${slave.behavioralFlaw}</span>`);
					}
				}
				if (slave.sexualFlaw !== "none") {
					if (slave.behavioralFlaw !== "none") {
						r.push(`and would still`);
					}
					switch (slave.sexualFlaw) {
						case "hates oral":
							r.push(`<span class="red">hate oral.</span>`);
							break;
						case "hates anal":
							r.push(`<span class="red">hate anal.</span>`);
							break;
						case "hates penetration":
							r.push(`<span class="red">hate penetration.</span>`);
							break;
						case "cum addict":
							r.push(`a <span class="yellow">cum addict.</span>`);
							break;
						case "anal addict":
							r.push(`an <span class="yellow">anal addict.</span>`);
							break;
						case "attention whore":
							r.push(`an <span class="yellow">attention whore.</span>`);
							break;
						case "breast growth":
							r.push(`have a <span class="yellow">breast obsession.</span>`);
							break;
						case "breeder":
							r.push(`have a <span class="yellow">breeding obsession.</span>`);
							break;
						default:
							r.push(`be <span class="red">${slave.sexualFlaw}.</span>`);
					}
				} else {
					r.push(`to an unacceptable degree.`);
				}
			}
			if (slave.behavioralQuirk !== "none" || slave.sexualQuirk !== "none") {
				r.push(`${His} character seems to retain some distinctiveness; ${he} may still`);
				if (slave.behavioralQuirk !== "none") {
					r.push(`be`);
					switch (slave.behavioralQuirk) {
						case "fitness":
							r.push(`<span class="green">a fitness fanatic</span>`);
							break;
						case "adores women":
							r.push(`<span class="green">adore women</span>`);
							break;
						case "adores men":
							r.push(`<span class="green">adore men</span>`);
							break;
						case "advocate":
							r.push(`<span class="green">an advocate</span>`);
							break;
						default:
							r.push(`<span class="green">${slave.behavioralQuirk}</span>`);
					}
				}
				if (slave.sexualQuirk !== "none") {
					if (slave.behavioralQuirk !== "none") {
						r.push(`and still`);
					}
					r.push(`be`);
					switch (slave.sexualQuirk) {
						case "romantic":
						case "perverted":
						case "caring":
						case "unflinching":
							r.push(`<span class="green"> ${slave.sexualQuirk}.</span>`);
							break;
						default:
							r.push(`a <span class="green"> ${slave.sexualQuirk}.</span>`);
					}
				} else {
					r.push(`in there.`);
				}
			}
		}

		if (slave.fetishKnown === 1) {
			r.push(`${His} recent biomedical readings indicate that ${he} still prefers`);
			switch (slave.fetish) {
				case "submissive":
					r.push(`<span class="lightcoral">being forced to submit</span>`);
					break;
				case "cumslut":
					r.push(`<span class="lightcoral">being facefucked</span>`);
					break;
				case "humiliation":
					r.push(`<span class="lightcoral">being fucked in public</span>`);
					break;
				case "buttslut":
					r.push(`<span class="lightcoral">being sodomized</span>`);
					break;
				case "boobs":
					r.push(`<span class="lightcoral">having ${his} breasts handled</span>`);
					break;
				case "pregnancy":
					r.push(`<span class="lightcoral">being inseminated</span>`);
					break;
				case "dom":
				case "sadist":
					r.push(`<span class="lightcoral">being on top</span>`);
					break;
				case "masochist":
					r.push(`<span class="lightcoral">being hurt</span>`);
					break;
				default:
					r.push(`<span class="lightcoral">having vanilla sex</span>`);
			}
			r.push(`to any other kind of use.`);
		}

		if (slave.attrKnown === 1) {
			r.push(`${His} suit usually forces ${him} to become aroused for use, but when ${he}'s allowed to react naturally, ${he} has`);
			if (slave.energy > 95) {
				r.push(`a <span class="green">nymphomaniac</span> need`);
			} else if (slave.energy > 80) {
				r.push(`a <span class="green">pathological need</span>`);
			} else if (slave.energy > 60) {
				r.push(`a <span class="green">powerful need</span>`);
			} else if (slave.energy > 40) {
				r.push(`a <span class="yellow">healthy need</span>`);
			} else if (slave.energy > 20) {
				r.push(`a <span class="red">weak need</span>`);
			} else {
				r.push(`<span class="red">no need</span>`);
			}
			r.push(`for external sexual stimulation, acts`);
			if (slave.attrXX <= 15) {
				r.push(`<span class="red">revolted</span>`);
			} else if (slave.attrXX <= 35) {
				r.push(`<span class="red">unhappy</span>`);
			} else if (slave.attrXX <= 65) {
				r.push(`indifferent`);
			} else if (slave.attrXX <= 85) {
				r.push(`<span class="green">eager</span>`);
			} else {
				r.push(`<span class="green">very enthusiastic</span>`);
			}
			r.push(`when a pussy is pressed against ${his} face hole, and`);
			if (slave.attrXY <= 15) {
				r.push(`<span class="red">struggles</span>`);
			} else if (slave.attrXY <= 35) {
				r.push(`<span class="red">does not react positively</span>`);
			} else if (slave.attrXY <= 65) {
				r.push(`does not react significantly`);
			} else if (slave.attrXY <= 85) {
				r.push(`<span class="green">seems pleased</span>`);
			} else {
				r.push(`is <span class="green">very happy</span>`);
			}
			r.push(`when a dick is pushed inside`);
			if (canDoVaginal(slave) && slave.vagina > 0 && canDoAnal(slave) && slave.anus > 0) {
				r.push(`either of ${his} lower holes.`);
			} else if (canDoVaginal(slave) && slave.vagina > 0) {
				r.push(`${his} front hole.`);
			} else if (canDoAnal(slave) && slave.anus > 0) {
				r.push(`${his} rear hole.`);
			} else {
				r.push(`it.`);
			}
		}
	}

	function behavioralFlaws() {
		const r = [];
		if (slave.behavioralFlaw === "arrogant") {
			if (slave.devotion < -20 && slave.trust >= -20) {
				r.push(`${He} is <span class="red">arrogant</span> and clings to ${his} dignity.`);
			} else if (slave.devotion < -20) {
				r.push(`${He} is still <span class="red">arrogant</span> at heart, but does ${his} best to hide it out of fear.`);
			} else if (slave.devotion <= 20) {
				r.push(`${He} is <span class="red">arrogant</span> and seems to think slavery beneath ${him}.`);
			} else {
				r.push(`Despite being well broken, ${he} seems to retain hints of <span class="red">arrogance.</span>`);
			}
		} else if (slave.behavioralFlaw === "bitchy") {
			if (slave.devotion < -20 && slave.trust >= -20) {
				r.push(`${He} is <span class="red">bitchy</span> and insults you every chance ${he} gets.`);
			} else if (slave.devotion < -20) {
				r.push(`${He} is still <span class="red">bitchy</span> at times, but does ${his} best to keep quiet out of fear.`);
			} else if (slave.devotion <= 20) {
				r.push(`${He} is <span class="red">bitchy</span> and constantly tries to get a word in edgewise.`);
			} else {
				r.push(`Since ${he} is well broken, ${he} tries to confine ${his} <span class="red">bitchy</span> remarks to your other slaves.`);
			}
		} else if (slave.behavioralFlaw === "liberated") {
			if (slave.devotion < -20 && slave.trust >= -20) {
				r.push(`${He} strongly believes that <span class="red">slavery is wrong,</span> and resists it as best ${he} can.`);
			} else if (slave.devotion < -20) {
				r.push(`${He} strongly believes that <span class="red">slavery is wrong,</span> but usually keeps quiet out of fear.`);
			} else if (slave.devotion <= 20) {
				r.push(`${He} strongly believes that <span class="red">slavery is wrong,</span> and rarely misses a chance to complain about it.`);
			} else {
				r.push(`${He} strongly believes that <span class="red">slavery is wrong,</span> but has learned to keep it to ${himself}.`);
			}
		} else if (slave.behavioralFlaw === "devout") {
			r.push(`${He} is <span class="red">devoutly religious,</span>`);
			if (slave.devotion < -20 && slave.trust >= -20) {
				r.push(`and uses ${his} faith as a wellspring of resistance.`);
			} else if (slave.devotion < -20) {
				r.push(`and uses ${his} faith as a place of refuge.`);
			} else if (slave.devotion <= 20) {
				r.push(`and uses ${his} faith as a private place within ${himself}.`);
			} else {
				r.push(`but has learned to keep ${his} faith private.`);
			}
		} else if (slave.behavioralFlaw === "odd") {
			r.push(`${He} behaves <span class="red">oddly,</span> saying and doing random things.`);
		} else if (slave.behavioralFlaw === "hates men") {
			r.push(`${He} <span class="red">strongly dislikes</span> being around`);
			if (slave.attrXY >= 85 && slave.energy >= 40) {
				r.push(`men; since ${he} loves the dick, ${he}'s forced to put up with them.`);
			} else if (slave.attrXY >= 65 && slave.energy >= 40) {
				r.push(`men; since ${he} likes the dick, ${he} reluctantly puts up with them.`);
			} else {
				r.push(`men.`);
			}
		} else if (slave.behavioralFlaw === "hates women") {
			r.push(`${He} <span class="red">strongly dislikes</span> being around`);
			if (slave.attrXX >= 85 && slave.energy >= 40) {
				r.push(`women; since ${he} loves pussy, ${he}'s forced to put up with them.`);
			} else if ((slave.attrXX >= 65) && (slave.energy >= 40)) {
				r.push(`women; since ${he} likes pussy, ${he} reluctantly puts up with them.`);
			} else {
				r.push(`women.`);
			}
		} else if (slave.behavioralFlaw === "anorexic") {
			r.push(`${He} suffers from <span class="red">anorexia.</span>`);
		} else if (slave.behavioralFlaw === "gluttonous") {
			r.push(`${He} <span class="red">tends to overeat</span> whenever ${he} can, reacting to the rigors of sexual slavery with overeating.`);
		}
		return r.join(" ");
	}

	function behavioralQuirks() {
		const r = [];
		switch (slave.behavioralQuirk) {
			case "confident":
				r.push(`${He}'s <span class="green">confident,</span> and believes that ${he} has something of value to offer, even as a slave.`);
				break;
			case "cutting":
				r.push(`${He} often has a witty or <span class="green">cutting</span> remark ready, but knows when to keep them to ${himself}.`);
				break;
			case "funny":
				r.push(`${He}'s <span class="green">funny,</span> often providing a little comic relief.`);
				break;
			case "adores women":
				r.push(`${He} <span class="green">adores women,</span> and loves spending time with them.`);
				break;
			case "adores men":
				r.push(`${He} <span class="green">adores men,</span> and loves spending time with them.`);
				break;
			case "fitness":
				r.push(`${He}'s a <span class="green">fitness fanatic,</span> and almost gets off to a hard workout.`);
				break;
			case "insecure":
				r.push(`${He}'s <span class="green">insecure,</span> defining ${his} self worth by how much others want to fuck ${him}.`);
				break;
			case "sinful":
				if (!FutureSocieties.isActive('FSChattelReligionist')) {
					r.push(`${He}'s delightfully <span class="green">sinful,</span> taking real pleasure in breaking cultural mores.`);
				} else {
					r.push(`${He}'s a devout Chattel Religionist, and is aggressively sinful against old world faiths. ${He} is enthusiastic about slutty religious clothing, and excited by intentional sacrilege like openly using old world religious icons as sex toys or having orgies on altars.`);
				}
				break;
			case "advocate":
				r.push(`${He}'s an <span class="green">advocate</span> for slavery, and can articulate what it's done for ${him}.`);
		}
		return r.join(" ");
	}

	function sexualFlaws() {
		const r = [];
		switch (slave.sexualFlaw) {
			case "hates oral":
				r.push(`${He} <span class="red">hates</span> oral sex and tries to avoid it.`);
				break;
			case "hates anal":
				r.push(`${He} <span class="red">hates</span> anal sex and tries to avoid it.`);
				break;
			case "hates penetration":
				r.push(`${He} <span class="red">hates</span> penetration and tries to avoid it.`);
				break;
			case "repressed":
				r.push(`${He} is <span class="red">sexually repressed,</span> retaining a fundamental distaste for sex from ${his} upbringing.`);
				break;
			case "idealistic":
				r.push(`${He} is <span class="red">sexually idealistic,</span> retaining a belief that sex should be based on love and consent.`);
				break;
			case "shamefast":
				r.push(`${He} is <span class="red">shamefast,</span> suffering crippling anxiety when naked.`);
				break;
			case "apathetic":
				r.push(`${He} is <span class="red">sexually apathetic,</span> often slipping into inertness during sex.`);
				break;
			case "crude":
				r.push(`${He} is <span class="red">sexually crude,</span> and has little sense of what partners find disgusting during sex.`);
				break;
			case "judgemental":
				r.push(`${He} is <span class="red">sexually judgemental,</span> and often denigrates ${his} sexual partners' performance.`);
				break;
			case "cum addict":
				r.push(`${He}'s a <span class="yellow">cum addict:</span> ${he} has a deep psychological addiction to`);
				if (V.PC.balls > 0) {
					r.push(`semen`);
					if (V.PC.vagina !== -1) {
						r.push(`and`);
					}
				}
				if (V.PC.vagina !== -1) {
					r.push(`pussyjuice`);
				}
				r.push(`and becomes anxious if ${he} goes for a few hours without drinking any.`);
				break;
			case "anal addict":
				r.push(`${He}'s an <span class="yellow">anal addict:</span> ${he} has a deep psychological need to be fucked in the ass and becomes anxious if ${he} goes for a few hours without anal.`);
				break;
			case "attention whore":
				r.push(`${He}'s an <span class="yellow">attention whore:</span> shocking and titillating spectators is more important to ${him} than the actual pleasure of sex.`);
				break;
			case "breast growth":
				r.push(`${He} has a <span class="yellow">breast growth obsession:</span> ${he}'s nearly incapable of believing that ${his} breasts are big enough.`);
				break;
			case "abusive":
				r.push(`${He}'s sexually <span class="yellow">abusive:</span> ${he} prefers taking sexual pleasure by force to having it offered to ${him}.`);
				break;
			case "malicious":
				r.push(`${He}'s sexually <span class="yellow">malicious:</span> ${he} gets off on others' anguish.`);
				break;
			case "self hating":
				r.push(`${He}'s filled with <span class="yellow">self hatred,</span> and is disturbingly willing to comply with things that might hurt ${him}.`);
				break;
			case "neglectful":
				r.push(`${He}'s sexually <span class="yellow">self neglectful,</span> and often shows no interest in getting off ${himself}.`);
				break;
			case "breeder":
				r.push(`${He}'s <span class="yellow">obsessed with being bred</span> to the point of fetishizing pregnancy itself as much as any act that leads to it.`);
				break;
			case "animal lover":
				r.push(`${He}'s an exclusive <span class="yellow">zoophile:</span> ${he} prefers sex with animals to sex with other humans.`);
				break;
		}
		return r.join(" ");
	}

	function sexualQuirk() {
		const r = [];
		switch (slave.sexualQuirk) {
			case "gagfuck queen":
				r.push(`${He}'s a <span class="green">gagfuck queen:</span> ${he}'s able to safely take a rough facefuck.`);
				break;
			case "painal queen":
				r.push(`${He}'s a <span class="green">painal queen:</span> ${he} knows exactly how much ${he} can take without getting hurt.`);
				break;
			case "strugglefuck queen":
				r.push(`${He}'s a <span class="green">strugglefuck queen:</span> ${he} can gauge exactly how much resistance ${his} partners want.`);
				break;
			case "tease":
				r.push(`${He}'s a <span class="green">tease,</span> and often displays a little flash of ${himself} followed by a blush.`);
				break;
			case "romantic":
				r.push(`${He}'s a <span class="green">romantic,</span> and persists in innocent pleasure in the closeness of sex.`);
				break;
			case "perverted":
				r.push(`${He}'s <span class="green">perverted,</span> and enjoys breaking sexual boundaries.`);
				break;
			case "caring":
				r.push(`${He}'s <span class="green">caring,</span> and enjoys bringing partners pleasure more than getting off ${himself}.`);
				break;
			case "unflinching":
				r.push(`${He}'s <span class="green">unflinching,</span> willing to do anything, even by the standards of sex slaves.`);
				break;
			case "size queen":
				r.push(`${He}'s <span class="green">a size queen;</span> preferring big cock is almost ${his} trademark.`);
		}
		return r.join(" ");
	}

	function fetish() {
		const r = [];
		if (slave.fetishKnown === 1) {
			switch (slave.fetish) {
				case "submissive":
					if (slave.sexualFlaw === "apathetic") {
						r.push(`This sexual apathy plays into ${his} preference for <span class="lightcoral">submission.</span>`);
					} else if (slave.behavioralFlaw === "arrogant") {
						r.push(`${His} arrogance is really just a thin shell to protect ${his} true need to <span class="lightcoral">submit.</span>`);
					} else if (slave.fetishStrength > 95) {
						r.push(`${He}'s an extreme <span class="lightcoral">submissive,</span> and relishes the strictures of slavery.`);
					} else if (slave.fetishStrength > 60) {
						r.push(`${He}'s a confirmed <span class="lightcoral">submissive,</span> and enjoys the strictures of slavery.`);
					} else {
						r.push(`${He} has <span class="lightcoral">submissive</span> tendencies, and likes the strictures of slavery.`);
					}
					break;
				case "cumslut":
					if (slave.sexualFlaw === "hates oral") {
						r.push(`${He}'s torn between ${his} <span class="lightcoral">love of semen</span> and ${his} dislike of having cocks in ${his} mouth.`);
					} else if (slave.fetishStrength > 95) {
						r.push(`${He}'s a <span class="lightcoral">cumslut,</span> and loves giving blowjobs and receiving facials.`);
					} else if (slave.fetishStrength > 60) {
						r.push(`${He} <span class="lightcoral">prefers giving oral,</span> and enjoys sucking dick and receiving facials.`);
					} else {
						r.push(`${He} has an <span class="lightcoral">oral fixation,</span> and likes giving blowjobs and receiving facials.`);
					}
					break;
				case "humiliation":
					if (slave.behavioralFlaw === "bitchy") {
						r.push(`${His} bitchiness is really just an expression of ${his} deep need to be <span class="lightcoral">humiliated</span> ${himself}.`);
					} else if (slave.sexualFlaw === "shamefast") {
						r.push(`${His} shame is genuine, and it is with real self-loathing that ${he} <span class="lightcoral">gets off on humiliation.</span>`);
					} else if (slave.fetishStrength > 95) {
						r.push(`${He}'s a slut for <span class="lightcoral">humiliation,</span> and gets off on having others see ${his} enslavement.`);
					} else if (slave.fetishStrength > 60) {
						r.push(`${He} enjoys <span class="lightcoral">humiliating</span> sex.`);
					} else {
						r.push(`${He} likes <span class="lightcoral">embarrassing</span> sex.`);
					}
					break;
				case "buttslut":
					if (slave.sexualFlaw === "hates anal") {
						r.push(`${His} hatred is just pretense to cover ${his} shame about how much ${he} really loves getting <span class="lightcoral">fucked in the butt.</span>`);
					} else if (slave.fetishStrength > 95) {
						r.push(`${He}'s a <span class="lightcoral">buttslut,</span> happy to have anyone put anything up ${his} ass.`);
					} else if (slave.fetishStrength > 60) {
						r.push(`${He} <span class="lightcoral">prefers anal.</span>`);
					} else {
						r.push(`${He} has an <span class="lightcoral">anal fixation.</span>`);
					}
					break;
				case "boobs":
					if (slave.fetishStrength > 95) {
						r.push(`${He} <span class="lightcoral">prefers mammary intercourse</span> to any other kind of sex, and readily climaxes to nipple stimulation.`);
					} else if (slave.fetishStrength > 60) {
						r.push(`${He} enjoys <span class="lightcoral">breast play,</span> and is rapidly aroused by nipple stimulation.`);
					} else {
						r.push(`${He} <span class="lightcoral">really likes boobs,</span> ${hers} and others.`);
					}
					break;
				case "pregnancy":
					if (slave.fetishStrength > 95) {
						r.push(`${He} has a <span class="lightcoral">pregnancy fetish,</span> and finds anything related to reproduction sexy.`);
					} else if (slave.fetishStrength > 60) {
						if ((canDoVaginal(slave) && slave.vagina > 0) || (slave.mpreg && canGetPregnant(slave))) {
							r.push(`${He} has an <span class="lightcoral">impregnation fantasy,</span> and enjoys bareback sex.`);
						} else {
							r.push(`${He} has an <span class="lightcoral">impregnation fantasy,</span> and is titillated by the idea of growing heavy with child.`);
						}
					} else {
						r.push(`${He} has a recurring <span class="lightcoral">impregnation fantasy.</span>`);
					}
					break;
				case "dom":
					if (slave.sexualFlaw === "apathetic") {
						r.push(`${He} is at war with ${himself}, since ${his} habitual apathy during sex barely masks a desire to <span class="lightcoral">dominate.</span>`);
					} else if (slave.fetishStrength > 95) {
						r.push(`${He} is a <span class="lightcoral">complete dom;</span> with other slaves this is expressed as a strong preference to top, and with ${his} betters ${he}'s an almost competitive lover.`);
					} else if (slave.fetishStrength > 60) {
						r.push(`${He} likes to take an active, powerful role in sex; with other slaves this is expressed as <span class="lightcoral">dominance,</span> and with ${his} betters ${he}'s a very energetic lover.`);
					} else {
						r.push(`${He} prefers to take a <span class="lightcoral">dominant</span> sexual role.`);
					}
					break;
				case "sadist":
					if (slave.fetishStrength > 95) {
						r.push(`${He} is an <span class="lightcoral">aggressive sadist;</span> ${he}'s constantly plotting to control, abuse, and hurt other slaves.`);
					} else if (slave.fetishStrength > 60) {
						r.push(`${He} has <span class="lightcoral">sadistic tendencies;</span> ${he} enjoys watching other slaves in pain, but truly loves causing pain ${himself}.`);
					} else {
						r.push(`${He} gets off on <span class="lightcoral">the suffering of others;</span> ${he} enjoys watching other slaves in pain.`);
					}
					break;
				case "masochist":
					if (slave.fetishStrength > 95) {
						r.push(`${He} is a <span class="lightcoral">pain slut.</span>`);
					} else if (slave.fetishStrength > 60) {
						r.push(`${He} <span class="lightcoral">gets off on pain,</span> showing strong masochistic tendencies.`);
					} else {
						r.push(`${He} <span class="lightcoral">doesn't mind pain,</span> and shows some masochistic tendencies.`);
					}
					break;
				case Fetish.BESTIALITY:
					if (slave.fetishStrength > 95) {
						r.push(`${He} has a <span class="lightcoral">bestiality fetish,</span> and prefers animal cocks to human ones.`);
					} else if (slave.fetishStrength > 60) {
						r.push(`${He} <span class="lightcoral">is aroused by the mere thought of fucking an animal.</span>`);
					} else {
						r.push(`${He} has a <span class="lightcoral">bestiality fetish,</span> and enjoys fucking animals.`);
					}
					break;
				default:
					r.push(`${His} sexual tastes are <span class="pink">quite normal.</span>`);
					break;
			}
		} else {
			r.push(`${His} fetishes, if any, are not known to you.`);
		}
		return r.join(" ");
	}

	function attraction() {
		const r = [];
		if (slave.attrKnown === 1) {
			if (slave.energy > 95) {
				r.push(`${He}'s a <span class="green">nymphomaniac.</span>`);
			} else if (slave.energy > 80) {
				r.push(`${He}'s a <span class="green">sex addict.</span>`);
			} else if (slave.energy > 60) {
				r.push(`${He} has a <span class="green">powerful appetite for sex.</span>`);
			} else if (slave.energy > 40) {
				r.push(`${He} has a <span class="yellow">healthy sex drive.</span>`);
			} else if (slave.energy > 20) {
				r.push(`${He} has a <span class="red">weak sex drive.</span>`);
			} else {
				r.push(`${He}'s <span class="red">frigid,</span> with little interest in sex.`);
			}
			if (slave.attrXY <= 5) {
				if (slave.attrXX <= 5) {
					r.push(`${He} <span class="red">finds both men's and women's intimate areas quite repulsive,</span> an unfortunate state of affairs!`);
				} else {
					r.push(`${He} <span class="red">finds men sexually disgusting,</span>`);
					if (slave.attrXX <= 15) {
						r.push(`and <span class="red">has almost as much trouble with women.</span>`);
					} else if (slave.attrXX <= 35) {
						r.push(`and is <span class="red">unenthusiastic about women.</span>`);
					} else if (slave.attrXX <= 65) {
						r.push(`and ${he} is indifferent to women.`);
					} else if (slave.attrXX <= 85) {
						r.push(`but <span class="green">is attracted to women.</span>`);
					} else if (slave.attrXX <= 95) {
						r.push(`<span class="green">strongly preferring women.</span>`);
					} else {
						r.push(`but is <span class="green">passionate about women.</span>`);
					}
				}
			} else if (slave.attrXY <= 15) {
				r.push(`${He} <span class="red">considers men's bodies a turnoff,</span>`);
				if (slave.attrXX <= 5) {
					r.push(`and is <span class="red">actually disgusted by women's.</span>`);
				} else if (slave.attrXX <= 15) {
					r.push(`and <span class="red">feels the same about women's.</span>`);
				} else if (slave.attrXX <= 35) {
					r.push(`and is <span class="red">unenthusiastic about women.</span>`);
				} else if (slave.attrXX <= 65) {
					r.push(`and ${he} is indifferent to women.`);
				} else if (slave.attrXX <= 85) {
					r.push(`but <span class="green">is attracted to women.</span>`);
				} else if (slave.attrXX <= 95) {
					r.push(`<span class="green">strongly preferring women.</span>`);
				} else {
					r.push(`but is <span class="green">passionate about women.</span>`);
				}
			} else if (slave.attrXY <= 35) {
				r.push(`${He} <span class="red">finds most men unattractive,</span>`);
				if (slave.attrXX <= 5) {
					r.push(`and is <span class="red">disgusted by the idea of intimacy with a woman.</span>`);
				} else if (slave.attrXX <= 15) {
					r.push(`and is <span class="red">turned off by women.</span>`);
				} else if (slave.attrXX <= 35) {
					r.push(`and is <span class="red">unenthusiastic about women.</span>`);
				} else if (slave.attrXX <= 65) {
					r.push(`and ${he} is indifferent to women.`);
				} else if (slave.attrXX <= 85) {
					r.push(`but <span class="green">is attracted to women.</span>`);
				} else if (slave.attrXX <= 95) {
					r.push(`<span class="green">strongly preferring women.</span>`);
				} else {
					r.push(`but is <span class="green">passionate about women.</span>`);
				}
			} else if (slave.attrXY <= 65) {
				r.push(`${He}'s indifferent to sex with men,`);
				if (slave.attrXX <= 5) {
					r.push(`but is <span class="red">disgusted by the idea of intimacy with a woman.</span>`);
				} else if (slave.attrXX <= 15) {
					r.push(`but is <span class="red">turned off by women.</span>`);
				} else if (slave.attrXX <= 35) {
					r.push(`but is <span class="red">actually unenthusiastic about women.</span>`);
				} else if (slave.attrXX <= 65) {
					r.push(`and feels the same about women, too.`);
				} else if (slave.attrXX <= 85) {
					r.push(`but <span class="green">is attracted to women.</span>`);
				} else if (slave.attrXX <= 95) {
					r.push(`<span class="green">strongly preferring women.</span>`);
				} else {
					r.push(`but is <span class="green">passionate about women.</span>`);
				}
			} else if (slave.attrXY <= 85) {
				r.push(`${He} <span class="green">finds men attractive,</span>`);
				if (slave.attrXX <= 5) {
					r.push(`but is <span class="red">disgusted by the idea of intimacy with a woman.</span>`);
				} else if (slave.attrXX <= 15) {
					r.push(`but is <span class="red">turned off by women.</span>`);
				} else if (slave.attrXX <= 35) {
					r.push(`but is <span class="red">unenthusiastic about women.</span>`);
				} else if (slave.attrXX <= 65) {
					r.push(`but is indifferent to women.`);
				} else if (slave.attrXX <= 85) {
					r.push(`and <span class="green">likes women too.</span>`);
				} else if (slave.attrXX <= 95) {
					r.push(`but <span class="green">likes women even more.</span>`);
				} else {
					r.push(`but is really <span class="green">passionate about women.</span>`);
				}
			} else if (slave.attrXY <= 95) {
				r.push(`${He} <span class="green">is aroused by most men,</span>`);
				if (slave.attrXX <= 5) {
					r.push(`but is <span class="red">disgusted by the idea of intimacy with a woman.</span>`);
				} else if (slave.attrXX <= 15) {
					r.push(`but is <span class="red">turned off by women.</span>`);
				} else if (slave.attrXX <= 35) {
					r.push(`but is <span class="red">unenthusiastic about women.</span>`);
				} else if (slave.attrXX <= 65) {
					r.push(`but is indifferent to women.`);
				} else if (slave.attrXX <= 85) {
					r.push(`and <span class="green">likes women too.</span>`);
				} else if (slave.attrXX <= 95) {
					r.push(`and <span class="green">thinks most women are hot,</span> too.`);
				} else {
					r.push(`but is most <span class="green">passionate about women.</span>`);
				}
			} else {
				if (slave.attrXX > 95) {
					r.push(`${He}'s <span class="green">omnisexual,</span> and is passionately attracted to nearly everyone.`);
				} else {
					r.push(`${He}'s <span class="green">passionate about men,</span>`);
					if (slave.attrXX <= 5) {
						r.push(`but is <span class="red">disgusted by the idea of intimacy with a woman.</span>`);
					} else if (slave.attrXX <= 15) {
						r.push(`but is <span class="red">turned off by women.</span>`);
					} else if (slave.attrXX <= 35) {
						r.push(`but is <span class="red">unenthusiastic about women.</span>`);
					} else if (slave.attrXX <= 65) {
						r.push(`but is indifferent to women.`);
					} else if (slave.attrXX <= 85) {
						r.push(`but also <span class="green">likes women,</span> too.`);
					} else {
						r.push(`but also <span class="green">thinks most women are hot,</span> too.`);
					}
				}
			}
		} else {
			r.push(`You do not understand ${his} sexuality very well.`);
		}
		return r.join(" ");
	}

	return r.join(" ");
};

repo_name: Arkerthan/fc

license: mit


code:
/**
 * @param {App.Entity.SlaveState} slave
 * @returns {string}
 */
App.Desc.mouth = function(slave) {
	const r = [];
	const {
		he, him, his, He, His, woman, girl
	} = getPronouns(slave);

	r.push(`${He} has`);
	if (slave.lips <= 10) {
		r.push(`thin, unattractive lips.`);
	} else if (slave.lips <= 20) {
		r.push(`normal lips.`);
	} else if (slave.lips <= 40) {
		r.push(`full, attractive lips.`);
	} else if (slave.lips <= 70) {
		r.push(`plump, beestung lips.`);
	} else if (slave.lips <= 95) {
		r.push(`huge, obviously augmented lips.`);
	} else {
		r.push(`a facepussy: ${his} lips are so huge that they're always a bit parted in the middle, forming a moist, inviting`);
		if (V.PC.dick !== 0) {
			r.push(`hole for cock.`);
		} else {
			r.push(`hole.`);
		}
	}

	if (V.showImplantEffects === 1) {
		if (FutureSocieties.isActive('FSTransformationFetishist')) {
			if (slave.lipsImplant > 0) {
				r.push(`They are about ${Math.floor((slave.lipsImplant / slave.lips) * 100)}% implant.`);
			}
			if (V.arcologies[0].FSTransformationFetishist > 20) {
				if (slave.lips > 70) {
					if (slave.lipsImplant / slave.lips < .50) {
						r.push(`${His} lips are huge and <span class="red">disgustingly natural</span> for their size.`);
					} else {
						r.push(`${His} lips are huge and <span class="green">obviously implants,</span> as they should be.`);
					}
				}
			}
		}
	}

	if (slave.fuckdoll > 0) {
		r.push(`${His} mouth is held open by the suit's oral insert.`);
	} else if ((slave.assignment === Job.DAIRY) && (V.dairyRestraintsSetting > 1)) {
		if (V.dairyFeedersSetting > 1) {
			r.push(`${His} milking machine has a phallus a long way down ${his} throat to rehydrate ${him}.`);
		} else {
			r.push(`${He}'s got ${his} mouth wrapped around a phallus provided by ${his} milking machine, and is sucking it off for hydration.`);
		}
	} else {
		if (canTalk(slave)) {
			if (slave.lips > 70) {
				const {title} = getEnunciation(slave);
				const writtenTitle = getWrittenTitle(slave);
				r.push(`${He} can barely enunciate past ${his} dick-sucking lips;`);
				if (title === writtenTitle) {
					if (App.Data.misc.badNames.includes(capFirstChar(writtenTitle))) {
						r.push(`unfortunately`);
					} else {
						r.push(`fortunately`);
					}
					r.push(`'${title}' is easy to pronounce.`);
				} else {
					r.push(`'${writtenTitle}' comes out as '${lispReplace(writtenTitle)}.'`);
				}
			}
		}
		if (slave.teeth !== "normal") {
			if (slave.teeth === "crooked") {
				r.push(`${His} teeth are <span class="yellow">crooked,</span> detracting from ${his} beauty whenever ${he} opens ${his} mouth.`);
			} else if (slave.teeth === "straightening braces") {
				r.push(`${He} has braces,`);
				if (slave.visualAge > 35) {
					r.push(`an amusing sight on such a mature ${woman}.`);
				} else if ((slave.visualAge > 14) && (slave.visualAge < 18)) {
					r.push(`a cute look on such a young ${girl}.`);
				} else {
					r.push(`and occasionally looks preoccupied with discomfort as they straighten ${his} teeth.`);
				}
			} else if (slave.teeth === "cosmetic braces") {
				r.push(`${He}'s wearing braces despite ${his} straight teeth,`);
				if (slave.visualAge > 35) {
					r.push(`an amusing sight on such a mature ${woman}.`);
				} else if ((slave.visualAge > 14) && (slave.visualAge < 18)) {
					r.push(`a cute look on such a young ${girl}.`);
				} else {
					r.push(`just for appearances.`);
				}
			} else if (slave.teeth === "gapped") {
				r.push(`${He} has a prominent gap between ${his} front`);
				if (slave.faceShape === "cute") {
					r.push(`teeth that suits ${his} cute face surprisingly well.`);
				} else {
					r.push(`teeth.`);
				}
				if (canTalk(slave)) {
					r.push(`It also leaves ${him} with a slight lisp.`);
				}
			} else if (slave.teeth === "removable") {
				r.push(`${His} teeth have been removed and replaced with high-quality dentures. It's difficult to tell anything's unusual until you take them out for gummy oral sex.`);
			} else if (slave.teeth === "pointy") {
				r.push(`${His} teeth have been replaced with realistic implants that mimic the dentition of a carnivore. ${His} smiles are frightening, and ${he} can bare them to become truly terrifying.`);
			} else if (slave.teeth === "fangs") {
				if (slave.race === "catgirl") {
					r.push(`${His} upper canine teeth are sharp feline fangs that distinctly mark ${him} as a bioengineered cat${girl} every time ${he} opens ${his} mouth. ${His} smiles are frightening, and ${he} can bare them to become truly terrifying.`);
				} else {
					r.push(`${His} upper canine teeth have been replaced with realistic implants that mimic fangs. ${His} smiles are frightening, and ${he} can bare them to become truly terrifying.`);
				}
			} else if (slave.teeth === "fang") {
				r.push(`One of ${his} upper canine teeth has been replaced with realistic implant shaped like a fang.`);
				if (slave.faceShape === "cute") {
					r.push(`It gives ${his} cute face an added`);
					if (slave.lips <= 50) {
						r.push(`charm, especially when it rests over ${his} lower lip.`);
					} else {
						r.push(`charm.`);
					}
				} else {
					if (slave.lips <= 50) {
						r.push(`It stands out when it rests over ${his} lower lip.`);
					} else {
						r.push(`It doesn't fit well in ${his} mouth and frequently prods ${his} fat lower lip.`);
					}
				}
			} else if (slave.teeth === "baby") {
				r.push(`${He} still has ${his} baby teeth.`);
			} else if (slave.teeth === "mixed") {
				r.push(`${He} is in the process of replacing ${his} baby teeth.`);
			}
		}
		if (V.policies.gumjobFetishism === 1 && slave.teeth !== "removable") {
			r.push(`${His} teeth have not yet been removed, <span class="red">disappointing</span> those that find them unwilling to pop out.`);
		}
	}
	if (slave.tastes === -1) {
		r.push(`${He} has no sense of taste, but this isn't immediately obvious just by looking at ${his} tongue.`);
	}

	r.push(App.Desc.mods(slave, "lips"));
	r.push(App.Desc.mods(slave, "tongue"));

	if (slave.fuckdoll > 0) {
		if (V.PC.dick !== 0) {
			r.push(`Sticking a dick`);
		} else {
			r.push(`Sliding a dildo`);
		}
		r.push(`into ${his}`);
		if (slave.lips > 95) {
			r.push(`facepussy`);
		} else {
			r.push(`mouth insert`);
		}
		if (slave.fuckdoll <= 45) {
			r.push(`mostly results in gagging.`);
		} else {
			r.push(`offers its user a selection of delightful face hole massage options.`);
		}
	} else {
		r.push(`${He} is`);
		if (slave.skill.oral >= 100) {
			r.push(`an <span class="skill">oral sex master.</span>`);
		} else if (slave.skill.oral > 60) {
			r.push(`an <span class="skill">expert at oral.</span>`);
		} else if (slave.skill.oral > 30) {
			r.push(`<span class="skill">orally skilled.</span>`);
		} else if (slave.skill.oral > 10) {
			r.push(`<span class="skill">capable of basic oral sex.</span>`);
		} else {
			r.push(`unskilled at oral sex.`);
		}
	}
	return r.join(" ");
};


code:
/**
 * @param {App.Entity.SlaveState} slave
 * @returns {string}
 */
App.Desc.name = function(slave) {
	const r = [];
	const {
		he, him, his, He
	} = getPronouns(slave);
	if (slave.slaveName !== slave.birthName || slave.slaveSurname !== slave.birthSurname) {
		let nameLoss = 0;
		if (slave.fuckdoll === 0) {
			if (slave.slaveName !== slave.birthName && slave.slaveSurname !== slave.birthSurname && slave.slaveSurname !== 0) {
				r.push(`${SlaveFullName(slave)} is not ${his} original full name;`);
				if (slave.birthName === "" || slave.birthSurname === "") {
					r.push(`whatever it was, however, has been lost forever.`);
					nameLoss = 1;
				}
			} else if (slave.slaveName !== slave.birthName) {
				r.push(`${slave.slaveName} is not ${his} original given name;`);
				if (slave.birthName === "") {
					r.push(`whatever it was, however, has been lost forever.`);
					nameLoss = 1;
				}
			} else if (slave.slaveSurname !== slave.birthSurname) {
				if (slave.slaveSurname === 0 && slave.birthSurname === "") {
					r.push(`${He} once had a surname; whatever it was, however, has been lost forever.`);
					nameLoss = 1;
				} else if (slave.slaveSurname !== 0) {
					r.push(`${slave.slaveSurname} is not ${his} original surname;`);
					if (slave.birthSurname === "") {
						r.push(`whatever it was, however, has been lost forever.`);
						nameLoss = 1;
					}
				} else {
					nameLoss = 1;
				}
			}
			if (slave.birthName === "" && slave.birthSurname === "") {
				r.push(`${He} has little alternative but to use whatever name you give ${him}.`);
			} else {
				if (slave.slaveName === slave.birthName && slave.birthSurname === "") {
					// deadend
				} else if (slave.slaveSurname === slave.birthSurname && slave.birthName === "") {
					if (slave.career === "a Futanari Sister") {
						r.push(`${He} discarded ${his} birth name upon initiation into the Futanari Sisters, and neither ${he} nor they have ever revealed what it might have been.`);
					} else {
						r.push(`${He} uses ${his} slave name automatically, having no alternative.`);
					}
				} else {
					if (nameLoss === 1) {
						r.push(`${He}`);
					} else {
						r.push(`${he}`);
					}
					if (slave.devotion > 95) {
						r.push(`adores ${his} slave name and affects to have forgotten that ${he} was ever called`);
					} else if (slave.devotion > 50) {
						r.push(`uses ${his} slave name automatically and gives no sign that ${he} was ever called`);
					} else if (slave.devotion > 20) {
						r.push(`uses ${his} slave name despite once being known as`);
					} else if (slave.devotion >= -20) {
						r.push(`uses ${his} slave name hesitantly since ${he} was once called`);
					} else if (slave.devotion >= -50) {
						r.push(`uses ${his} slave name with resentment since ${he} prefers ${his} original name,`);
					} else {
						r.push(`uses ${his} slave name only when constantly punished, since ${he} feels ${his} real name is`);
					}
					if (slave.slaveName !== slave.birthName && slave.slaveSurname !== slave.birthSurname) {
						r.push(`${SlaveFullBirthName(slave)}.`);
					} else if (slave.slaveName !== slave.birthName && slave.birthName !== "") {
						if (slave.slaveName.endsWith(slave.birthName)) {
							r.push(`just plain`);
						}
						r.push(`${slave.birthName}.`);
					} else if (slave.slaveSurname !== slave.birthSurname) {
						r.push(`${slave.birthSurname}.`);
					}
				}
			}
			if (slave.slaveSurname === 0) {
				r.push(`${He} has no surname as a slave, which ${he}`);
				if (slave.devotion > 95) {
					r.push(`loves.`);
				} else if (slave.devotion > 50) {
					r.push(`likes.`);
				} else if (slave.birthSurname === "") {
					r.push(`is indifferent to.`);
				} else if (slave.devotion > 20) {
					r.push(`accepts.`);
				} else if (slave.devotion >= -20) {
					r.push(`tolerates.`);
				} else if (slave.devotion >= -50) {
					r.push(`resents.`);
				} else {
					r.push(`hates.`);
				}
			}
		} else {
			r.push(`${SlaveFullName(slave)} is not ${his} original name: ${he} was once called ${SlaveFullBirthName(slave)}.`);
		}
	}

	return r.join(" ");
};


code:
/**
 * @param {App.Entity.SlaveState} slave
 * @returns {string}
 */
App.Desc.prestige = function(slave) {
	const r = [];
	const {
		He, him, he, his
	} = getPronouns(slave);

	if (slave.prestige > 0) {
		if (slave.prestigeDesc) {
			r.push(pronounsForSlaveProp(slave, slave.prestigeDesc));
		}
		if (slave.prestige > 2) {
			r.push(`<span class="green">It is extremely prestigious to own ${him}.</span>`);
		} else if (slave.prestige > 1) {
			r.push(`<span class="green">It is quite prestigious to own ${him}.</span>`);
		} else {
			r.push(`<span class="green">It is fairly prestigious to own ${him}.</span>`);
		}
	}

	if (slave.porn.prestige > 0) {
		if (slave.porn.prestigeDesc) {
			r.push(pronounsForSlaveProp(slave, slave.porn.prestigeDesc));
		}
		if (slave.porn.prestige > 2) {
			r.push(`As such, ${he} tends to gain a following wherever ${he} goes.`);
		} else if (slave.porn.prestige > 1) {
			r.push(`As such, ${he} is recognized often.`);
		} else {
			r.push(`As such, ${he} is recognized occasionally.`);
		}
	}

	if (slave.prestige > 0 || slave.porn.prestige > 1) {
		if (slave.fuckdoll === 0 && slave.markings === "birthmark") {
			r.push(`${He} has a large, liver-colored birthmark, but since ${he}'s well known, this uniqueness adds to ${his} beauty rather than detracting from it.`);
		}
	}
	return r.join(" ");
};


code:
/**
 * @param {App.Entity.SlaveState} slave
 * @param {boolean} links
 * @returns {Array<string|HTMLElement|DocumentFragment>}
 */
App.Desc.relationRival = function(slave, links) {
	const r = [];
	const {
		his, He
	} = getPronouns(slave);

	r.push(...relative());
	r.push(...rival());

	return r;

	/**
	 * @returns {Array<string|HTMLElement>}
	 */
	function relative() {
		if (slave.relationship >= 3 && totalRelatives(slave) > 0) {
			const lover = getSlave(slave.relationshipTarget);
			if (lover) {
				const term = relativeTerm(slave, lover);
				if (term !== null) {
					const s = [];
					s.push(`${He} is in an`);
					const span = App.UI.DOM.makeElement("span", `incestuous relationship with ${his} ${term}, `, ["si-family"]);
					span.append(slaveReference(lover), ".");
					s.push(span);
					return s;
				}
			}
		} else if (slave.relationship <= -2) {
			const term = relativeTerm(slave, V.PC);
			if (term !== null) {
				return [`${He} is in an <span class="si-family">incestuous relationship with ${his} ${term}, you.</span>`];
			}
		}
		return [];
	}

	/**
	 * @returns {Array<string|HTMLElement|DocumentFragment>}
	 */
	function rival() {
		if (slave.rivalry !== 0) {
			const rival = getSlave(slave.rivalryTarget);
			if (rival) {
				if (slave.rivalry <= 1) {
					return [`${He} <span class="si-rival">dislikes</span>`, App.UI.DOM.combineNodes(slaveReference(rival), `.`)];
				} else if (slave.rivalry <= 2) {
					return [`${He} is`, App.UI.DOM.combineNodes(slaveReference(rival), `'s`), `<span class="si-rival">rival.</span>`];
				} else {
					return [`${He} <span class="si-rival">bitterly hates</span>`, App.UI.DOM.combineNodes(slaveReference(rival), `.`)];
				}
			}
		}
		return [];
	}

	/**
	 * @param {App.Entity.SlaveState} slave
	 * @returns {string|HTMLSpanElement}
	 */
	function slaveReference(slave) {
		if (links) {
			return App.UI.DOM.referenceSlaveWithPreview(slave, SlaveFullName(slave));
		} else {
			return SlaveFullName(slave);
		}
	}
};


code:
/**
 * @param {App.Entity.SlaveState} slave
 * @param {DescType} descType
 * @param {boolean} links
 * @returns {Array<string|HTMLElement>}
 */
App.Desc.sceneIntro = function(slave, descType, links) {
	/** @type {Array<string|HTMLElement>} */
	const r = [];
	const {
		he, him, his, He, His, himself, wife
	} = getPronouns(slave);
	const relTarget = slave.relationship > 0 ? getSlave(slave.relationshipTarget) : null;

	if (descType === DescType.EVENT) {
		r.push(`${He} is currently involved in an event, but is assigned to ${slave.assignment}.`);
		if (slave.assignment === Job.SUBORDINATE) {
			let lsd = getSlave(slave.subTarget);
			if (lsd) {
				r.push(`${He} has been ordered to serve`, App.UI.DOM.makeElement("span", slaveReference(lsd), ["slave", "name", "simple"]), `specifically.`);
			}
		}
	} else if (descType !== DescType.MARKET) {
		r.push(inspectionIntro());
		if (slave.sentence > 0) {
			r.push(sentence());
		}
		if (slave.fuckdoll === 0) {
			if (slave.voice !== 0) {
				r.push(voice());
			}
		}
		r.push(...relationship());
		if (slave.fuckdoll === 0) {
			r.push(sleepLoc());
		}
	}
	return r;

	function inspectionIntro() {
		const r = [];
		if (slave.fuckdoll > 0) {
			r.push(`You order another slave to bring ${him} before your desk so you can inspect ${him}.`);
		} else if ((slave.assignment === Job.DAIRY) && (V.dairyRestraintsSetting > 1)) {
			r.push(`You go down to ${V.dairyName} to inspect ${his} heaving body.`);
		} else if (slave.assignment === Job.AGENT) {
			const arc = V.arcologies.find(a => a.leaderID === slave.ID);
			r.push(`You place a call to ${arc ? arc.name : `${his} current location`}, and ${he} instantly appears on camera.`);
		} else {
			r.push(`${He} comes to you for an inspection`);
			switch (slave.assignment) {
				case Job.WHORE:
				case Job.BROTHEL:
					r.push(`between customers.`);
					break;
				case Job.PUBLIC:
					r.push(`from where ${he} was offering ${himself} publicly.`);
					break;
				case Job.CLUB:
					r.push(`from where ${he} was dancing in ${V.clubName}.`);
					break;
				case Job.GLORYHOLE:
					r.push(`straight from confinement in a glory hole.`);
					break;
				case Job.ARCADE:
					r.push(`straight from confinement in ${V.arcadeName}.`);
					break;
				case Job.MILKED:
				case Job.DAIRY:
					r.push(`between milkings.`);
					break;
				case Job.FARMYARD:
					r.push(`from where ${he} was taking care of crops and animals.`);
					break;
				case Job.REST:
					r.push(`from where ${he} was resting.`);
					break;
				case Job.NURSERY:
					r.push(`from where ${he} was`);
					if (V.nurseryChildren === 1) {
						r.push(`taking care of a child.`);
					} else if (V.nurseryChildren > 0) {
						r.push(`taking care of children.`);
					} else {
						r.push(`keeping ${V.nurseryName} clean.`);
					}
					break;
				case Job.FUCKTOY:
					r.push(`from where ${he} was offering ${himself} to you.`);
					break;
				case Job.MASTERSUITE:
					r.push(`from ${V.masterSuiteName}.`);
					break;
				case Job.SUBORDINATE:
					if (slave.subTarget === -1) {
						r.push(`from where ${he} was resting after ${his} latest baby-making session.`);
					} else {
						r.push(`straight from orally servicing another slave.`);
					}
					break;
				case Job.HOUSE:
				case Job.QUARTER:
					r.push(`straight from bathing another slave.`);
					break;
				case Job.TEACHER:
					r.push(`between slave training contracts.`);
					break;
				case Job.SCHOOL:
				case Job.CLASSES:
					r.push(`between classes.`);
					break;
				case Job.CONFINEMENT:
					r.push(`straight from ${his} confinement.`);
					break;
				case Job.CELLBLOCK:
					r.push(`straight from ${his} cell in ${V.cellblockName}.`);
					break;
				case Job.BODYGUARD:
					r.push(`armed and alert.`);
					break;
				case Job.RECRUITER:
					if (V.recruiterTarget !== "other arcologies") {
						r.push(`after ${he} finishes cybering with a prospective recruit.`);
					} else if (V.arcologies[0].influenceTarget === -1) {
						r.push(`right away, since you haven't decided on an arcology to target for cultural influence, leaving ${him} with nothing to do.`);
					} else {
						const arc = V.arcologies.find(a => a.direction === V.arcologies[0].influenceTarget);
						r.push(`from where ${he} was resting after ${his} latest sexually exhausting visit to ${arc ? arc.name : "a nearby arcology"}.`);
					}
					break;
				case Job.HEADGIRL:
					r.push(`with updates on your other slaves ready for your review.`);
					break;
				default:
					r.push(`as quickly as ${he} can. ${He} is assigned to ${slave.assignment}.`);
			}
		}
		return r.join(" ");
	}

	function sentence() {
		const r = [];

		if (slave.assignment === Job.GLORYHOLE) {
			r.push(`${His} sentence lasts another`);
			if (slave.sentence > 1) {
				r.push(`${slave.sentence} weeks.`);
			} else {
				r.push(`week.`);
			}
		} else {
			r.push(`${His} work assignment lasts another`);
			if (slave.sentence > 1) {
				r.push(`${slave.sentence} weeks.`);
			} else {
				r.push(`week.`);
			}
		}

		return r.join(" ");
	}

	function voice() {
		const r = [];

		if (slave.rules.speech === "restrictive") {
			r.push(`${He} is not allowed to speak unless spoken to, but when allowed, ${he} speaks in a`);
		} else {
			r.push(`${He} is allowed to ask questions, and when ${he} speaks, ${he} does so in a`);
		}
		if (slave.voice === 1) {
			if (slave.voiceImplant < 0) {
				r.push(`ridiculously deep, gravelly voice.`);
			} else {
				r.push(`deep, unfeminine voice.`);
			}
		} else if (slave.voice === 2) {
			if (slave.voiceImplant !== 0) {
				r.push(`slightly artificial feminine voice.`);
			} else {
				r.push(`pretty, feminine voice.`);
			}
		} else if (slave.voice === 3) {
			if (slave.voiceImplant > 0) {
				r.push(`ridiculously high, bubblegum voice.`);
			} else {
				r.push(`high, girly voice.`);
			}
		}

		if (canTalk(slave, false)) {
			r.push(App.Desc.accent(slave));
		}

		return r.join(" ");
	}

	function relationship() {
		/** @type {Array<string|HTMLElement>} */
		const r = [];

		if (slave.relationship === -3) {
			if (slave.fetish === Fetish.MINDBROKEN) {
				r.push(`${He} is <span class="relationship">married to you,</span> not that it matters to ${his} broken mind; to ${him}, ${he} is a slave, nothing more.`);
			} else if (slave.devotion + slave.trust >= 175) {
				r.push(`${He} is <span class="relationship">happily married to you,</span> though of course ${he} is still your slave; albeit a loving, devoted one.`);
			} else if (slave.devotion < -20 && slave.trust > 20) {
				r.push(`${He} is <span class="relationship">reluctantly married to you,</span> though of course ${he} is still your slave.`);
			} else if (slave.devotion < -20) {
				r.push(`${He} is <span class="relationship">forcibly married to you,</span> though of course ${he} is still your slave.`);
			} else {
				r.push(`${He} is <span class="relationship">married to you,</span> though of course ${he} is still your slave.`);
			}
		} else if (slave.relationship === -1) {
			r.push(`${He} is an <span class="relationship">emotional slut,</span> happy to remain officially single and free to treat everyone equally.`);
		} else if (slave.relationship === -2) {
			r.push(`${He} is <span class="relationship">emotionally bound to you;</span> ${his} feelings for you are comparable to those in a healthy, loving relationship.`);
		} else if (slave.relationship !== 0 && relTarget) {
			r.push(`${He} is`);
			// TODO: update this with the new relationship rules
			if (slave.relationship <= 1) {
				r.push(slaveRelationshipSpan(`friends with `, slaveReference(relTarget), `;`), `the rules`);
				if (slave.rules.relationship !== "restrictive") {
					r.push(`encourage`);
				} else {
					r.push(`discourage`);
				}
				r.push(`their relationship.`);
			} else if (slave.relationship <= 2) {
				r.push(slaveRelationshipSpan(`best friends with `, slaveReference(relTarget), `;`), `the rules`);
				if (slave.rules.relationship !== "restrictive") {
					r.push(`encourage`);
				} else {
					r.push(`discourage`);
				}
				r.push(`their close relationship.`);
			} else if (slave.relationship <= 3) {
				r.push(slaveRelationshipSpan(slaveReference(relTarget), `'s friend with benefits;`), `the rules`);
				if (slave.rules.relationship === "permissive") {
					r.push(`encourage`);
				} else {
					r.push(`discourage`);
				}
				r.push(`their sexual relationship.`);
			} else if (slave.relationship <= 4) {
				r.push(slaveRelationshipSpan(slaveReference(relTarget), `'s lover;`), `the rules`);
				if (slave.rules.relationship === "permissive") {
					r.push(`encourage`);
				} else {
					r.push(`discourage`);
				}
				r.push(`their passionate relationship.`);
			} else if (slave.relationship > 4) {
				r.push(slaveRelationshipSpan(slaveReference(relTarget), `'s slave ${wife};`), `the rules`);
				if (slave.rules.relationship === "permissive") {
					r.push(`encourage`);
				} else {
					r.push(`discourage`);
				}
				r.push(`marital bliss.`);
			}
		} else if (slave.fuckdoll === 0) {
			if (slave.rules.relationship === "restrictive") {
				r.push(`The rules forbid ${him} from associating freely with other slaves.`);
			} else if (slave.career === "a Futanari Sister") {
				r.push(`The rules encourage ${him} to form friendships with other slaves, but ${he} seems disinclined to do so. ${He}'s both friendly with them and eagerly sexual with them when allowed, but ${he} seems to be waiting for someone, deep down.`);
			} else if (slave.rules.relationship === "just friends") {
				r.push(`The rules encourage ${him} to form friendships with other slaves.`);
			} else {
				r.push(`The rules encourage ${him} to form relationships with other slaves.`);
			}
		}

		return r;
	}

	/**
	 * @param {Array<string|HTMLElement>} parts
	 * @returns {HTMLSpanElement}
	 */
	function slaveRelationshipSpan(...parts) {
		const span = document.createElement("span");
		span.classList.add("si-relationship");
		span.append(...parts);
		return span;
	}

	function sleepLoc() {
		const r = [];

		if (slave.ID === V.HeadGirlID && V.HGSuite === 1) {
			r.push(`${He} lives in ${his} own suite within your penthouse,`);
		} else if ((slave.ID === V.BodyguardID) && (V.dojo > 1)) {
			r.push(`${He} lives in ${his} own room within the armory,`);
		} else if ([Job.MASTERSUITE, Job.CONCUBINE].includes(slave.assignment) && V.masterSuiteUpgradeLuxury === 1) {
			r.push(`${He} sleeps with you in your bed,`);
		} else if ((slave.assignment === Job.DAIRY) && (V.dairyRestraintsSetting > 1)) {
			r.push(`${He} sleeps attached to a milking machine,`);
		} else if (slave.rules.living === "spare") {
			r.push(`${He} sleeps on a bedroll,`);
		} else if (slave.rules.living === "normal") {
			r.push(`${He} sleeps on a cot,`);
		} else if (slave.relationship >= 4 && relTarget) {
			const {wife2, girl2} = getPronouns(relTarget).appendSuffix('2');
			r.push(`${He} has ${his} own room, which ${he} shares with ${his}`);
			if (slave.relationship === 5) {
				r.push(wife2);
			} else {
				r.push(`${girl2}friend`);
			}
			r.push(`whenever they can manage it,`);
		} else {
			r.push(`${He} sleeps in ${his} own little room,`);
		}
		r.push(App.Desc.releaseDesc(slave));

		return r.join(" ");
	}

	/**
	 * @param {App.Entity.SlaveState} slave
	 * @returns {string|HTMLSpanElement}
	 */
	function slaveReference(slave) {
		if (links) {
			return App.UI.DOM.referenceSlaveWithPreview(slave, SlaveFullName(slave));
		} else {
			return SlaveFullName(slave);
		}
	}
};


code:
/**
 * @param {App.Entity.SlaveState} slave
 * @returns {string}
 */
App.Desc.shoulders = function(slave) {
	const r = [];
	const {
		him, his, His
	} = getPronouns(slave);
	if (slave.fuckdoll === 0) {
		if (slave.shoulders < -1) {
			r.push(`${His} shoulders and chest are very narrow and`);
			if (slave.boobs > 2000) {
				r.push(`feminine, forcing ${his} pressed-together tits to spread far beyond ${his} sides.`);
			} else {
				r.push(`feminine.`);
			}
		} else if (slave.shoulders < 0) {
			r.push(`${His} shoulders and chest are quite`);
			if (slave.boobs > 1200) {
				r.push(`feminine, causing a lot of cleavage and pressing ${his} boobs outward beyond ${his} sides.`);
			} else {
				r.push(`feminine.`);
			}
		} else if (slave.shoulders > 1) {
			r.push(`${His} shoulders and chest are very`);
			if (slave.boobs > 600) {
				r.push(`broad, making ${his} boobs look a lot smaller than they actually are.`);
			} else {
				r.push(`broad.`);
			}
		} else if (slave.shoulders > 0) {
			r.push(`${His} shoulders and chest are fairly`);
			if (slave.boobs > 600) {
				r.push(`broad, making ${his} tits look smaller than they actually are.`);
			} else {
				r.push(`broad.`);
			}
		} else {
			r.push(`${His} shoulders and chest are`);
			if (slave.boobs > 800) {
				r.push(`feminine, flattering ${his} breasts.`);
			} else {
				r.push(`feminine.`);
			}
		}
		if (slave.shoulders > slave.hips) {
			r.push(`They're wider than ${his} hips,`);
			if (slave.boobs > 2000 * (slave.shoulders - slave.hips)) {
				r.push(`but ${his} massive breasts make it hard to discern.`);
			} else if (FutureSocieties.isActive('FSGenderRadicalist')) {
				r.push(`giving ${him} a somewhat mannish appearance.`);
			} else if (FutureSocieties.isActive('FSGenderFundamentalist')) {
				r.push(`giving ${him} an <span class="red">ugly, mannish appearance.</span>`);
			} else {
				r.push(`giving ${him} an <span class="red">unattractive, somewhat mannish, appearance.</span>`);
			}
		}
	}
	return r.join(" ");
};


code:
/**
 * @param {App.Entity.SlaveState} slave
 * @returns {string}
 */
App.Desc.skills = function(slave) {
	const r = [];
	const {
		He, girl
	} = getPronouns(slave);

	if (slave.fuckdoll > 0) {
		r.push(`${He} is`);
		if (slave.fuckdoll <= 10) {
			r.push(`poorly adapted to life as a living sex toy.`);
		} else if (slave.fuckdoll <= 30) {
			r.push(`<span class="skill">moderately adapted to life as a living sex toy.</span>`);
		} else if (slave.fuckdoll <= 60) {
			r.push(`<span class="skill">well adapted to life as a living sex toy.</span>`);
		} else if (slave.fuckdoll < 100) {
			r.push(`<span class="skill">almost perfectly adapted to life as a living sex toy.</span>`);
		} else {
			r.push(`<span class="skill">perfectly adapted to life as a living sex toy.</span>`);
		}
		r.push(`Entertainment and prostitution skills are irrelevant for a Fuckdoll.`);
	} else {
		if (slave.skill.whoring <= 10) {
			if (slave.skill.entertainment <= 10) {
				// no text
			} else if (slave.skill.entertainment <= 30) {
				r.push(`${He} is <span class="skill">reasonably entertaining.</span>`);
			} else if (slave.skill.entertainment <= 60) {
				r.push(`${He} is a <span class="skill">skilled entertainer.</span>`);
			} else if (slave.skill.entertainment < 100) {
				r.push(`${He} is an <span class="skill">expert entertainer.</span>`);
			} else {
				r.push(`${He} is a <span class="skill">master of entertainment.</span>`);
			}
		} else {
			if (slave.skill.entertainment <= 10) {
				// no text
			} else if (slave.skill.entertainment <= 30) {
				r.push(`${He} is <span class="skill">reasonably entertaining</span> and`);
			} else if (slave.skill.entertainment <= 60) {
				r.push(`${He} is a <span class="skill">skilled entertainer</span> and`);
			} else if (slave.skill.entertainment < 100) {
				r.push(`${He} is an <span class="skill">expert entertainer</span> and`);
			} else {
				r.push(`${He} is a <span class="skill">master of entertainment</span> and`);
			}
		}
		if (slave.skill.whoring <= 10) {
			// no text
		} else if (slave.skill.whoring <= 30) {
			if (slave.skill.entertainment <= 10) {
				r.push(`${He}`);
			}
			r.push(`has <span class="skill">basic experience as a prostitute.</span>`);
		} else if (slave.skill.whoring <= 60) {
			if (slave.skill.entertainment <= 10) {
				r.push(`${He} is`);
			}
			r.push(`a <span class="skill">skilled streetwalker.</span>`);
		} else if (slave.skill.whoring < 100) {
			if (slave.skill.entertainment <= 10) {
				r.push(`${He} is`);
			}
			r.push(`an <span class="skill">expert working ${girl}.</span>`);
		} else {
			if (slave.skill.entertainment <= 10) {
				r.push(`${He} is`);
			}
			r.push(`a <span class="skill">masterful whore.</span>`);
		}
	}
	return r.join(" ");
};


code:
/**
 * @param {App.Entity.SlaveState} slave
 * @param {DescType} descType
 * @returns {string}
 */
App.Desc.skin = function(slave, descType) {
	/** @type {Array<string>} */
	let r = [];
	const {
		he, his, He, His
	} = getPronouns(slave);

	const skin = (slave.race === "catgirl") ? "fur" : "skin";

	if (slave.fuckdoll > 0) {
		r.push(`The small areas of visible ${skin} are`);
		r = r.concat(freckles());
		r = r.concat(tanned());
	} else if (V.seeNationality === 1) {
		if (!slave.nationality) {
			r.push(`Ethnically, ${he}'s`);
		} else if (slave.nationality === "slave") {
			r.push(`${He}'s been chattel long enough that slavery is effectively ${his} nationality; ethnically, ${he}'s`);
		} else if (slave.nationality === "Stateless") {
			if (slave.tankBaby > 0) {
				r.push(`${He} was born in the Free Cities, and is considered stateless by old world nations; ethnically, ${he}'s`);
			} else {
				r.push(`${He} has spent so much time in the Free Cities that their statelessness is effectively ${his} nationality; ethnically, ${he}'s`);
			}
		} else if (slave.nationality === "Zimbabwean" && slave.race === "white") {
			r.push(`${He}'s originally <span class="nationality">Rhodesian;</span> ethnically, ${he}'s`);
		} else if (slave.nationality === "Vatican") {
			r.push(`${He}'s originally <span class="nationality">from Vatican City;</span> ethnically, ${he}'s`);
		} else {
			r.push(`${He}'s originally <span class="nationality">${slave.nationality};</span> ethnically, ${he}'s`);
		}
		r.push(`<span class="race">${slave.race},</span> and ${his} ${skin} is`);
		r.push(...freckles(), ...tanned(), ...changedRace());
	} else if (V.seeRace === 1) {
		r.push(`Ethnically, ${he}'s <span class="race">${slave.race},</span> and ${his} ${skin} is`);
		r.push(...freckles(), ...tanned(), ...changedRace());
	} else {
		r.push(`${His} ${skin} is`);
		r = r.concat(freckles());
		r = r.concat(tanned());
	}

	return r.join(" ");

	/**
	 * @returns {Array<string>}
	 */
	function changedRace() {
		/** @type {Array<string>} */
		const r = [];
		if (slave.race !== slave.origRace) {
			if (descType !== DescType.MARKET) {
				r.push(`${He} has received plastic surgery to appear ${slave.race}; ${he} is originally ${slave.origRace}.`);
			} else {
				if (V.PC.skill.medicine >= 100) {
					r.push(`Thanks to your medical experience, you can easily tell that ${he} was originally ${slave.origRace}, but surgically modified.`);
				} else if (V.PC.skill.medicine >= 50) {
					r.push(`Oddly enough, ${he} appears to have a number of ${slave.origRace} features.`);
				} else if (V.PC.skill.slaving >= 50) {
					r.push(`Thanks to your experience in buying and selling slaves, you can easily tell that ${he} is not naturally ${slave.race}.`);
				} else if (jsRandom(0, 100) < V.PC.skill.medicine) {
					r.push(`${His} features seem slightly off.`);
				}
			}
		}
		return r;
	}

	/**
	 * @returns {Array<string>}
	 */
	function freckles() {
		/** @type {Array<string>} */
		const r = [];
		if (slave.markings === "freckles" && slave.race === "catgirl") {
			r.push(`${slave.skin} and lightly spotted.`);
		} else if (slave.markings === "freckles") {
			r.push(`${slave.skin} and lightly`);
			if (App.Medicine.Modification.naturalSkins.includes(slave.skin) && skinToneLevel(slave.skin).isBetween(5, 10) && (App.Data.misc.redheadColors.includes(slave.hColor))) {
				r.push(`freckled, an attractive combination.`);
			} else {
				r.push(`freckled.`);
			}
		} else if (slave.markings === "heavily freckled" && slave.race === "catgirl") {
			r.push(`${slave.skin} and heavily spotted.`);
		} else if (slave.markings === "heavily freckled") {
			r.push(`${slave.skin} and heavily`);
			if (App.Medicine.Modification.naturalSkins.includes(slave.skin) && skinToneLevel(slave.skin).isBetween(5, 10) && (App.Data.misc.redheadColors.includes(slave.hColor))) {
				r.push(`freckled, an attractive combination.`);
			} else {
				r.push(`freckled.`);
			}
		} else {
			r.push(`${slave.skin}.`);
		}
		return r;
	}

	/**
	 * @returns {Array<string>}
	 */
	function tanned() {
		/** @type {Array<string>} */
		const r = [];
		if (slave.skin === "sun tanned" || slave.skin === "spray tanned") {
			r.push(`${His} ${skin} has been`);
			if (slave.skin === "sun tanned") {
				r.push(`tanned to a natural, healthy-looking tone.`);
			} else if (slave.skin === "spray tanned") {
				r.push(`tanned with obvious, garish-looking makeup.`);
			} else {
				r.push(`tanned.`);
			}
		}
		return r;
	}
};


code:
/**
 * @param {App.Entity.SlaveState} slave
 * @returns {string}
 */
App.Desc.armwear = function(slave) {
	const r = [];
	const {
		his, He
	} = getPronouns(slave);
	// TODO: check clothing descriptions for glove references
	if (hasAnyArms(slave) && !hasAnyQuadrupedArms(slave)) {
		switch (slave.armAccessory) {
			case "hand gloves":
				switch (slave.clothes) {
					default:
						if (hasBothArms(slave)) {
							r.push(`${He} is wearing a pair of simple gloves that cover ${his} hands up to ${his} wrists.`);
						} else {
							r.push(`${He} is wearing a simple glove that covers ${his} hand up to its wrist.`);
						}
				}
				break;
			case "elbow gloves":
				switch (slave.clothes) {
					case "no clothing":
					case "an apron":
					case "a thong":
					case "a skimpy loincloth":
					case "body oil":
					case "boyshorts":
					case "panties":
					case "panties and pasties":
						if (hasBothArms(slave)) {
							r.push(`${He} is wearing a pair of long${slave.collar === "leather with cowbell" ? " cow print" : ""} gloves that cover ${his} arms until just past ${his} elbows.`);
						} else {
							r.push(`${He} is wearing a long${slave.collar === "leather with cowbell" ? " cow print" : ""} glove that covers ${his} arm until just past its elbow.`);
						}
						break;
					default:
						if (hasBothArms(slave)) {
							r.push(`${He} is wearing a pair of long gloves that cover ${his} arms until just past ${his} elbows.`);
						} else {
							r.push(`${He} is wearing a long glove that covers ${his} arm until just past its elbow.`);
						}
				}
				break;
		}
	}

	return r.join(" ");
};