code:
App.UI.multipleOrganImplant = function() {
	const node = new DocumentFragment();

	node.append(intro());

	App.UI.DOM.appendNewElement("h1", node, "Implant Prosthetics");

	/* prosthetics */
	for (const slave of V.slaves) {
		V.AS = slave.ID;
		/* count for estimating health impact */
		const prostheticCount = V.adjustProsthetics.filter(p => p.slaveID === V.AS && p.workLeft <= 0).length;

		/* since we already have count, skip slaves that don't need work */
		if (prostheticCount < 1) {
			continue;
		}
		/*
		Ensures that a slave can never die during the execution of this passage.
		Calculation based on worst case, so when changing worst case change it here too.
		*/
		if (slave.health.health - (prostheticCount * 20) < -75) {
			App.UI.DOM.appendNewElement("hr", node);
			App.UI.DOM.appendNewElement("div", node, `Estimated health impact too great; ${slave.slaveName} skipped.`, ["health", "dec"]);
			continue;
		}

		const {
			he,
		} = getPronouns(slave);

		for (let k = 0; k < V.adjustProsthetics.length; k++) {
			const p = V.adjustProsthetics[k];
			if (p.slaveID === V.AS && p.workLeft <= 0) {
				V.adjustProsthetics.splice(k, 1);
				k--;
				V.adjustProstheticsCompleted--;
				addProsthetic(slave, p.id);
				const div = App.UI.DOM.appendNewElement("div", node, document.createElement("hr"));
				switch (p.id) {
					case "ocular":
						if (getBestVision(slave) === 0) {
							eyeSurgery(slave, "both", "cybernetic");
							cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave);
							surgeryDamage(slave, 20);
							V.surgeryType = "ocular implant";
							node.append(App.UI.SlaveInteract.surgeryDegradation(slave));
						} else {
							App.UI.DOM.appendNewElement("span", div, `Since ${he} has working eyes the ${App.Data.prosthetics.ocular.name} will be put into storage.`, "note");
						}
						break;
					case "cochlear":
						if (slave.hears !== 0) {
							slave.earImplant = 1;
							cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave);
							surgeryDamage(slave, 20);
							V.surgeryType = "cochlear implant";
							node.append(App.UI.SlaveInteract.surgeryDegradation(slave));
						} else {
							App.UI.DOM.appendNewElement("span", div, `Since ${he} has working ears the  ${App.Data.prosthetics.cochlear.name} will be put into storage.`, "note");
						}
						break;
					case "electrolarynx":
						if (slave.voice <= 0) {
							slave.electrolarynx = 1;
							slave.voice = 2;
							cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave);
							surgeryDamage(slave, 20);
							V.surgeryType = "electrolarynx";
							node.append(App.UI.SlaveInteract.surgeryDegradation(slave));
						} else {
							App.UI.DOM.appendNewElement("span", div, `Since ${he} has a voice the ${App.Data.prosthetics.electrolarynx.name} will be put into storage.`, "note");
						}
						break;
					case "interfaceP1":
						if (hasAnyNaturalLimbs(slave)) {
							App.UI.DOM.appendNewElement("span", div, `Since ${he} has at least one healthy limb the ${App.Data.prosthetics.interfaceP1.name} will be put into storage.`, "note");
						} else if (slave.PLimb === 2) {
							App.UI.DOM.appendNewElement("span", div, `Since ${he} already has ${addA(App.Data.prosthetics.interfaceP2.name)} installed the ${App.Data.prosthetics.interfaceP1.name} will be put into storage.`, "note");
						} else {
							slave.PLimb = 1;
							cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave);
							surgeryDamage(slave, 20);
							V.surgeryType = "PLimb interface1";
							node.append(App.UI.SlaveInteract.surgeryDegradation(slave));
						}
						break;
					case "interfaceP2":
						if (hasAllNaturalLimbs(slave)) {
							App.UI.DOM.appendNewElement("span", div, `Since ${he} has no amputated limbs the ${App.Data.prosthetics.interfaceP2.name} will be put into storage.`, "note");
						} else if (slave.PLimb === 1) {
							slave.PLimb = 2;
							cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave);
							surgeryDamage(slave, 5);
							V.surgeryType = "PLimb interface3";
							node.append(App.UI.SlaveInteract.surgeryDegradation(slave));
						} else {
							slave.PLimb = 2;
							cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave);
							surgeryDamage(slave, 20);
							V.surgeryType = "PLimb interface2";
							node.append(App.UI.SlaveInteract.surgeryDegradation(slave));
						}
						break;
					case "basicL":
					case "sexL":
					case "beautyL":
					case "combatL":
					case "cyberneticL":
						if (slave.fuckdoll !== 0) {
							App.UI.DOM.appendNewElement("span", div, `Since a Fuckdoll can't use prosthetic limbs the ${App.Data.prosthetics[p.id].name} will be put into storage.`, "note");
						} else if (hasAllNaturalLimbs(slave)) {
							App.UI.DOM.appendNewElement("span", div, `Since ${he} needs an amputated limb to attach prosthetics the ${App.Data.prosthetics[p.id].name} will be put into storage.`, "note");
						} else if (slave.PLimb === 0) {
							App.UI.DOM.appendNewElement("span", div, `Since ${he} must have a prosthetic interface installed to attach prosthetic limbs the ${App.Data.prosthetics[p.id].name} will be put into storage.`, "note");
						} else {
							if (p.id === "basicL") {
								const state = App.Medicine.Limbs.currentLimbs(slave);
								const change = upgradeLimbs(slave, 2);
								if (change) {
									node.append(App.Medicine.Limbs.reaction(slave, state));
								} else {
									App.UI.DOM.appendNewElement("span", div, `Since ${he} already has more advanced prosthetic limbs attached the ${App.Data.prosthetics.basicL.name} will be put into storage.`, "note");
								}
							} else if (p.id === "sexL") {
								const state = App.Medicine.Limbs.currentLimbs(slave);
								const change = upgradeLimbs(slave, 3);
								if (change) {
									node.append(App.Medicine.Limbs.reaction(slave, state));
								} else {
									App.UI.DOM.appendNewElement("span", div, `Since ${he} already has advanced prosthetic limbs attached the ${App.Data.prosthetics.sexL.name} will be put into storage.`, "note");
								}
							} else if (p.id === "beautyL") {
								const state = App.Medicine.Limbs.currentLimbs(slave);
								const change = upgradeLimbs(slave, 4);
								if (change) {
									node.append(App.Medicine.Limbs.reaction(slave, state));
								} else {
									App.UI.DOM.appendNewElement("span", div, `Since ${he} already has advanced prosthetic limbs attached the ${App.Data.prosthetics.beautyL.name} will be put into storage.`, "note");
								}
							} else if (p.id === "combatL") {
								const state = App.Medicine.Limbs.currentLimbs(slave);
								const change = upgradeLimbs(slave, 5);
								if (change) {
									node.append(App.Medicine.Limbs.reaction(slave, state));
								} else {
									App.UI.DOM.appendNewElement("span", div, `Since ${he} already has advanced prosthetic limbs attached the ${App.Data.prosthetics.combatL.name} will be put into storage.`, "note");
								}
							} else {
								if (slave.PLimb === 2) {
									const state = App.Medicine.Limbs.currentLimbs(slave);
									const change = upgradeLimbs(slave, 2);
									if (change) {
										node.append(App.Medicine.Limbs.reaction(slave, state));
									}
								} else {
									App.UI.DOM.appendNewElement("span", div, `Since ${he} must have ${addA(App.Data.prosthetics.interfaceP2.name)} installed to attach cybernetic limbs the ${App.Data.prosthetics.cyberneticL.name} will be put into storage.`, "note");
								}
							}
						}
						break;
					case "interfaceTail":
						slave.PTail = 1;
						slave.tail = "none";
						slave.tailColor = "none";
						cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave);
						surgeryDamage(slave, 10);
						V.surgeryType = "tailInterface";
						node.append(App.UI.SlaveInteract.surgeryDegradation(slave));
						break;
					case "modT":
					case "sexT":
					case "combatT":
						if (slave.PTail === 0) {
							App.UI.DOM.appendNewElement("span", div, `Since ${he} must have ${addA(App.Data.prosthetics.interfaceTail.name)} installed to attach tails the ${App.Data.prosthetics[p.id].name} will be put into storage.`, "note");
						} else if (slave.tail !== "none") {
							App.UI.DOM.appendNewElement("span", div, `Since ${he} currently has a tail attached the ${App.Data.prosthetics[p.id].name} will be put into storage.`, "note");
						} else if (p.id === "modT") {
							App.UI.DOM.appendNewElement("span", div, `Since installing ${addA(App.Data.prosthetics.modT.name)} is complicated it can't be automated.`, "note");
							/* Reason: there are different designs player can choose from.*/
						} else if (p.id === "combatT") {
							V.prostheticsConfig = "attachTail";
							slave.tail = "combat";
							slave.tailColor = "jet black";
							node.append(App.UI.prostheticsConfigPassage());
						} else if (p.id === "sexT") {
							V.prostheticsConfig = "attachTail";
							slave.tail = "sex";
							slave.tailColor = "pink";
							node.append(App.UI.prostheticsConfigPassage());
						}
						break;
					default:
						App.UI.DOM.appendNewElement("span", div, `Since there is no automated procedure to implant/attach ${App.Data.prosthetics[p.id].name} it will be put into storage.`, "note");
				}
			}
		}
	}

	/* This needs to be down here to over-ride any Surgery Degradation calls */
	V.nextButton = "Continue";
	V.nextLink = "Main";

	return node;

	function intro() {
		const frag = document.createDocumentFragment();

		// Get the slaves with ready organs/prosthetics to have a count
		const ids = new Set();
		for (const organ of V.completedOrgans) {
			ids.add(organ.ID);
		}
		for (const p of V.adjustProsthetics) {
			if (p.workLeft <= 0) {
				ids.add(p.ID);
			}
		}

		let r = [];
		r.push("You head down to your");
		if (V.surgeryUpgrade === 1) {
			r.push("heavily upgraded and customized");
		}
		r.push(`remote surgery and start having the ${ids.size > 1 ? "slaves" : "slave"} with`);
		if (V.completedOrgans.length > 0 && V.adjustProstheticsCompleted > 0) {
			r.push("organs or prosthetics");
		} else if (V.completedOrgans.length > 1) {
			r.push("organs");
		} else if (V.adjustProstheticsCompleted > 1) {
			r.push("prosthetics");
		}
		r.push("which are ready be sent down.");

		App.UI.DOM.appendNewElement("p", frag, r.join(" "));

		let any = false;
		const applyFrag = new DocumentFragment();

		let F = App.Medicine.OrganFarm;
		for (const slave of V.slaves) {
			let sortedOrgans = F.getSortedOrgans(slave);
			if (sortedOrgans.length === 0) {
				continue;
			}
			any = true;

			App.UI.DOM.appendNewElement("h2", applyFrag, slave.slaveName);

			for (let j = 0; j < sortedOrgans.length; j++) {
				App.UI.DOM.appendNewElement("h3", applyFrag, F.Organs.get(sortedOrgans[j]).name);

				let actions = F.Organs.get(sortedOrgans[j]).implantActions;
				let manual = false;
				let success = false;
				let cancel = false;
				for (let k = 0; k < actions.length; k++) {
					if (!actions[k].autoImplant) {
						if (actions[k].canImplant(slave)) {
							manual = true;
						}
						continue;
					}
					if (!actions[k].canImplant(slave)) {
						let error = actions[k].implantError(slave);
						if (error !== "") {
							App.UI.DOM.appendNewElement("div", applyFrag, error, "warning");
						}
					} else if (slave.health.health - actions[k].healthImpact < -75) {
						App.UI.DOM.appendNewElement("div", applyFrag, "Estimated health impact too high, skipping further surgeries.");
						cancel = true;
						break;
					} else {
						App.Medicine.OrganFarm.implant(slave, sortedOrgans[j], k);
						App.UI.DOM.appendNewElement("p", applyFrag, App.UI.SlaveInteract.surgeryDegradation(slave));
						success = true;
					}
				}
				if (cancel) {
					break;
				}
				if (!success && manual) {
					App.UI.DOM.appendNewElement("div", applyFrag, `Cannot implant ${F.Organs.get(sortedOrgans[j]).name.toLowerCase()} automatically, try implanting manually in the remote surgery.`, "note");
				}
			}
		}
		frag.append(applyFrag);

		if (any) {
			App.UI.DOM.appendNewElement("h1", frag, "Implant Organs");
		}
		return frag;
	}
};


code:
/** @param {App.Entity.SlaveState} slave */
App.UI.SlaveInteract.remoteSurgery = function(slave) {
	const el = new DocumentFragment();
	const {His} = getPronouns(slave);
	updateHealth(slave);

	V.surgeryType = 0;
	V.encyclopedia = "The Remote Surgery";
	/* get all prosthetics that are ready for this slave */
	if (V.adjustProstheticsCompleted > 0) {
		V.adjustProsthetics = V.adjustProsthetics.filter(function(p) {
			if (p.workLeft <= 0 && p.slaveID === V.AS) {
				addProsthetic(slave, p.id);
				V.adjustProstheticsCompleted--;
				return false;
			}
			return true;
		});
	}

	App.UI.DOM.appendNewElement("h1", el, "The Remote Surgery");

	const introP = document.createElement("p");
	introP.classList.add("scene-intro");
	App.Events.addNode(introP, intro());
	el.append(introP);

	if (slave.indentureRestrictions >= 1) {
		App.UI.DOM.appendNewElement("p", el, `${His} indenture forbids elective surgery`, ["yellow", "note"]);
	}

	const tabBar = new App.UI.Tabs.TabBar("RemoteSurgery");
	const f = new DocumentFragment();
	App.Events.drawEventArt(f, slave);
	tabBar.customNode = f;

	tabBar.addTab("Hair and Face", "hairAndFace", App.UI.surgeryPassageHairAndFace(slave, refresh));
	tabBar.addTab("Upper", "upper", App.UI.surgeryPassageUpper(slave, refresh));
	tabBar.addTab("Lower", "lower", App.UI.surgeryPassageLower(slave, refresh));
	tabBar.addTab("Structural", "structural", App.UI.surgeryPassageStructural(slave, refresh));
	tabBar.addTab("Exotic", "exotic", App.UI.surgeryPassageExotic(slave));
	if (V.seeExtreme) {
		tabBar.addTab("Extreme", "extreme", App.UI.surgeryPassageExtreme(slave));
	}
	el.append(tabBar.render());

	return el;

	/**
	 * @returns {Array<string|HTMLElement>}
	 */
	function intro() {
		const r = [];
		r.push(`${slave.slaveName} is lying strapped down on the table in your`);
		if (V.surgeryUpgrade === 1) {
			r.push(`heavily upgraded and customized`);
		}
		r.push(`remote surgery. The surgical equipment reads`);
		if (slave.health.health < -20) {
			r.push(App.UI.DOM.makeElement("span", `SLAVE UNHEALTHY, SURGERY NOT RECOMMENDED.`, "red"));
		} else if (slave.health.health <= 20) {
			r.push(App.UI.DOM.makeElement("span", `SLAVE HEALTHY, SURGERY SAFE.`, "yellow"));
		} else {
			r.push(App.UI.DOM.makeElement("span", `SLAVE HEALTHY, SURGERY ENCOURAGED.`, "green"));
		}
		if (V.PC.skill.medicine >= 100) {
			r.push(`The remote surgery mechanisms that allow a surgeon to be brought in by telepresence are inactive, and the autosurgery is ready for your control inputs. Surgery on your slaves is a challenge and a pleasure you wouldn't dream of sharing.`);
		}
		return r;
	}

	function refresh() {
		$(introP).empty();
		App.Events.addNode(introP, intro());
	}
};

repo_name: Elohiem/fc

license: mit


code:
/**
 * UI for performing surgery. Refreshes without refreshing the passage.
 * @param {App.Entity.SlaveState} slave
 * @param {boolean} [cheat=false]
 * @returns {HTMLElement}
 */

App.UI.surgeryPassageExotic = function(slave, cheat = false) {
	const container = document.createElement("span");
	container.append(content());
	return container;

	function content() {
		const frag = new DocumentFragment();
		const {
			His, He,
			his, him
		} = getPronouns(slave);

		frag.append(race());
		if (V.geneticMappingUpgrade >= 1) {
			App.UI.DOM.appendNewElement("h3", frag, `Retro-virus treatments:`);
			frag.append(geneTherapy());
		}
		frag.append(bodySwap());

		return frag;

		function race() {
			const el = new DocumentFragment();
			const linkArray = [];
			App.UI.DOM.appendNewElement("div", el, `${He} is ${slave.race}${(slave.race !== slave.origRace) ? `, but was originally ${slave.origRace}` : ``}. Surgically alter ${him} to look more:`);
			if (slave.indentureRestrictions > 1) {
				App.UI.DOM.appendNewElement("div", el, `${His} indenture forbids elective surgery`, ["choices", "note"]);
			} else {
				for (const [race, capRace] of App.Data.misc.filterRaces) {
					if (slave.race === race) {
						continue;
					}
					linkArray.push(
						makeLink(
							capRace,
							"race",
							() => {
								slave.race = race;
								slave.skin = randomRaceSkin(slave.race);
								slave.hColor = randomRaceHair(slave.race);
								setEyeColor(slave, randomRaceEye(slave.race));
								surgeryDamage(slave, 20);
							}
						)
					);
				}
			}

			App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices");
			return el;
		}

		function geneTherapy() {
			const el = new DocumentFragment();
			const r = [];
			const linkArray = [];
			if (slave.indentureRestrictions >= 1) {
				App.UI.DOM.appendNewElement("div", el, `${His} indenture forbids elective surgery`, ["choices", "note"]);
			} else if (slave.health.health < 0) {
				App.UI.DOM.appendNewElement("div", el, `${He}'s too unhealthy to undergo gene therapy`, ["choices", "note"]);
			} else {
				if (V.arcologies[0].childhoodFertilityInducedNCSResearch === 1) {
					if (slave.geneMods.NCS === 0) {
						linkArray.push(makeLink(
							"Induced NCS treatment",
							"retrograde virus injection NCS",
							() => {
								slave.geneMods.NCS = 1;
								slave.chem += 40;
								surgeryDamage(slave, 80);
							},
							4,
							`This will induce NCS in ${his} genetic code`
						));
					} else {
						App.UI.DOM.appendNewElement("div", el, `${He} already has Induced NCS`, ["choices", "note"]);
					}
				}

				if (V.RapidCellGrowthFormula === 1) {
					if (slave.geneMods.rapidCellGrowth === 0) {
						linkArray.push(makeLink(
							"Increased elasticity treatment",
							"gene treatment",
							() => {
								slave.geneMods.rapidCellGrowth = 1;
								slave.chem += 100;
								surgeryDamage(slave, 40);
							},
							4,
							`This will alter ${his} genetic code to encourage ${his} body to stretch`
						));
					} else {
						App.UI.DOM.appendNewElement("div", el, `${He} already has received the plasticity increasing elasticity treatment`, ["choices", "note"]);
					}
				}

				if (V.immortalityFormula === 1) {
					if (slave.geneMods.immortality === 0) {
						linkArray.push(makeLink(
							"Immortality",
							"gene treatment",
							() => {
								slave.geneMods.immortality = 1;
								slave.chem += 1000;
								surgeryDamage(slave, 40);
							},
							4,
							`This will alter ${his} genetic code to reverse and prevent aging, effectively thwarting the rigors of old age`
						));
					} else {
						App.UI.DOM.appendNewElement("div", el, `${He} already is already immortal`, ["choices", "note"]);
					}
				}
			}
			App.Events.addNode(el, r, "div");
			App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices");
			el.append(retroVirus());
			return el;

			function retroVirus() {
				const el = new DocumentFragment();
				const slaveGeneList = App.UI.DOM.appendNewElement("ul", el);
				const select = App.UI.DOM.appendNewElement("select", el);
				select.classList.add("rajs-list");
				const description = App.UI.DOM.appendNewElement("div", el, null);
				for (const gene in slave.geneticQuirks) {
					const geneData = App.Data.geneticQuirks.get(gene);

					// Continue if player settings do not allow them to even see it described
					if (geneData.hasOwnProperty("requirements") && !geneData.requirements) {
						continue;
					}

					if (slave.geneticQuirks[gene] === 2 || (slave.geneticQuirks[gene] === 1 && V.geneticMappingUpgrade >= 2)) {
						const strength = (slave.geneticQuirks[gene] === 1) ? "Carrier for " : "Activated ";
						App.UI.DOM.appendNewElement("li", slaveGeneList, strength)
							.append(App.UI.DOM.makeElement("span", geneData.title, "orange"));
					}

					// Some of these can be described, but not tweaked in certain ways and circumstances
					if (
						(gene === "pFace" && slave.geneticQuirks.pFace !== 2) ||
						(gene === "uFace" && slave.geneticQuirks.uFace !== 2) ||
						(["heterochromia", "girlsOnly"].includes(gene))
					) {
						continue;
					}
					const choice = App.UI.DOM.appendNewElement("option", select, capFirstChar(geneData.title));
					choice.value = gene;
					select.append(choice);
				}
				select.selectedIndex = -1;
				select.onchange = () => {
					// selectedGene = select.options[select.selectedIndex];
					jQuery(description).empty().append(describeGene(select.value));
				};

				return el;

				function describeGene(selectedGene) {
					const el = new DocumentFragment();
					const r = [];
					const linkArray = [];
					const geneData = App.Data.geneticQuirks.get(selectedGene);
					r.push(`Selected gene is`);
					r.push(App.UI.DOM.makeElement("span", `${geneData.title}:`, "orange"));
					r.push(`${geneData.description}.`);
					App.Events.addNode(el, r, "div");

					const warning = "Applying a retro-virus treatment radically increases carcinogen buildup.";
					if (["pFace", "uFace"].includes(selectedGene)) {
						linkArray.push(makeLink(
							`Prevent passing of ${geneData.title}s`,
							"gene treatment",
							() => {
								slave.geneticQuirks[selectedGene] = 0;
								slave.chem += 100;
								surgeryDamage(slave, 40);
							},
							4,
							warning
						));
					} else if (slave.geneticQuirks[selectedGene] === 2) {
						linkArray.push(makeLink(
							`Correct ${geneData.title}`,
							"gene treatment",
							() => {
								if (selectedGene === "albinism") {
									induceAlbinism(slave, 0);
								} else {
									slave.geneticQuirks[selectedGene] = 0;
								}
								slave.chem += 100;
								surgeryDamage(slave, 40);
							},
							4,
							warning
						));
					} else if (slave.geneticQuirks[selectedGene] === 1 && V.geneticMappingUpgrade >= 2) {
						linkArray.push(makeLink(
							`${capFirstChar(geneData.title)} activation treatment`,
							"gene treatment",
							() => {
								if (selectedGene === "albinism") {
									induceAlbinism(slave, 2);
								} else {
									slave.geneticQuirks[selectedGene] = 2;
								}
								slave.chem += 100;
								surgeryDamage(slave, 40);
							},
							4,
							warning
						));
						linkArray.push(makeLink(
							`${capFirstChar(geneData.title)} carrier corrective treatment`,
							"gene treatment",
							() => {
								if (selectedGene === "albinism") {
									induceAlbinism(slave, 0);
								} else {
									slave.geneticQuirks[selectedGene] = 0;
								}
								slave.chem += 100;
								surgeryDamage(slave, 40);
							},
							4,
							warning
						));
					} else if (V.geneticFlawLibrary === 1) {
						linkArray.push(makeLink(
							`Induced ${geneData.title} treatment`,
							"gene treatment",
							() => {
								if (selectedGene === "albinism") {
									induceAlbinism(slave, 2);
								} else {
									slave.geneticQuirks[selectedGene] = 2;
								}
								slave.chem += 100;
								surgeryDamage(slave, 40);
							},
							10,
							`This will induce ${geneData.title} in ${his} genetic code. ${warning}`
						));
					}
					App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices");
					return el;
				}
			}
		}

		function bodySwap() {
			const el = new DocumentFragment();
			const r = [];
			const linkArray = [];
			if (V.bodyswapAnnounced === 1 && slave.indenture < 0) {
				if (slave.bodySwap === 0) {
					r.push(`${He} is in ${his} native body.`);
				} else if (slave.origBodyOwner !== "") {
					r.push(`${He} currently occupies ${slave.origBodyOwner}'s body.`);
				} else {
					r.push(`${He} is no longer in ${his} native body.`);
				}
				if (slave.indenture === -1) {
					linkArray.push(App.UI.DOM.passageLink(
						`Swap ${his} body with another of your stock`,
						"Slave Slave Swap Workaround",
					));
				} else {
					App.UI.DOM.appendNewElement("div", el, `Indentured servants must remain in their own bodies.`, ["choices", "note"]);
				}
			} else if (V.cheatMode === 1) {
				linkArray.push(App.UI.DOM.link(
					`Force enable bodyswapping`,
					() => {
						V.bodyswapAnnounced = 1;
					},
					[],
					"Remote Surgery",
				));
			}
			App.Events.addNode(el, r, "div");
			App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices");
			return el;
		}

		/**
		 *
		 * @param {string} title
		 * @param {string} surgeryType
		 * @param {function(void):void} [func]
		 * @param {number} [costMult=1]
		 * @param {string} [note]
		 * @returns {HTMLAnchorElement}
		 */
		function makeLink(title, surgeryType, func, costMult = 1, note = "") {
			const cost = Math.trunc(V.surgeryCost * costMult);
			const tooltip = new DocumentFragment();
			App.UI.DOM.appendNewElement("div", tooltip, `Costs ${cashFormat(cost)}.`);
			if (note) {
				App.UI.DOM.appendNewElement("div", tooltip, note);
			}
			return App.UI.DOM.link(
				title,
				() => {
					if (typeof func === "function") {
						func();
					}
					if (cheat) {
						jQuery(container).empty().append(content());
						App.Events.refreshEventArt(slave);
					} else {
						V.surgeryType = surgeryType;
						// TODO: pass if it affected health or not?
						cashX(forceNeg(cost), "slaveSurgery", slave);
						Engine.play("Surgery Degradation");
					}
				},
				[],
				"",
				tooltip
			);
		}
	}
};


code:
/**
 * UI for performing surgery. Refreshes without refreshing the passage.
 * @param {App.Entity.SlaveState} slave
 * @param {boolean} [cheat=false]
 * @returns {HTMLElement}
 */

App.UI.surgeryPassageExtreme = function(slave, cheat = false) {
	const container = document.createElement("span");
	container.append(content());
	return container;

	function content() {
		const frag = new DocumentFragment();
		const {
			His, He,
			his, he, him
		} = getPronouns(slave);

		if (V.seeExtreme === 1) {
			frag.append(fuckdoll(), chemLobotomy());
		}

		return frag;

		function fuckdoll() {
			const el = new DocumentFragment();
			const r = [];
			const linkArray = [];
			if (slave.fuckdoll === 0) {
				r.push(`${He} is a normal sex slave, not a living sex toy.`);
				if (slave.indentureRestrictions < 1 && (slave.breedingMark !== 1 || V.propOutcome === 0 || V.eugenicsFullControl === 1 || V.arcologies[0].FSRestart === "unset")) {
					linkArray.push(makeLink(
						"Encase in a Fuckdoll suit",
						"fuckdoll",
						() => {
							beginFuckdoll(slave);
							SetBellySize(slave);
						},
						0,
						`This will greatly restrict ${him}`
					));
				}
			} else {
				r.push(`${He} is encased in a Fuckdoll suit.`);
				linkArray.push(makeLink(
					`Extract ${him}`,
					"fuckdollExtraction",
					() => {
						slave.fuckdoll = 0;
						slave.clothes = "no clothing";
						slave.shoes = "none";
					},
					0
				));
			}
			App.Events.addNode(el, r, "div");
			App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices");
			return el;
		}

		function chemLobotomy() {
			const el = new DocumentFragment();
			const r = [];
			const linkArray = [];
			if (slave.fetish !== "mindbroken") {
				r.push(`${He} is mentally competent.`);
			} else if (slave.fetish === "mindbroken") {
				r.push(`${His} mind is gone; ${he} has either been chemically lobotomized, or has lost ${his} mind due to extreme abuse.`);
			}
			if (slave.indentureRestrictions < 1 && (slave.breedingMark !== 1 || V.propOutcome === 0 || V.eugenicsFullControl === 1 || V.arcologies[0].FSRestart === "unset")) {
				if (slave.fetish !== "mindbroken") {
					linkArray.push(makeLink(
						"Chemically lobotomize",
						"mindbreak",
						() => {
							applyMindbroken(slave);
							surgeryDamage(slave, 20);
						},
						1,
						`Warning: this is permanent and irreversible. It will destroy ${his} will and ${his} ability to remember anything but the simplest skills.`
					));
				}
			}
			App.Events.addNode(el, r, "div");
			App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices");
			return el;
		}

		/**
		 *
		 * @param {string} title
		 * @param {string} surgeryType
		 * @param {function(void):void} [func]
		 * @param {number} [costMult=1]
		 * @param {string} [note]
		 * @returns {HTMLAnchorElement}
		 */
		function makeLink(title, surgeryType, func, costMult = 1, note = "") {
			const cost = Math.trunc(V.surgeryCost * costMult);
			const tooltip = new DocumentFragment();
			App.UI.DOM.appendNewElement("div", tooltip, `Costs ${cashFormat(cost)}.`);
			if (note) {
				App.UI.DOM.appendNewElement("div", tooltip, note);
			}
			return App.UI.DOM.link(
				title,
				() => {
					if (typeof func === "function") {
						func();
					}
					if (cheat) {
						jQuery(container).empty().append(content());
						App.Events.refreshEventArt(slave);
					} else {
						V.surgeryType = surgeryType;
						// TODO: pass if it affected health or not?
						cashX(forceNeg(cost), "slaveSurgery", slave);
						Engine.play("Surgery Degradation");
					}
				},
				[],
				"",
				tooltip
			);
		}
	}
};


code:
/**
 * UI for performing surgery. Refreshes without refreshing the passage.
 * @param {App.Entity.SlaveState} slave
 * @param {function():void} refreshParent
 * @param {boolean} [cheat=false]
 * @returns {HTMLElement}
 */

App.UI.surgeryPassageHairAndFace = function(slave, refreshParent, cheat = false) {
	const container = document.createElement("span");
	container.append(content());
	return container;

	function content() {
		const frag = new DocumentFragment();
		const pubertyAge = Math.min(slave.pubertyAgeXX, slave.pubertyAgeXY);
		const {
			His, He,
			his, him
		} = getPronouns(slave);
		const artificiality = faceSurgeryArtificiality();

		App.UI.DOM.appendNewElement("h3", frag, `Hair:`);
		frag.append(
			mainHair(), eyebrows(), armpitHair()
		);

		App.UI.DOM.appendNewElement("h3", frag, `Face:`);
		frag.append(
			faceShape(), eyes(), ears(), topEars(), hearing(), horns(), lips(), teeth(), voice(), chemosensory()
		);

		return frag;

		function mainHair() {
			const el = new DocumentFragment();
			if (slave.bald === 0 && slave.hStyle !== "bald") {
				App.UI.DOM.appendNewElement("div", el, `${He} naturally grows ${slave.origHColor} hair from ${his} head.`);
				if (slave.indentureRestrictions > 1) {
					App.UI.DOM.appendNewElement("div", el, `${His} indenture forbids elective surgery`, ["choices", "note"]);
				} else {
					App.UI.DOM.appendNewElement("div", el,
						App.Medicine.Surgery.makeLink(new App.Medicine.Surgery.Procedures.HairRemoval(slave), refresh, cheat),
						"choices");
				}
			} else {
				App.UI.DOM.appendNewElement("div", el, `${He} is no longer capable of growing hair on ${his} head.`);
			}
			return el;
		}

		function eyebrows() {
			const el = new DocumentFragment();
			if (slave.eyebrowHStyle !== "bald") {
				App.UI.DOM.appendNewElement("div", el, `${He} has ${slave.origHColor} eyebrows.`);
				if (slave.indentureRestrictions > 1) {
					App.UI.DOM.appendNewElement("div", el, `${His} indenture forbids elective surgery`, ["choices", "note"]);
				} else {
					App.UI.DOM.appendNewElement("div", el,
						App.Medicine.Surgery.makeLink(new App.Medicine.Surgery.Procedures.EyebrowRemoval(slave), refresh, cheat),
						"choices");
				}
			} else {
				App.UI.DOM.appendNewElement("div", el, `${He} is no longer capable of growing eyebrow hair.`);
			}
			return el;
		}

		function armpitHair() {
			const el = new DocumentFragment();
			const r = [];
			if ((slave.underArmHStyle !== "bald" && slave.underArmHStyle !== "hairless") || (slave.pubicHStyle !== "bald" && slave.pubicHStyle !== "hairless")) {
				r.push(`${He}`);
				if (slave.physicalAge >= pubertyAge) {
					r.push(`naturally grows`);
				} else if (slave.physicalAge >= pubertyAge - 1) {
					r.push(`is beginning to grow`);
				} else {
					r.push(`will someday grow`);
				}
				r.push(`${slave.origHColor} body hair.`);
				App.Events.addNode(el, r, "div");
				if (slave.indentureRestrictions > 1) {
					App.UI.DOM.appendNewElement("div", el, `${His} indenture forbids elective surgery`, ["choices", "note"]);
				} else {
					App.UI.DOM.appendNewElement("div", el,
						App.Medicine.Surgery.makeLink(new App.Medicine.Surgery.Procedures.BodyHairRemoval(slave), refresh, cheat),
						"note");
				}
			} else {
				r.push(`${His} ${slave.skin} skin is silky smooth and hair free from ${his} neck to ${his}`);
				if (!hasAnyLegs(slave)) {
					r.push(`hips.`);
				} else {
					r.push(`toes.`);
				}
				App.Events.addNode(el, r, "div");
			}
			return el;
		}

		function faceShape() {
			const el = new DocumentFragment();
			let r = [];
			r.push(`${His} ${slave.faceShape} face is`);
			const faceDiv = App.UI.DOM.appendNewElement("div", el);
			if (slave.face < -95) {
				r.push(`very ugly.`);
			} else if (slave.face < -40) {
				r.push(`ugly.`);
			} else if (slave.face < -10) {
				r.push(`unattractive.`);
			} else if (slave.face <= 10) {
				r.push(`quite average.`);
			} else if (slave.face <= 40) {
				r.push(`attractive.`);
			} else if (slave.face <= 95) {
				r.push(`beautiful.`);
			} else if (slave.face > 95) {
				r.push(`very beautiful.`);
			}

			if (slave.faceImplant === 0) {
				r.push(`It is entirely natural.`);
			} else if (slave.faceImplant > 5) {
				r.push(`It has seen some work.`);
			} else if (slave.faceImplant > 30) {
				r.push(`It has been totally reworked.`);
			}
			App.Events.addNode(faceDiv, r, "div");

			if (slave.indentureRestrictions > 1) {
				App.UI.DOM.appendNewElement("div", el, `${His} indenture forbids elective surgery`, ["choices", "note"]);
			} else if (slave.faceImplant > 95) {
				App.UI.DOM.appendNewElement("div", el, `${His} face cannot sustain further cosmetic surgery`, ["choices", "note"]);
			} else {
				const linkArray = [];
				const faceMap = (slave.faceShape === "masculine") ? new Map([["normal", {}], ["androgynous", {}]]) : App.Medicine.Modification.faceShape;

				for (const [key, shape] of faceMap) {
					if (
						(shape.hasOwnProperty("requirements") && !shape.requirements) ||
						slave.faceShape === key || // Can't change to what you are
						slave.faceShape !== "androgynous" && key === "masculine" // Can't go directly to or from masculine, have to go through androgynous
					) {
						continue;
					}
					linkArray.push(App.Medicine.Surgery.makeLink(new App.Medicine.Surgery.Procedures.FaceShape(slave, key), refresh, cheat));
				}
				linkArray.push(App.Medicine.Surgery.makeLink(new App.Medicine.Surgery.Procedures.FaceAttractiveness(slave), refresh, cheat));
				App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices");
				r = [];
				r.push(`Facial surgery can either rework it and improve its attractiveness, or simply make it more attractive. No facial surgery is perfect and each surgery will make it look less natural.`);
				if (V.PC.skill.medicine >= 100 && V.surgeryUpgrade) {
					r.push(`Your surgical skills and the advanced surgical suite will minimize this effect as much as possible.`);
				} else if (V.PC.skill.medicine >= 100) {
					r.push(`Your surgical skills will reduce this effect.`);
				} else if (V.surgeryUpgrade) {
					r.push(`The advanced surgical suite will reduce this effect.`);
				}
				if (slave.faceImplant + artificiality > 95) {
					r.push(App.UI.DOM.makeElement("span", `${(slave.faceImplant !== 0) ? `Further facial` : `Facial`} surgery will create a severe uncanny valley effect.`, "yellow"));
				} else if (slave.faceImplant + artificiality > 60 && slave.faceImplant <= 60) {
					r.push(App.UI.DOM.makeElement("span", `${(slave.faceImplant !== 0) ? `Further facial` : `Facial`}surgery will be extremely obvious.`, "yellow"));
				} else if (slave.faceImplant + artificiality > 30 && slave.faceImplant <= 30) {
					r.push(App.UI.DOM.makeElement("span", `${(slave.faceImplant !== 0) ? `Further facial` : `Facial`} surgery will eliminate a natural appearance.`, "yellow"));
				} else if (slave.faceImplant + artificiality > 5 && slave.faceImplant <= 5) {
					r.push(App.UI.DOM.makeElement("span", `${(slave.faceImplant !== 0) ? `Further facial` : `Facial`} surgery will disturb a perfectly natural appearance.`, "yellow"));
				} else {
					r.push(`A single facial surgery is not projected to significantly impact artificiality.`);
				}
				App.Events.addNode(faceDiv, r, "span", "note");
			}

			if (slave.indentureRestrictions < 2 && slave.faceImplant <= 95) {
				if (slave.ageImplant > 1) {
					App.UI.DOM.appendNewElement("div", el, `${He}'s had a multiple facelifts and other cosmetic procedures in an effort to preserve ${his} youth.`);
				} else if (slave.ageImplant > 0) {
					App.UI.DOM.appendNewElement("div", el, `${He}'s had a face lift and other minor cosmetic procedures to make ${him} look younger.`);
				} else if (slave.physicalAge >= 25 && slave.visualAge >= 25) {
					App.UI.DOM.appendNewElement("div", el, `${He}'s old enough that a face lift and other minor cosmetic procedures could make ${him} look younger.`);
					App.UI.DOM.appendNewElement("div", el,
						App.Medicine.Surgery.makeLink(new App.Medicine.Surgery.Procedures.AgeLift(slave), refresh, cheat),
						"choices");
				}
			}
			return el;
		}

		function eyes() {
			const el = new DocumentFragment();
			let linkArray;
			App.UI.DOM.appendNewElement("div", el, `${He} has ${App.Desc.eyesType(slave)}${(hasAnyEyes(slave)) ? `, they are ${App.Desc.eyesVision(slave)}` : ``}.`);
			/* eye blur and fix */
			if (hasAnyEyes(slave)) {
				/* Blur eyes*/
				if (slave.indentureRestrictions > 1) {
					App.UI.DOM.appendNewElement("div", el, `${His} indenture forbids elective surgery`, ["choices", "note"]);
				} else {
					linkArray = [];
					if (getLeftEyeVision(slave) === 2 && getLeftEyeType(slave) === 1) {
						linkArray.push(App.Medicine.Surgery.makeLink(
							new App.Medicine.Surgery.Procedures.EyeBlur(slave, "left"),
							refresh, cheat));
					}
					if (getRightEyeVision(slave) === 2 && getRightEyeType(slave) === 1) {
						linkArray.push(App.Medicine.Surgery.makeLink(
							new App.Medicine.Surgery.Procedures.EyeBlur(slave, "right"),
							refresh, cheat));
					}
					if (linkArray.length === 2) {
						linkArray.push(App.Medicine.Surgery.makeLink(
							new App.Medicine.Surgery.Procedures.EyeBlur(slave, "both"),
							refresh, cheat));
					}
					App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices");
				}

				/* Fix eyes */
				linkArray = [];
				if (getLeftEyeVision(slave) === 1 && getLeftEyeType(slave) === 1) {
					linkArray.push(App.Medicine.Surgery.makeLink(
						new App.Medicine.Surgery.Procedures.EyeFix(slave, "left"),
						refresh, cheat));
				}
				if (getRightEyeVision(slave) === 1 && getRightEyeType(slave) === 1) {
					linkArray.push(App.Medicine.Surgery.makeLink(
						new App.Medicine.Surgery.Procedures.EyeFix(slave, "right"),
						refresh, cheat));
				}
				if (linkArray.length === 2) {
					linkArray.push(App.Medicine.Surgery.makeLink(
						new App.Medicine.Surgery.Procedures.EyeFix(slave, "both"),
						refresh, cheat));
				}
				App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices");
			}

			if (V.seeExtreme === 1) {
				if (slave.indentureRestrictions < 1) {
					/* blind */
					linkArray = [];
					if (getLeftEyeVision(slave) > 0 && getLeftEyeType(slave) === 1) {
						linkArray.push(App.Medicine.Surgery.makeLink(
							new App.Medicine.Surgery.Procedures.Blind(slave, "left"),
							refresh, cheat));
					}
					if (getRightEyeVision(slave) > 0 && getRightEyeType(slave) === 1) {
						linkArray.push(App.Medicine.Surgery.makeLink(
							new App.Medicine.Surgery.Procedures.Blind(slave, "right"),
							refresh, cheat));
					}
					if (linkArray.length === 2) {
						linkArray.push(App.Medicine.Surgery.makeLink(
							new App.Medicine.Surgery.Procedures.Blind(slave, "both"),
							refresh, cheat));
					}
					App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices");

					/* remove */
					linkArray = [];
					if (hasLeftEye(slave)) {
						linkArray.push(App.Medicine.Surgery.makeLink(
							new App.Medicine.Surgery.Procedures.RemoveEyes(slave, "left"),
							refresh, cheat));
					}
					if (hasRightEye(slave)) {
						linkArray.push(App.Medicine.Surgery.makeLink(
							new App.Medicine.Surgery.Procedures.RemoveEyes(slave, "right"),
							refresh, cheat));
					}
					if (linkArray.length === 2) {
						linkArray.push(App.Medicine.Surgery.makeLink(
							new App.Medicine.Surgery.Procedures.RemoveEyes(slave, "both"),
							refresh, cheat));
					}
					App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices");
					/* implant */
					if (isProstheticAvailable(slave, "ocular")) {
						linkArray = [];
						if (!hasLeftEye(slave)) {
							linkArray.push(makeLink(
								"Give left eye ocular implant",
								getBestVision(slave) > 0 ? "ocular implant" : "ocular implant for blind",
								() => {
									eyeSurgery(slave, "left", "cybernetic");
									surgeryDamage(slave, 5);
								}
							));
						}
						if (!hasRightEye(slave)) {
							linkArray.push(makeLink(
								"Give right eye ocular implant",
								getBestVision(slave) > 0 ? "ocular implant" : "ocular implant for blind",
								() => {
									eyeSurgery(slave, "right", "cybernetic");
									surgeryDamage(slave, 5);
								}
							));
						}
						if (linkArray.length === 2) {
							linkArray.push(makeLink(
								"Give both eyes ocular implants",
								getBestVision(slave) > 0 ? "ocular implant" : "ocular implant for blind",
								() => {
									eyeSurgery(slave, "both", "cybernetic");
									surgeryDamage(slave, 5);
								}
							));
						}
						App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices");
					}
				}
			}
			return el;
		}

		function ears() {
			const el = new DocumentFragment();
			const r = [];
			const linkArray = [];
			r.push(`${He} has`);
			if (slave.earShape === "normal") {
				r.push(`normal ears.`);
			} else if (slave.earShape === "damaged") {
				r.push(`damaged ears.`);
				linkArray.push(App.Medicine.Surgery.makeLink(
					new App.Medicine.Surgery.Procedures.EarRestore(slave),
					refresh, cheat));
			} else if (slave.earShape === "pointy") {
				r.push(`small elfin ears.`);
			} else if (slave.earShape === "elven") {
				r.push(`long elf ears.`);
			} else if (slave.earShape === "ushi") {
				r.push(`floppy cow ears.`);
			} else if (slave.earShape === "none") {
				r.push(`no ears.`);
			} else {
				r.push(`bugged ears. You done goofed. <span class="note">Report This</span>`);
			}
			App.Events.addNode(el, r, "div");

			if (slave.indentureRestrictions >= 2) {
				App.UI.DOM.appendNewElement("div", el, `${His} indenture forbids elective surgery`, ["choices", "note"]);
			} else {
				if (slave.earShape !== "normal" && slave.earShape !== "none") {
					linkArray.push(App.Medicine.Surgery.makeLink(
						new App.Medicine.Surgery.Procedures.EarRestore(slave),
						refresh, cheat));
				}

				if (slave.earShape !== "none" && V.seeExtreme === 1 && slave.indentureRestrictions < 1) {
					linkArray.push(App.Medicine.Surgery.makeLink(
						new App.Medicine.Surgery.Procedures.RemoveEars(slave),
						refresh, cheat));
				}
				if (slave.earShape !== "none") {
					if (slave.earShape !== "pointy") {
						if (slave.earShape !== "elven") {
							linkArray.push(App.Medicine.Surgery.makeLink(
								new App.Medicine.Surgery.Procedures.EarMinorReshape(slave, "small elfin", "pointy"),
								refresh, cheat));
						}
					}
					if (V.surgeryUpgrade === 1) {
						if (slave.earShape !== "elven") {
							linkArray.push(App.Medicine.Surgery.makeLink(
								new App.Medicine.Surgery.Procedures.EarMajorReshape(slave, "long elf", "elven"),
								refresh, cheat));
						}
						if (slave.earShape !== "ushi") {
							linkArray.push(App.Medicine.Surgery.makeLink(
								new App.Medicine.Surgery.Procedures.EarMajorReshape(slave, "bovine", "ushi"),
								refresh, cheat));
						}
					}
				}
			}
			App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices");
			return el;
		}

		function topEars() {
			const el = new DocumentFragment();
			const r = [];
			const linkArray = [];
			r.push(`${He} has`);
			if (slave.earT === "none") {
				if (slave.earShape !== "none") {
					r.push(`only one set of ears.`);
				} else {
					r.push(`no secondary ears.`);
				}
			} else if (slave.earT === "normal") {
				if (slave.earShape !== "none") {
					r.push(`a second pair of ears grafted to ${his} head.`);
				} else {
					r.push(`a pair of ears grafted to the top of ${his} head.`);
				}
			} else if (slave.earT === "neko") {
				r.push(`a pair of cat ears adorning ${his} head.`);
			} else if (slave.earT === "inu") {
				r.push(`a pair of dog ears adorning ${his} head.`);
			} else if (slave.earT === "kit") {
				r.push(`a pair of fox ears adorning ${his} head.`);
			} else if (slave.earT === "tanuki") {
				r.push(`a pair of tanuki ears adorning ${his} head.`);
			} else if (slave.earT === "usagi") {
				r.push(`a pair of rabbit ears adorning ${his} head.`);
			} else {
				r.push(`You done goofed.`);
				r.push(`<span class="note">Report This</span>`);
			}
			if (slave.indentureRestrictions >= 2) {
				App.UI.DOM.appendNewElement("div", el, `${His} indenture forbids elective surgery`, ["choices", "note"]);
			} else {
				if (slave.earT !== "none") {
					if (V.seeExtreme === 1 && slave.indentureRestrictions < 1) {
						linkArray.push(App.Medicine.Surgery.makeLink(
							new App.Medicine.Surgery.Procedures.RemoveTopEars(slave),
							refresh, cheat));
					}
					if (slave.earT !== "neko") {
						linkArray.push(App.Medicine.Surgery.makeLink(
							new App.Medicine.Surgery.Procedures.TopEarReshape(slave, "cat", "neko"),
							refresh, cheat));
					}
					if (slave.earT !== "inu") {
						linkArray.push(App.Medicine.Surgery.makeLink(
							new App.Medicine.Surgery.Procedures.TopEarReshape(slave, "dog", "inu"),
							refresh, cheat));
					}
					if (slave.earT !== "kit") {
						linkArray.push(App.Medicine.Surgery.makeLink(
							new App.Medicine.Surgery.Procedures.TopEarReshape(slave, "fox", "kit"),
							refresh, cheat));
					}
					if (slave.earT !== "tanuki") {
						linkArray.push(App.Medicine.Surgery.makeLink(
							new App.Medicine.Surgery.Procedures.TopEarReshape(slave, "tanuki", "tanuki"),
							refresh, cheat));
					}
					if (slave.earT !== "usagi") {
						linkArray.push(App.Medicine.Surgery.makeLink(
							new App.Medicine.Surgery.Procedures.TopEarReshape(slave, "rabbit", "usagi"),
							refresh, cheat));
					}
					if (slave.earTColor === "hairless") {
						r.push(`They are completely bald.`);
						linkArray.push(App.Medicine.Surgery.makeLink(
							new App.Medicine.Surgery.Procedures.TopEarsImplantHair(slave),
							refresh, cheat));
					} else {
						r.push(`They are covered by a multitude of implanted ${slave.earTColor} fibers mimicking hair.`);
						linkArray.push(App.Medicine.Surgery.makeLink(
							new App.Medicine.Surgery.Procedures.TopEarsRemoveHair(slave),
							refresh, cheat));
					}
				}
			}
			App.Events.addNode(el, r, "div");
			App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices");
			return el;
		}

		function hearing() {
			const el = new DocumentFragment();
			const r = [];
			const linkArray = [];

			if (slave.earImplant === 1) {
				r.push(`${He} has cochlear implants.`);
			} else if (slave.hears <= -2) {
				r.push(`${He} is deaf.`);
			} else {
				r.push(`${He} has working`);
				if (slave.hears === -1) {
					r.push(`inner ears, but is hearing impaired${(slave.earShape === "none") ? `, likely due to missing the outer structure` : ``}.`);
				} else {
					r.push(`ears and good hearing.`);
				}
			}
			App.Events.addNode(el, r, "div");

			if (slave.earImplant !== 1) {
				if (slave.hears === -1) {
					if (slave.earImplant !== 1 && slave.earShape !== "none") {
						linkArray.push(App.Medicine.Surgery.makeLink(
							new App.Medicine.Surgery.Procedures.EarFix(slave),
							refresh, cheat));
					}
				} else if (slave.hears === 0) {
					if (V.seeExtreme === 1 && slave.earImplant !== 1 && slave.indentureRestrictions < 1) {
						linkArray.push(App.Medicine.Surgery.makeLink(
							new App.Medicine.Surgery.Procedures.EarMuffle(slave),
							refresh, cheat));
					}
				}
			}

			if (V.seeExtreme === 1 && slave.indentureRestrictions < 1) {
				if (slave.earImplant === 0) {
					if (slave.hears > -2) {
						linkArray.push(App.Medicine.Surgery.makeLink(
							new App.Medicine.Surgery.Procedures.Deafen(slave),
							refresh, cheat));
					}
					if (isProstheticAvailable(slave, "cochlear")) {
						linkArray.push(App.Medicine.Surgery.makeLink(
							new App.Medicine.Surgery.Procedures.CochlearImplant(slave),
							refresh, cheat));
					}
				}
			}
			App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices");
			return el;
		}

		function horns() {
			const el = new DocumentFragment();
			const r = [];
			const linkArray = [];
			r.push(`${He} has`);
			if (slave.horn === "none") {
				r.push(`no horns.`);
			} else {
				r.push(`${slave.horn}.`);
			}
			App.Events.addNode(el, r, "div");

			if (slave.indentureRestrictions >= 2) {
				App.UI.DOM.appendNewElement("div", el, `${His} indenture forbids elective surgery`, ["choices", "note"]);
			} else if (slave.horn === "none") {
				linkArray.push(makeLink(
					"Succubus horns",
					"horn",
					() => {
						slave.horn = "curved succubus horns";
						slave.hornColor = "jet black";
						surgeryDamage(slave, 10);
					}
				));
				linkArray.push(makeLink(
					"Backswept horns",
					"horn",
					() => {
						slave.horn = "backswept horns";
						slave.hornColor = "jet black";
						surgeryDamage(slave, 10);
					}
				));
				linkArray.push(makeLink(
					"Bovine horns",
					"horn",
					() => {
						slave.horn = "cow horns";
						slave.hornColor = "ivory";
						surgeryDamage(slave, 10);
					}
				));
				linkArray.push(makeLink(
					"One oni horn",
					"horn",
					() => {
						slave.horn = "one long oni horn";
						slave.hornColor = slave.skin;
						surgeryDamage(slave, 10);
					}
				));
				linkArray.push(makeLink(
					"Two oni horns",
					"horn",
					() => {
						slave.horn = "two long oni horns";
						slave.hornColor = slave.skin;
						surgeryDamage(slave, 10);
					}
				));
				linkArray.push(makeLink(
					"Small horns",
					"horn",
					() => {
						slave.horn = "small horns";
						slave.hornColor = "ivory";
						surgeryDamage(slave, 10);
					}
				));
			} else if (slave.horn !== "one long oni horn") {
				linkArray.push(makeLink(
					"Remove them",
					"hornGone",
					() => {
						surgeryAmp(slave, "horn");
					}
				));
			} else {
				linkArray.push(makeLink(
					"Remove it",
					"hornGone",
					() => {
						surgeryAmp(slave, "horn");
					}
				));
			}
			App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices");
			return el;
		}

		function lips() {
			const el = new DocumentFragment();
			const r = [];
			const linkArray = [];
			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 hole for cock.`);
			}
			if (slave.lipsImplant > 20) {
				r.push(`${He} has enormous lip implants.`);
			} else if (slave.lipsImplant > 10) {
				r.push(`${He} has large lip implants.`);
			} else if (slave.lipsImplant > 0) {
				r.push(`${He} has moderate lip implants.`);
			}
			r.push(App.UI.DOM.makeElement("span", `New implants will reduce ${his} oral skills`, "note"));
			App.Events.addNode(el, r, "div");

			if (slave.indentureRestrictions >= 2) {
				App.UI.DOM.appendNewElement("div", el, `${His} indenture forbids elective surgery`, ["choices", "note"]);
			} else if ((slave.lips <= 75) || ((slave.lips <= 95) && (V.seeExtreme === 1))) {
				if (slave.lipsImplant > 0) {
					linkArray.push(makeLink(
						"Replace with the next size up",
						"lips",
						() => {
							slave.lipsImplant += 20;
							slave.lips += 20;
							surgeryDamage(slave, 10);
						}
					));
				} else {
					linkArray.push(makeLink(
						"Lip implant",
						"lips",
						() => {
							slave.lipsImplant = 20;
							slave.lips += 20;
							surgeryDamage(slave, 10);
						}
					));
				}
			}
			if (slave.lipsImplant !== 0) {
				if (slave.indentureRestrictions < 2) {
					linkArray.push(makeLink(
						"Remove lip implants",
						"lips",
						() => {
							surgeryAmp(slave, "lips");
						}
					));
				}
			}
			if (slave.lips >= 10 && slave.lipsImplant === 0) {
				if (slave.indentureRestrictions < 2) {
					linkArray.push(makeLink(
						"Reduce lips",
						"lips",
						() => {
							slave.lips -= 10;
							surgeryDamage(slave, 10);
						}
					));
				}
			}
			App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices");
			return el;
		}

		function teeth() {
			const el = new DocumentFragment();
			const r = [];
			const linkArray = [];
			switch (slave.teeth) {
				case "crooked":
					r.push(`${He} has crooked teeth.`);
					linkArray.push(makeLink(
						"Apply braces",
						"braces",
						() => {
							slave.teeth = "straightening braces";
						}
					));
					break;
				case "gapped":
					r.push(`${He} has a noticeable gap in ${his} front teeth.`);
					linkArray.push(makeLink(
						"Apply braces",
						"braces",
						() => {
							slave.teeth = "straightening braces";
						}
					));
					break;
				case "straightening braces":
					r.push(`${His} crooked teeth are in braces.`);
					linkArray.push(makeLink(
						"Remove braces",
						"removeBraces",
						() => {
							slave.teeth = "crooked";
						},
						0
					));
					break;
				case "cosmetic braces":
					r.push(`${He} has braces on ${his} straight teeth.`);
					linkArray.push(makeLink(
						"Remove braces",
						"removeCosmeticBraces",
						() => {
							slave.teeth = "normal";
						},
						0
					));
					break;
				case "removable":
					r.push(`${He} has prosthetic teeth that can be removed for extreme oral sex.`);
					break;
				case "pointy":
					r.push(`${His} teeth have been replaced with sturdy, realistic implants that mimic the dentition of a predator.`);
					if (V.seeExtreme === 1 && slave.indentureRestrictions < 1) {
						linkArray.push(makeLink(
							"Normal dental implants",
							"oral",
							() => {
								slave.teeth = "normal";
								surgeryDamage(slave, 10);
							}
						));
					}
					break;
				case "fangs":
					r.push(`${His} upper canines have been replaced with sturdy, realistic implants that can only be described as vampiric.`);
					if (V.seeExtreme === 1 && slave.indentureRestrictions < 1) {
						linkArray.push(makeLink(
							"Remove a fang",
							"fang",
							() => {
								slave.teeth = "fang";
								surgeryDamage(slave, 20);
							}
						));
						linkArray.push(makeLink(
							"Normal dental implants",
							"oral",
							() => {
								slave.teeth = "normal";
								surgeryDamage(slave, 10);
							}
						));
					}
					break;
				case "fang":
					r.push(`A single one of ${his} upper canines has been replaced with a sturdy, realistic implant shaped like a fang.`);
					if (slave.lips <= 50) {
						r.push(`It is occasionally visible over ${his} lower lip.`);
					}
					if (V.seeExtreme === 1 && slave.indentureRestrictions < 1) {
						linkArray.push(makeLink(
							"Replace them with removable prosthetics",
							"teeth",
							() => {
								slave.teeth = "removable";
								surgeryDamage(slave, 20);
							}
						));
						linkArray.push(makeLink(
							"Add another fang",
							"fangs",
							() => {
								slave.teeth = "fangs";
							}
						));
						linkArray.push(makeLink(
							"Normal dental implants",
							"oral",
							() => {
								slave.teeth = "normal";
								surgeryDamage(slave, 10);
							}
						));
					}
					break;
				case "baby":
					r.push(`${He} has baby teeth.`);
					if (V.seeExtreme === 1 && slave.indentureRestrictions < 1) {
						linkArray.push(makeLink(
							"Normal dental implants",
							"oral",
							() => {
								slave.teeth = "normal";
								surgeryDamage(slave, 10);
							}
						));
					}
					break;
				case "mixed":
					r.push(`${He} has a mix of baby and normal teeth.`);
					break;
				default:
					r.push(`${He} has normal, healthy teeth.`);
					linkArray.push(makeLink(
						"Unnecessary braces",
						"braces",
						() => {
							slave.teeth = "cosmetic braces";
						}
					));
					if (V.seeExtreme === 1 && slave.indentureRestrictions < 1) {
						linkArray.push(makeLink(
							"Add a fang",
							"fang",
							() => {
								slave.teeth = "fang";
							}
						));
					}
			}
			if (V.seeExtreme === 1 && slave.indentureRestrictions < 1) {
				if (slave.teeth !== "removable") {
					linkArray.push(makeLink(
						"Replace them with removable prosthetics",
						"teeth",
						() => {
							slave.teeth = "removable";
							surgeryDamage(slave, 20);
						}
					));
				}

				if (slave.teeth !== "pointy") {
					linkArray.push(makeLink(
						"Replace them with sharp teeth",
						"sharp",
						() => {
							slave.teeth = "pointy";
							surgeryDamage(slave, 20);
						}
					));
				}

				if (slave.teeth !== "fangs" && slave.teeth !== "fang") {
					linkArray.push(makeLink(
						"Replace them with fangs",
						"fangs",
						() => {
							slave.teeth = "fangs";
							surgeryDamage(slave, 20);
						}
					));
				}
			}
			App.Events.addNode(el, r, "div");
			App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices");
			return el;
		}

		function voice() {
			const el = new DocumentFragment();
			const r = [];
			if (slave.electrolarynx === 1) {
				r.push(`${He} has an artificial larynx.`);
			} else {
				if (slave.voice === 0) {
					r.push(`${He} is mute.`);
				} else if (slave.voice === 1) {
					r.push(`${He} has a deep voice.`);
				} else if (slave.voice === 2) {
					r.push(`${He} has a feminine voice.`);
				} else if (slave.voice === 3) {
					r.push(`${He} has a high, girly voice.`);
				}
				if (slave.voiceImplant >= 1) {
					r.push(`${He} has had surgery on ${his} voice box to raise ${his} voice.`);
				} else if (slave.voiceImplant <= -1) {
					r.push(`${He} has had surgery on ${his} voice box to lower ${his} voice.`);
				}
			}
			App.Events.addNode(el, r, "div");
			if (slave.indentureRestrictions < 1 && slave.electrolarynx !== 1) {
				const linkArray = [];
				if (slave.voice !== 0) {
					if (slave.voice < 3) {
						linkArray.push(makeLink(
							"Perform surgery to raise voice",
							"voice",
							() => {
								slave.voice += 1;
								slave.voiceImplant += 1;
								surgeryDamage(slave, 10);
							}
						));
					}
					if (slave.voice > 1) {
						linkArray.push(makeLink(
							"Perform surgery to lower voice",
							"voice2",
							() => {
								slave.voice -= 1;
								slave.voiceImplant -= 1;
								surgeryDamage(slave, 10);
							}
						));
					}
					if (V.seeExtreme === 1) {
						linkArray.push(makeLink(
							"Remove vocal cords",
							"mute",
							() => {
								surgeryAmp(slave, "voicebox");
							}
						));
					}
				} else if (isProstheticAvailable(slave, "electrolarynx")) {
					linkArray.push(makeLink(
						`Give ${him} an electrolarynx`,
						"electrolarynx",
						() => {
							slave.electrolarynx = 1;
							slave.voice = 2;
							surgeryDamage(slave, 20);
						}
					));
				}
				App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices");
			}
			return el;
		}

		function chemosensory() {
			const el = new DocumentFragment();
			const r = [];
			if (slave.smells === 0 && slave.tastes === 0) {
				r.push(`${He} has a working chemosensory system.`);
			} else if (slave.smells === 0) {
				r.push(`${He} has a working olfactory system and an impaired gustatory system.`);
			} else if (slave.tastes === 0) {
				r.push(`${He} has a working gustatory system and an impaired olfactory system.`);
			} else {
				r.push(`${He} has an impaired chemosensory system.`);
			}
			App.Events.addNode(el, r, "div");
			if (slave.indentureRestrictions < 1) {
				const linkArray = [];
				if (slave.smells === 0 && V.seeExtreme === 1) {
					linkArray.push(makeLink(
						"Remove sense of smell",
						"desmell",
						() => {
							slave.smells = -1;
							surgeryDamage(slave, 10);
						}
					));
				} else if (slave.smells === -1) {
					linkArray.push(makeLink(
						"Repair sense of smell",
						"resmell",
						() => {
							slave.smells = 0;
							surgeryDamage(slave, 10);
						}
					));
				}
				if (slave.tastes === 0 && V.seeExtreme === 1) {
					linkArray.push(makeLink(
						"Remove sense of taste",
						"detaste",
						() => {
							slave.tastes = -1;
							surgeryDamage(slave, 10);
						}
					));
				} else if (slave.tastes === -1) {
					linkArray.push(makeLink(
						"Repair sense of taste",
						"retaste",
						() => {
							slave.tastes = 0;
							surgeryDamage(slave, 10);
						}
					));
				}
				App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices");
			}
			return el;
		}
	}

	/**
	 *
	 * @param {string} title
	 * @param {string} surgeryType
	 * @param {function(void):void} [func]
	 * @param {number} [costMult=1]
	 * @returns {HTMLAnchorElement}
	 */
	function makeLink(title, surgeryType, func, costMult = 1) {
		const cost = Math.trunc(V.surgeryCost * costMult);
		return App.UI.DOM.link(
			title,
			() => {
				if (typeof func === "function") {
					func();
				}
				if (cheat) {
					refresh();
				} else {
					V.surgeryType = surgeryType;
					// TODO: pass if it affected health or not?
					cashX(forceNeg(cost), "slaveSurgery", slave);
					Engine.play("Surgery Degradation");
				}
			},
			[],
			"",
			`Costs ${cashFormat(cost)}`
		);
	}

	function refresh() {
		jQuery(container).empty().append(content());
		App.Events.refreshEventArt(slave);
		refreshParent();
	}
};


code:
/**
 * UI for performing surgery. Refreshes without refreshing the passage.
 * @param {App.Entity.SlaveState} slave
 * @param {()=>void} refreshParent
 * @param {boolean} [cheat=false]
 * @returns {HTMLElement}
 */
App.UI.surgeryPassageLower = function(slave, refreshParent, cheat = false) {
	const container = document.createElement("span");
	container.append(content());
	return container;

	function content() {
		const frag = new DocumentFragment();
		// const pubertyAge = Math.min(slave.pubertyAgeXX, slave.pubertyAgeXY);
		const {
			His, He,
			his, he, him
		} = getPronouns(slave);
		// const artificiality = 25 - (5 * Math.trunc(V.PC.skill.medicine / 50)) - (5 * V.surgeryUpgrade);

		App.UI.DOM.appendNewElement("h3", frag, `Butt:`);
		frag.append(butt(), asshole());

		App.UI.DOM.appendNewElement("h3", frag, `Sex:`);
		frag.append(labia(), fertility(), sexDescription(), extraSex());
		if (slave.balls > 0) {
			frag.append(balls());
		}
		frag.append(prostate());

		return frag;

		function butt() {
			const el = new DocumentFragment();
			const r = [];
			r.push(`${He}'s got a`);
			if (slave.butt <= 1) {
				r.push(`flat and ${either("skinny", "slim", "taut")} ass.`);
			} else if (slave.butt <= 2) {
				r.push(`${either("rounded, small", "small but rounded", "small, sleek")} rear end.`);
			} else if (slave.butt <= 3) {
				r.push(`${either("big and healthy", "curved and plump", "healthy and plump")} derrière.`);
			} else if (slave.butt <= 4) {
				r.push(`${either("big bubble", "curvy and enticing", "juicy and large")} butt.`);
			} else if (slave.butt <= 5) {
				r.push(`${either("huge", "juicy and huge", "massive and undeniable")} rear end.`);
			} else if (!hasBothLegs(slave)) {
				r.push(`ridiculous ass. It's so big it would jiggle as ${he} walked — if ${he} could walk.`);
			} else {
				r.push(`ridiculous ass. It's so big it jiggles as ${he} walks.`);
			}

			if (slave.buttImplant > 0) {
				r.push(`${He} has`);
				if (slave.buttImplantType === "string") {
					if (slave.buttImplant > 2) {
						r.push(`massively engorged`);
					}
				} else if (slave.buttImplantType === "normal") {
					if (slave.buttImplant === 1) {
						r.push(`moderate`);
					} else if (slave.buttImplant === 2) {
						r.push(`enormous`);
					} else {
						r.push(`absurd`);
					}
				} else if (slave.buttImplantType === "hyper fillable") {
					if (slave.buttImplant > 19) {
						r.push(`overfilled`);
					} else if (slave.buttImplant < 9) {
						r.push(`underfilled`);
					} else if (slave.buttImplant <= 5) {
						r.push(`deflated`);
					} else {
						r.push(`absurd`);
					}
				} else if (slave.buttImplantType === "advanced fillable") {
					if (slave.buttImplant > 8) {
						r.push(`overfilled`);
					} else if (slave.buttImplant < 5) {
						r.push(`underfilled`);
					} else if (slave.buttImplant <= 3) {
						r.push(`deflated`);
					} else {
						r.push(`massive`);
					}
				} else if (slave.buttImplantType === "fillable") {
					if (slave.buttImplant > 4) {
						r.push(`overfilled`);
					} else if (slave.buttImplant < 3) {
						r.push(`underfilled`);
					} else if (slave.buttImplant === 1) {
						r.push(`deflated`);
					} else {
						r.push(`massive`);
					}
				}
				if (slave.buttImplantType !== "normal") {
					r.push(`${slave.buttImplantType}`);
				}
				r.push(`butt implants.`);
				if (slave.buttImplant > 3 && slave.buttImplantType === "string") {
					r.push(App.UI.DOM.makeElement("span", "Large string based implants are a risk to a slave's health.", "yellow"));
				}
			}
			App.Events.addNode(el, r, "div");

			const surgeries = App.Medicine.Surgery.sizingProcedures.butt(slave, App.Medicine.Surgery.allSizingOptions());
			const surgeryLinks = surgeries.map(s => App.Medicine.Surgery.makeLink(s, refresh, cheat));
			App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(surgeryLinks), "choices");
			return el;
		}

		function asshole() {
			const el = new DocumentFragment();
			const r = [];
			const linkArray = [];
			r.push(`${He} has`);
			if (slave.anus === 0) {
				r.push(`a virgin asshole.`);
			} else if (slave.anus === 1) {
				r.push(`a tight asshole.`);
			} else if (slave.anus === 2) {
				r.push(`a loose asshole.`);
			} else if (slave.anus === 3) {
				r.push(`a very loose asshole.`);
			} else {
				r.push(`a permanently gaping asshole.`);
			}
			if (slave.anus > 3) {
				r.push(`${His} anal sphincter could benefit from surgical repair.`);
				linkArray.push(makeLink(
					"Repair asshole",
					"anus",
					() => {
						slave.anus = 3;
						surgeryDamage(slave, 10);
					},
					1,
					`This will reduce ${his} anal skills`
				));
			} else if (V.surgeryUpgrade === 1 && slave.indentureRestrictions < 2) {
				if (slave.anus > 1) {
					r.push(`${His} anal sphincter could benefit from microsurgical rejuvenation.`);
					linkArray.push(makeLink(
						"Tighten asshole",
						"anus",
						() => {
							slave.anus = 1;
							surgeryDamage(slave, 10);
						},
						1,
						`This will reduce ${his} anal skills`
					));
				} else if (slave.anus > 0) {
					r.push(`${His} butthole is fairly narrow, but could be tightened to virgin status.`);
					linkArray.push(makeLink(
						"Restore anal virginity",
						"anus",
						() => {
							slave.anus = 0;
							surgeryDamage(slave, 10);
						},
						1,
						`This will reduce ${his} anal skills`
					));
				}
			}

			App.Events.addNode(el, r, "div");
			App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices");
			return el;
		}

		function labia() {
			const el = new DocumentFragment();
			let r = [];
			let linkArray = [];
			if (slave.vagina > -1) {
				if (slave.labia === 0) {
					r.push(`${He} has minimal pussylips.`);
				} else if (slave.labia === 1) {
					r.push(`${He} has pretty, noticeable pussylips.`);
				} else if (slave.labia === 2) {
					r.push(`${He} has large pussylips.`);
				} else if (slave.labia > 2) {
					r.push(`${He} has extremely large pussylips.`);
				}
				if (slave.labia > 0) {
					if (slave.indentureRestrictions < 2) {
						linkArray.push(makeLink(
							"Apply labiaplasty",
							"labiaplasty",
							() => {
								slave.labia = 0;
								surgeryDamage(slave, 10);
							}
						));
					}
				}
				if (slave.labia < 3 && V.surgeryUpgrade === 1) {
					if (slave.indentureRestrictions < 1) {
						linkArray.push(makeLink(
							"Increase labia",
							"labiaplasty",
							() => {
								slave.labia += 1;
								surgeryDamage(slave, 10);
							}
						));
					}
				}
				App.Events.addNode(el, r, "div");
				App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices");
				if (slave.dick === 0) {
					r = [];
					linkArray = [];
					r.push(`${He} has`);
					if (slave.clit === 0) {
						r.push(`a small clit`);
					} else if (slave.clit === 1) {
						r.push(`a big clit`);
					} else if (slave.clit === 2) {
						r.push(`a huge clit`);
					} else if (slave.clit > 2) {
						r.push(`an enormous clit`);
					}
					if (V.seeCircumcision === 1 && slave.foreskin > 0) {
						r.push(`with a hood.`);
					} else {
						r.push(r.pop() + `.`);
					}

					if (slave.clit > 0) {
						if (slave.indentureRestrictions < 2) {
							linkArray.push(makeLink(
								"Apply clitoral reduction",
								"clitoral reduction",
								() => {
									slave.clit = 0;
									surgeryDamage(slave, 10);
								}
							));
						}
					}
					if (slave.clit < 3 && V.surgeryUpgrade === 1) {
						if (slave.indentureRestrictions < 1) {
							linkArray.push(makeLink(
								"Increase clit",
								"clitoral enlargement",
								() => {
									slave.clit += 1;
									surgeryDamage(slave, 10);
								}
							));
						}
					}
					if (slave.foreskin > 0 && slave.clit > 0) {
						if (V.seeCircumcision === 1) {
							if (slave.indentureRestrictions < 2) {
								linkArray.push(makeLink(
									"Remove clitoral hood",
									"circumcision",
									() => {
										slave.foreskin = 0;
										surgeryDamage(slave, 10);
									}
								));
							}
						}
					}
					App.Events.addNode(el, r, "div");
					App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices");
				}
			}
			return el;
		}

		function fertility() {
			const el = new DocumentFragment();
			let r = [];
			let linkArray = [];

			if (slave.preg > -2 && slave.preg < 1 && (slave.ovaries !== 0 || slave.mpreg !== 0) && slave.pubertyXX === 0) {
				r.push(`${He} has not had ${his} first period.`);
			} else if (slave.preg > -2 && slave.preg < 1 && (slave.ovaries !== 0 || slave.mpreg !== 0)) {
				r.push(`${He} has a working womb.`);
			} else if (slave.preg <= -2 && (slave.ovaries !== 0 || slave.mpreg !== 0)) {
				r.push(`${He} has a sterile womb.`);
			}

			if (isFertile(slave) && slave.preg === 0) {
				linkArray.push(
					App.UI.DOM.passageLink(
						"Artificially inseminate",
						"Artificial Insemination"
					)
				);
			}

			if (slave.ovaries !== 0 || slave.mpreg !== 0) {
				if (slave.preg > -2 && slave.preg < 1) {
					if (slave.indentureRestrictions < 1 && (slave.breedingMark !== 1 || V.propOutcome === 0 || V.eugenicsFullControl === 1 || V.arcologies[0].FSRestart === "unset")) {
						linkArray.push(makeLink(
							"Sterilize",
							"ster",
							() => {
								slave.preg = -2;
								surgeryDamage(slave, 10);
							}
						));
					}
				} else if (slave.preg === -2) {
					linkArray.push(makeLink(
						"Restore fertility",
						"fert",
						() => {
							slave.preg = 0;
							surgeryDamage(slave, 10);
						}
					));
				}
			}

			App.Events.addNode(el, r, "div");
			App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices");
			if (slave.ovaries === 1 || slave.mpreg === 1) {
				r = [];
				linkArray = [];
				if (slave.pubertyXX === 0) {
					r.push(`${He} has`);
					if (slave.eggType !== "human") {
						r.push(slave.eggType);
					}
					r.push(`ovaries but has not had ${his} first period.`);
				} else {
					r.push(`${He} has working`);
					if (slave.eggType !== "human") {
						r.push(slave.eggType);
					}
					r.push(`ovaries${(slave.mpreg) ? ` and a womb attached to ${his} rectum` : ``}.`);
				}

				if (slave.indentureRestrictions > 0) {
					App.UI.DOM.appendNewElement("div", el, `${His} indenture forbids elective surgery`, ["choices", "note"]);
				} else {
					if (slave.ovaImplant !== 0) {
						switch (slave.ovaImplant) {
							case "fertility":
								r.push(`They have fertility implants attached to them.`);
								linkArray.push(makeLink(
									"Remove implants",
									"ovaImplant changed",
									() => {
										slave.ovaImplant = 0;
										surgeryDamage(slave, 10);
									}
								));
								break;
							case "sympathy":
								r.push(`They are linked via implants and ovulate in concert.`);
								linkArray.push(makeLink(
									"Remove implants",
									"ovaImplant changed",
									() => {
										slave.ovaImplant = 0;
										surgeryDamage(slave, 10);
									}
								));
								break;
							case "asexual":
								r.push(`One has been replaced with a sperm producing analog for self-fertilization.`);
						}
					} else {
						if (V.fertilityImplant === 1) {
							linkArray.push(makeLink(
								"Install fertility implants",
								"ovaImplant changed",
								() => {
									slave.ovaImplant = "fertility";
									surgeryDamage(slave, 10);
								}
							));
						}
						if (V.sympatheticOvaries === 1) {
							linkArray.push(makeLink(
								"Install sympathetic ovulation implants",
								"ovaImplant changed",
								() => {
									slave.ovaImplant = "sympathy";
									surgeryDamage(slave, 10);
								}
							));
						}
					}
					App.Events.addNode(el, r, "div");
					App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices");
				}

				if (slave.indentureRestrictions < 1 && (slave.breedingMark !== 1 || V.propOutcome === 0 || V.eugenicsFullControl === 1 || V.arcologies[0].FSRestart === "unset")) {
					r = [];
					linkArray = [];
					if (slave.ovaries === 1) {
						if (slave.preg > 0) {
							linkArray.push(
								App.UI.DOM.disabledLink(
									"Oophorectomy",
									[`${His} ovaries and womb cannot be removed while ${he} is pregnant.`]
								)
							);
						} else {
							linkArray.push(makeLink(
								"Oophorectomy",
								"ster",
								() => {
									slave.ovaries = 0;
									slave.ovaImplant = 0;
									slave.wombImplant = "none";
									surgeryDamage(slave, 10);
								}
							));
						}
					}
					if (slave.mpreg === 1) {
						if (slave.preg > 0) {
							linkArray.push(
								App.UI.DOM.disabledLink(
									"Remove anal reproductive organs",
									[`${His} anal womb cannot be removed while ${he} is pregnant.`]
								)
							);
						} else {
							linkArray.push(makeLink(
								"Remove anal reproductive organs",
								"mpreg removed",
								() => {
									slave.mpreg = 0;
									slave.ovaImplant = 0;
									slave.wombImplant = "none";
									surgeryDamage(slave, 30);
								}
							));
						}
					}
					App.Events.addNode(el, r, "div");
					App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices");
				}

				if (V.seeExtreme === 1 && V.seeHyperPreg === 1 && V.seePreg !== 0 && V.permaPregImplant === 1) {
					r = [];
					linkArray = [];
					if (slave.assignment === "work in the dairy" && V.dairyPregSetting > 0) {
						r.push(`${His} womb is already rented out for the production of calves.`);
					} else if (slave.broodmother > 0) {
						r.push(`${He} has been made into a`);
						if (slave.broodmother > 1) {
							r.push(`hyper-`);
						}
						r.push(`broodmother.`);
						if (slave.womb.length === 0) {
							linkArray.push(makeLink(
								"Remove the pregnancy generator",
								"pregRemove",
								() => {
									slave.preg = 0;
									slave.pregWeek = -1;
									slave.pregSource = 0;
									slave.pregKnown = 0;
									slave.pregType = 0;
									slave.broodmother = 0;
									slave.broodmotherFetuses = 0;
									slave.broodmotherOnHold = 0;
									slave.pregControl = "none";
									surgeryDamage(slave, 10);
								}
							));
						} else {
							r.push(`${He} is pregnant right now, so ${his} broodmother implant can't be safely extracted.`);
							if (slave.broodmother === 1 && slave.broodmotherFetuses === 1 && V.PGHack === 1) {
								// hack can be applied only one time, for type 1 broodmothers, and only if implant already present
								linkArray.push(makeLink(
									"Hack the pregnancy generator",
									"preg1hack",
									() => {
										slave.pregControl = "none";
										surgeryDamage(slave, 1); // Yes, in the TW, it was 1.
									},
									1,
									`This will trick the generator ova release logic, forcing it to release more than one ova each week. This is an untested override and can cause severe health problems.`
								));
							} else if (slave.broodmother === 1 && slave.broodmotherFetuses > 1) {
								r.push(`The implant firmware has already been adjusted.`);
							}
						}
					} else if (slave.indentureRestrictions > 0) {
						App.UI.DOM.appendNewElement("div", el, `${His} indenture forbids elective surgery`, ["choices", "note"]);
					} else if (slave.breedingMark === 1 && V.propOutcome === 1 && V.eugenicsFullControl !== 1 && V.arcologies[0].FSRestart !== "unset") {
						App.UI.DOM.appendNewElement("div", el, `${He} is protected from extreme surgery`, ["choices", "note"]);
					} else if (isFertile(slave) && slave.ovaryAge <= 46) {
						r.push(`${He} could be made into a broodmother.`);
						linkArray.push(makeLink(
							"Implant a pregnancy generator",
							"preg",
							() => {
								slave.preg = 1;
								slave.pregWeek = 1;
								slave.pregKnown = 1;
								slave.pregType = 1;
								slave.broodmother = 1;
								slave.broodmotherFetuses = 1;
								slave.pregControl = "none";
								surgeryDamage(slave, 10);
							},
							1,
							`This will have severe effects on ${his} health and mind`
						));
					} else {
						r.push(`${His} body cannot support being a broodmother.`);
					}
					App.Events.addNode(el, r, "div");
					App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices");
				}
			}

			return el;
		}

		function sexDescription() {
			const el = new DocumentFragment();
			const r = [];
			const linkArray = [];
			if (slave.dick === 0 && slave.vagina === -1) {
				r.push(`${He} is a null, possessing neither penis nor vagina.`);
			} else if (slave.dick !== 0) {
				r.push(`${He} has`);
				if (V.seeCircumcision === 1) {
					if (slave.foreskin === 0) {
						r.push(`a circumcised`);
					} else if (slave.foreskin >= 1) {
						r.push(`an uncircumcised`);
					}
				} else {
					r.push(`a`);
				}
				if (slave.vagina === -1) {
					r.push(`penis.`);
				} else if (slave.ovaries !== 0) {
					r.push(`penis and a`);
				} else if (slave.vagina !== -1) {
					r.push(`penis and`);
					if (slave.genes === "XY") {
						r.push(`an artificial`);
					} else {
						r.push(`a`);
					}
				}
			} else if (slave.dick === 0) {
				r.push(`${He} has a`);
			}

			if (slave.vagina > -1) {
				if (slave.vagina === 0) {
					r.push(`virgin pussy.`);
				} else if (slave.vagina === 1) {
					r.push(`tight pussy.`);
				} else if (slave.vagina === 2) {
					r.push(`used pussy.`);
				} else if (slave.vagina === 3) {
					r.push(`loose pussy.`);
				} else if (slave.vagina === 10) {
					r.push(`ruined cunt.`);
				} else {
					r.push(`gaping cunt.`);
				}
			}

			if (slave.dick !== 0 && (slave.ovaries !== 0 || slave.vagina !== -1)) {
				r.push(`It's possible to remove either and leave ${him} sexually functional.`);
			}
			if (slave.vagina > -1) {
				if (slave.indentureRestrictions < 1 && (slave.breedingMark !== 1 || V.propOutcome === 0 || V.eugenicsFullControl === 1 || V.arcologies[0].FSRestart === "unset")) {
					linkArray.push(makeLink(
						"Remove pussy",
						"vaginaRemoval",
						() => {
							surgeryAmp(slave, "vagina");
						},
						1,
						(slave.ovaries === 1) ? `This will remove ${his} ovaries as well` : ""
					));
				}
			}

			if (slave.indentureRestrictions < 1 && (slave.breedingMark !== 1 || V.propOutcome === 0 || V.eugenicsFullControl === 1 || V.arcologies[0].FSRestart === "unset")) {
				if (slave.vagina === -1 && slave.dick !== 0) {
					linkArray.push(makeLink(
						"Convert genitalia to female",
						"mtf",
						() => {
							slave.dick = 0;
							slave.dickAccessory = "none";
							slave.chastityPenis = 0;
							slave.dickTat = 0;
							slave.foreskin = 0;
							slave.scrotum = 0;
							slave.balls = 0;
							slave.ballType = "human";
							slave.vasectomy = 0;
							slave.vagina = 0;
							slave.preg = -2;
							slave.skill.vaginal = 0;
							surgeryDamage(slave, 40);
						}
					));
				}
				if (slave.vagina === -1 && slave.dick === 0 && V.surgeryUpgrade === 1) {
					linkArray.push(makeLink(
						"Create a vagina",
						"ntf",
						() => {
							slave.vagina = 0;
							slave.skill.vaginal = 0;
							surgeryDamage(slave, 40);
						}
					));
				}
				if (slave.dick > 0 && V.seeExtreme === 1) {
					linkArray.push(makeLink(
						"Remove penis",
						"chop",
						() => {
							surgeryAmp(slave, "dick");
						}
					));
				}
				if (slave.foreskin > 0 && slave.dick > 0) {
					if (slave.indentureRestrictions < 2) {
						if (V.seeCircumcision === 1) {
							linkArray.push(makeLink(
								"Remove foreskin",
								"circumcision",
								() => {
									slave.foreskin = 0;
									surgeryDamage(slave, 10);
								}
							));
						}
						if (slave.foreskin - slave.dick > 0) {
							linkArray.push(makeLink(
								"Remove excess foreskin",
								"foreskinTuck",
								() => {
									slave.foreskin = slave.dick;
									surgeryDamage(slave, 5);
								}
							));
						}
					}
				}
			}

			if (slave.dick !== 0 && slave.vagina === -1 && V.surgeryUpgrade === 1) {
				if (slave.indentureRestrictions < 1) {
					linkArray.push(makeLink(
						"Create surgical hermaphrodite",
						"herm",
						() => {
							slave.vagina = 0;
							slave.skill.vaginal = 0;
							surgeryDamage(slave, 40);
						}
					));
				}
			}
			// </div>
			App.Events.addNode(el, r, "div");
			App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices");
			return el;
		}

		function extraSex() {
			const el = new DocumentFragment();
			const r = [];
			const linkArray = [];
			if (slave.vagina > 3) {
				r.push(`${His} vagina could benefit from surgical repair.`);
				linkArray.push(makeLink(
					"Repair pussy",
					"vagina",
					() => {
						slave.vagina = 3;
						surgeryDamage(slave, 10);
					},
					1,
					`This will reduce ${his} vaginal skills`
				));
			} else if (V.surgeryUpgrade === 1 && slave.indentureRestrictions < 2) {
				if (slave.vagina > 1) {
					r.push(`${His} vaginal muscles could benefit from microsurgical rejuvenation.`);
					linkArray.push(makeLink(
						"Tighten pussy",
						"vagina",
						() => {
							slave.vagina = 1;
							surgeryDamage(slave, 10);
						},
						1,
						`This will reduce ${his} vaginal skills`
					));
				} else if (slave.vagina > 0) {
					r.push(`${His} pussy is as tight as a virgin's, and ${his} hymen could be restored.`);
					linkArray.push(makeLink(
						"Restore virginity",
						"vagina",
						() => {
							slave.vagina = 0;
							surgeryDamage(slave, 10);
						},
						1,
						`This will reduce ${his} vaginal skills`
					));
				}
			}
			App.Events.addNode(el, r, "div");
			App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices");
			return el;
		}

		function balls() {
			const el = new DocumentFragment();
			const r = [];
			const linkArray = [];
			if (slave.balls === 1) {
				r.push(`${His} testicles are vestigial, but ${he} has balls. Technically. They are`);
			} else if (slave.balls > 1) {
				r.push(`${He} has testicles`);
			}
			if (slave.scrotum > 0) {
				r.push(`located in ${his} scrotum.`);
			} else {
				if (slave.genes === "XY") {
					r.push(`relocated inside ${his} abdomen, and ${his} scrotum has been removed.`);
				} else {
					r.push(`implanted inside ${his} abdomen.`);
				}
			}
			if (slave.scrotum > 0) {
				if (slave.indentureRestrictions < 2) {
					if (slave.scrotum - slave.balls > 0) {
						linkArray.push(makeLink(
							"Remove excess scrotal skin",
							"scrotalTuck",
							() => {
								slave.scrotum = slave.balls;
								surgeryDamage(slave, 5);
							}
						));
					}
				}
				if (slave.indentureRestrictions < 1) {
					linkArray.push(makeLink(
						"Move them inside abdomen and remove scrotum",
						"relocate",
						() => {
							slave.scrotum = 0;
							surgeryDamage(slave, 20);
						},
						1,
						`This will have a negative impact on cum production`
					));
				}
			}
			if (V.seeExtreme === 1) {
				linkArray.push(makeLink(
					"Geld",
					"geld",
					() => {
						slave.balls = 0;
						slave.ballType = "human";
						slave.scrotum = 0;
						slave.vasectomy = 0;
						surgeryDamage(slave, 40);
					}
				));
			}
			if (slave.ballType !== "sterile") {
				linkArray.push(makeLink(
					"Chemically castrate",
					"chem castrate",
					() => {
						slave.ballType = "sterile";
					}
				));
			}

			if (slave.vasectomy === 1) {
				r.push(`${He} has had a vasectomy and shoots blanks when ${he} cums${(slave.pubertyXY === 0 || slave.ballType === "sterile") ? `, or would, if ${he} were potent` : ``}.`);
				linkArray.push(makeLink(
					"Reverse vasectomy",
					"vasectomy undo",
					() => {
						slave.vasectomy = 0;
						surgeryDamage(slave, 10);
					}
				));
			} else {
				if (slave.ballType === "sterile") {
					r.push(`${He} has non-functional testicles.`);
					if (slave.indentureRestrictions < 1) {
						linkArray.push(makeLink(
							"Clamp vas deferens",
							"vasectomy",
							() => {
								slave.vasectomy = 1;
								surgeryDamage(slave, 10);
							}
						));
					}
				} else {
					r.push(`${He} has working testicles${(slave.pubertyXY === 0) ? `, though ${he} isn't potent` : ``}.`);
					if (slave.indentureRestrictions < 1) {
						linkArray.push(makeLink(
							"Clamp vas deferens to cull potency",
							"vasectomy",
							() => {
								slave.vasectomy = 1;
								surgeryDamage(slave, 10);
							}
						));
					}
				}
			}

			App.Events.addNode(el, r, "div");
			App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices");
			return el;
		}

		function prostate() {
			const el = new DocumentFragment();
			const r = [];
			const linkArray = [];
			if (slave.prostate) {
				r.push(`${He} has a`);
				if (slave.prostate > 2) {
					r.push(`hyperactive, ejaculation enhancing`);
				} else if (slave.prostate > 1) {
					r.push(`hyperactive`);
				} else {
					r.push(`normal`);
				}
				r.push(`prostate.`);
				if (slave.prostate >= 2 && V.prostateImplants === 1) {
					if (slave.prostate < 3) {
						if (slave.indentureRestrictions < 2) {
							linkArray.push(makeLink(
								"Implant prostate with an ejaculation boosting implant",
								"ejaculation",
								() => {
									slave.prostate = 3;
									surgeryDamage(slave, 20);
								},
								1,
								`This will thin ${his} ejaculate but greatly increase its quantity`
							));
						}
					}
					if (slave.prostate === 3) {
						linkArray.push(makeLink(
							"Remove ejaculation implant",
							"endejac",
							() => {
								slave.prostate = 2;
								surgeryDamage(slave, 10);
							}
						));
					} else if (slave.prostate === 2) {
						linkArray.push(makeLink(
							"Remove drug implant",
							"endprecum",
							() => {
								slave.prostate = 1;
							}
						));
					}
				} else {
					if (slave.prostate > 1) {
						linkArray.push(makeLink(
							"Remove drug implant",
							"endprecum",
							() => {
								slave.prostate = 1;
							}
						));
					}
					if (slave.prostate < 2) {
						if (slave.indentureRestrictions < 2) {
							linkArray.push(makeLink(
								"Implant slow-release productivity drugs",
								"precum",
								() => {
									slave.prostate = 2;
									surgeryDamage(slave, 10);
								},
								1,
								`This may cause some leaking`
							));
						}
					}
				}
				if (V.seeExtreme === 1) {
					if (slave.indentureRestrictions < 1) {
						linkArray.push(makeLink(
							"Remove prostate",
							"prostate",
							() => {
								slave.prostate = 0;
								surgeryDamage(slave, 40);
							}
						));
					}
				}
			}

			App.Events.addNode(el, r, "div");
			App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices");
			return el;
		}
	}

	/**
	 *
	 * @param {string} title
	 * @param {string} surgeryType
	 * @param {function(void):void} [func]
	 * @param {number} [costMult=1]
	 * @param {string} [note]
	 * @returns {HTMLAnchorElement}
	 */
	function makeLink(title, surgeryType, func, costMult = 1, note = "") {
		const cost = Math.trunc(V.surgeryCost * costMult);
		const tooltip = new DocumentFragment();
		App.UI.DOM.appendNewElement("div", tooltip, `Costs ${cashFormat(cost)}.`);
		if (note) {
			App.UI.DOM.appendNewElement("div", tooltip, note);
		}
		return App.UI.DOM.link(
			title,
			() => {
				if (typeof func === "function") {
					func();
				}
				if (cheat) {
					refresh();
				} else {
					V.surgeryType = surgeryType;
					// TODO: pass if it affected health or not?
					cashX(forceNeg(cost), "slaveSurgery", slave);
					Engine.play("Surgery Degradation");
				}
			},
			[],
			"",
			tooltip
		);
	}

	function refresh() {
		jQuery(container).empty().append(content());
		App.Events.refreshEventArt(slave);
		refreshParent();
	}
};