code:
App.StartingGirls.passage = function() {
	V.activeSlave = V.activeSlave || App.StartingGirls.generate();
	if (!jsDef(V.applyCareerBonus)) {
		V.applyCareerBonus = 1;
	}
	const el = new DocumentFragment();
	let r = [];
	let linkArray = [];
	if (V.slaves.length === 0) {
		r.push(`You're no stranger to the Free Cities, which means you're no stranger to slavery. If you wish, you can bring slaves from your past life with you to your arcology. You can spend your cash reserves on slaves here, or bring it with you to start the game. Slaves created here will be much cheaper than if they were purchased on the market.`);
		if (V.PC.dick !== 0 && V.PC.vagina !== -1 && (V.seeDicks !== 0 || V.makeDicks === 1)) {
			r.push(`Since you have both a penis and a vagina yourself, you've obviously had access to a source of advanced surgery and organ farming. Slaves get a smaller cost increase here for having both penises and vaginas, and for having both testicles and ovaries.`);
		}
		if (isPCCareerInCategory("slaver")) {
			r.push(`Since you`);
			if (V.PC.career === "slaver") {
				r.push(`personally saw to the capture, breaking and or training of`);
			} else if (V.PC.career === "slave overseer") {
				r.push(`managed the slave pits that processed`);
			} else if (V.PC.career === "slave tender") {
				r.push(`helped train`);
			}
			r.push(`these slaves, <span class="skill player">they cost half of what they normally would have here.</span>`);
		}
	} else {
		const pronoun = V.slaves.length > 1 ? "they" : getPronouns(V.slaves[0]).he;
		r.push(`The following slave records have been finalized; ${pronoun} will arrive with you when you take over your new arcology.`);
	}
	r.push(App.UI.DOM.makeElement("div", "Current cash reserves can be found on the far left sidebar."));
	App.Events.addNode(el, r, "p");
	if (V.slaves.length > 0) {
		for (const slave of V.slaves) {
			const cost = slave.slaveCost;
			App.Events.addNode(el, [
				App.UI.DOM.slaveDescriptionDialog(slave),
				`costing: ${cashFormatColor(cost)}`,
				App.UI.DOM.generateLinksStrip([
					App.UI.DOM.link("Delete", () => {
						cashX(Math.abs(cost), "slaveTransfer", slave);
						removeSlave(slave);
					}, [], "Starting Girls")
				])
			], "div");
		}
		App.Events.addNode(el, [], "p");
	}

	const headerLinks = App.UI.DOM.appendNewElement("div", el);
	linkArray.push(
		App.UI.DOM.makeElement(
			"span",
			App.UI.DOM.passageLink("Refresh", "Starting Girls"),
			["major-link"]
		)
	);
	linkArray.push(
		App.UI.DOM.link(
			"Randomize career",
			() => {
				V.activeSlave.career = randomCareer(V.activeSlave);
			},
			[],
			"Starting Girls"
		)
	);

	linkArray.push(
		App.UI.DOM.link(
			"Randomize name",
			() => {
				nationalityToName(V.activeSlave);
				V.activeSlave.slaveName = V.activeSlave.birthName;
			},
			[],
			"Starting Girls"
		)
	);

	class SlaveExporterImporter {
		constructor(textareaElement) {
			this.textareaToExportTo = textareaElement;
		}
		exportToTextarea(string) {
			this.textareaToExportTo.value = string;
		}
		exportActiveSlave() {
			this.textareaToExportTo.value = JSON.stringify(V.activeSlave);
		}
		importActiveSlave() {
			const slave = JSON.parse(this.textareaToExportTo.value);
			App.Update.Slave(slave);
			App.Entity.Utils.SlaveDataSchemeCleanup(slave);
			SlaveDatatypeCleanup(slave);
			removeJob(slave, slave.assignment);
			V.activeSlave = slave;
		}
	}
	const textareaElement = App.UI.DOM.appendNewElement("textarea", el, JSON.stringify(V.activeSlave, null, 2));
	const exporter = new SlaveExporterImporter(textareaElement);
	linkArray.push(
		App.UI.DOM.link(
			"Experimental: Export this slave",
			// exporter.exportActiveSlave.bind(exporter),
			// If this link reloads the page, like all the other links on this line,
			// then we need to set the textarea to V.activeSlave when the page loads
			// (because anything it's set to by this link will be overwritten),
			// and then there's no actual need for a function call at this link because the page reload will do it.
			() => {},
			[],
			// "Export Slave"
			"Starting Girls"
		)
	);
	linkArray.push(
		App.UI.DOM.link(
			"Experimental: Import this slave",
			exporter.importActiveSlave.bind(exporter),
			[],
			// "Import Slave"
			"Starting Girls"
		)
	);

	linkArray.push(
		App.UI.DOM.link(
			"Start over with a random slave",
			() => {
				V.activeSlave = App.StartingGirls.generate();
			},
			[],
			"Starting Girls"
		)
	);

	linkArray.push(
		App.UI.DOM.link(
			"Start over by selecting an archetype",
			() => {
				const el = new DocumentFragment();
				App.UI.DOM.appendNewElement("div", el, "Convenient combinations of slave attributes", "note");
				App.UI.DOM.appendNewElement("div", el, App.UI.DOM.link(
					"Irish Rose",
					() => {
						V.activeSlave = App.StartingGirls.generate({nationality: "Irish", race: "white"});
						V.activeSlave.eye.origColor = "green";
						V.activeSlave.origSkin = "fair";
						V.activeSlave.origHColor = "red";
						V.activeSlave.markings = "heavily freckled";
						V.activeSlave.face = 55;
					},
					[],
					"Starting Girls"
				), "indent")
					.append(App.UI.DOM.makeElement("span", " A beautiful flower from the Emerald Isle", "note"));

				App.UI.DOM.appendNewElement("div", el, App.UI.DOM.link(
					"Cali Girl",
					() => {
						V.activeSlave = App.StartingGirls.generate({nationality: "American", race: "white"});
						V.activeSlave.eye.origColor = "blue";
						V.activeSlave.skin = "sun tanned";
						V.activeSlave.override_Skin = 1;
						V.activeSlave.origHColor = "blonde";
						V.activeSlave.markings = "none";
						V.activeSlave.face = 55;
						V.activeSlave.muscles = 20;
						V.activeSlave.weight = -20;
						V.activeSlave.natural.height = 190;
						V.activeSlave.height = Height.forAge(V.activeSlave.natural.height, V.activeSlave);
					},
					[],
					"Starting Girls"
				), "indent")
					.append(App.UI.DOM.makeElement("span", " Tall, taut, and tan", "note"));

				App.UI.DOM.appendNewElement("div", el, App.UI.DOM.link(
					"Novice",
					() => {
						V.activeSlave = App.StartingGirls.generate({minAge: 18, maxAge: 18});
						V.activeSlave.skill.anal = 0;
						V.activeSlave.skill.oral = 0;
						V.activeSlave.skill.vaginal = 0;
						V.activeSlave.skill.penetrative = 0;
						V.activeSlave.skill.whoring = 0;
						V.activeSlave.skill.entertainment = 0;
						V.activeSlave.skill.combat = 0;
						V.activeSlave.fetishKnown = 0;
						V.activeSlave.attrKnown = 0;
					},
					[],
					"Starting Girls"
				), "indent")
					.append(App.UI.DOM.makeElement("span", " Train your own and save", "note"));

				App.UI.DOM.appendNewElement("div", el, App.UI.DOM.link(
					"Head Girl Prospect",
					() => {
						V.activeSlave = App.StartingGirls.generate({minAge: 36, maxAge: 44});
						V.activeSlave.career = App.Data.Careers.Leader.HG.random();
						V.activeSlave.intelligence = 70;
						V.activeSlave.intelligenceImplant = 0;
					},
					[],
					"Starting Girls"
				), "indent")
					.append(App.UI.DOM.makeElement("span", " Inexpensive potential to become a great right hand woman", "note"));

				if (V.seeExtreme !== 0) {
					App.UI.DOM.appendNewElement("div", el, App.UI.DOM.link(
						"Wellspring",
						() => {
							V.activeSlave = App.StartingGirls.generate({minAge: 18, maxAge: 18});
							V.activeSlave.skill.anal = 0;
							V.activeSlave.skill.oral = 0;
							V.activeSlave.skill.vaginal = 0;
							V.activeSlave.skill.penetrative = 0;
							V.activeSlave.skill.whoring = 0;
							V.activeSlave.skill.entertainment = 0;
							V.activeSlave.skill.combat = 0;
							V.activeSlave.fetishKnown = 0;
							V.activeSlave.attrKnown = 0;
							V.activeSlave.health.condition = 10;
							V.activeSlave.intelligence = -100;
							V.activeSlave.intelligenceImplant = 0;
							V.activeSlave.vagina = 3;
							V.activeSlave.anus = 3;
							V.activeSlave.ovaries = 1;
							V.activeSlave.dick = 5;
							V.activeSlave.balls = 5;
							V.activeSlave.prostate = 1;
							V.activeSlave.lactation = 2;
							V.activeSlave.lactationDuration = 2;
							V.activeSlave.nipples = "huge";
							V.activeSlave.boobs = 10000;
						},
						[],
						"Starting Girls"
					), "indent")
						.append(App.UI.DOM.makeElement("span", " Capable of producing all kinds of useful fluids", "note"));

					App.UI.DOM.appendNewElement("div", el, App.UI.DOM.link(
						"Onahole",
						() => {
							V.activeSlave = App.StartingGirls.generate();
							applyMindbroken(V.activeSlave);
							V.activeSlave.voice = 0;
							V.activeSlave.hears = 0;
							removeLimbs(V.activeSlave, "all");
							eyeSurgery(V.activeSlave, "both", "normal");
						},
						[],
						"Starting Girls"
					), "indent")
						.append(App.UI.DOM.makeElement("span", " A living cocksleeve", "note"));
				}

				App.UI.DOM.appendNewElement("div", el, App.UI.DOM.passageLink("Back", "Starting Girls"), "indent");
				jQuery(headerLinks).empty().append(el);
			}
		)
	);

	linkArray.push(
		App.UI.DOM.link(
			"Start over by selecting a nationality",
			() => {
				const el = new DocumentFragment();
				const linkArray = [];
				App.UI.DOM.appendNewElement("h3", el, "Start over by selecting a nationality:");
				for (const nation of App.Data.misc.baseNationalities) {
					linkArray.push(
						App.UI.DOM.link(
							nation,
							() => {
								V.activeSlave = App.StartingGirls.generate({nationality: nation});
							},
							[],
							"Starting Girls"
						)
					);
				}
				el.append(App.UI.DOM.generateLinksStrip(linkArray));
				App.UI.DOM.appendNewElement("div", el, App.UI.DOM.passageLink("Back", "Starting Girls"));
				jQuery(headerLinks).empty().append(el);
			}
		)
	);

	/**
	 * @param {FC.HumanState} source
	 * @param {App.Entity.SlaveState} template
	 * @param {function(App.Entity.SlaveState): void} [afterCreateCB]
	 * */
	function relativeLinkStrip(source, template, afterCreateCB) {
		const relatives = [];
		const finish = (slave) => {
			App.StartingGirls.randomizeUnknowns(slave);
			if (typeof afterCreateCB === "function") {
				afterCreateCB(slave);
			}
		};
		const makeSiblingLink = (sibling) => {
			return App.UI.DOM.link(capFirstChar(sibling), () => {
				setMissingParents(source);
				template.mother = source.mother;
				template.father = source.father;
				V.activeSlave = generateRelatedSlave(template, sibling);
				finish(V.activeSlave);
			}, [], "Starting Girls");
		};
		if (source) {
			relatives.push(makeSiblingLink("twin"));
			if (V.seeDicks !== 100 && source.mother === 0) {
				const ageRange = getParentAgeRange(source, false);
				if (ageRange.min <= ageRange.max) {
					relatives.push(
						App.UI.DOM.link("Mother", () => {
							V.activeSlave = generateRelatedSlave(template, "mother");
							finish(V.activeSlave);
							source.mother = V.activeSlave.ID;
						}, [], "Starting Girls")
					);
				}
			}
			if (V.seeDicks !== 0 && source.father === 0) {
				const ageRange = getParentAgeRange(source, true);
				if (ageRange.min <= ageRange.max) {
					relatives.push(
						App.UI.DOM.link("Father", () => {
							V.activeSlave = generateRelatedSlave(template, "father");
							finish(V.activeSlave);
							source.father = V.activeSlave.ID;
						}, [], "Starting Girls")
					);
				}
			}
			if (source.actualAge < V.retirementAge - 2) {
				if (V.seeDicks !== 100) {
					relatives.push(makeSiblingLink("older sister"));
				}
				if (V.seeDicks !== 0) {
					relatives.push(makeSiblingLink("older brother"));
				}
			}
			if (source.actualAge > V.minimumSlaveAge + 2) {
				if (V.seeDicks !== 100) {
					relatives.push(makeSiblingLink("younger sister"));
				}
				if (V.seeDicks !== 0) {
					relatives.push(makeSiblingLink("younger brother"));
				}
			}
			if (source.actualAge > V.minimumSlaveAge + 11) {
				if (V.seeDicks !== 100) {
					relatives.push(
						App.UI.DOM.link("Daughter", () => {
							V.activeSlave = generateRelatedSlave(template, "daughter");
							finish(V.activeSlave);
						}, [], "Starting Girls")
					);
				}
				if (V.seeDicks !== 0) {
					relatives.push(
						App.UI.DOM.link("Son", () => {
							V.activeSlave = generateRelatedSlave(template, "son");
							finish(V.activeSlave);
						}, [], "Starting Girls")
					);
				}
			}
		}
		return App.UI.DOM.generateLinksStrip(relatives);
	}

	linkArray.push(
		App.UI.DOM.link(
			"Start over with your relative",
			() => {
				const pcAsSlave = convertPlayerToSlave(V.PC, "none");
				pcAsSlave.ID = -1; // cheesy but works...DO NOT try to use this abomination for anything else
				App.UI.DOM.appendNewElement("div", el, relativeLinkStrip(V.PC, pcAsSlave, (rel) => {
					// reset some stuff that shouldn't be copied from player conversion onto relatives
					rel.career = randomCareer(rel); // not arcology owners
					rel.skill = new App.Entity.SlaveSkillsState();
					rel.trust = 0;
					rel.devotion = 0;
					rel.origin = "$auto"; // TODO: maybe want custom automatic origins for PC relatives?
				}));
				App.UI.DOM.appendNewElement("div", el, App.UI.DOM.passageLink("Back", "Starting Girls"));
				jQuery(headerLinks).empty().append(el);
			}
		)
	);

	const newSlaves = V.slaves.filter(s => s.newGamePlus === 0);
	if (newSlaves.length > 0) {
		linkArray.push(
			App.UI.DOM.link(
				`Start over with a finalized slave's relative`,
				() => {
					const el = new DocumentFragment();

					const options = [];
					for (const slave of newSlaves) {
						options.push({
							key: slave.ID.toString(),
							name: `${SlaveFullName(slave)} (${slave.genes}, ${slave.actualAge})`
						});
					}
					const select = App.UI.DOM.makeSelect(options, null, slaveID => {
						const srcSlave = getSlave(Number.parseInt(slaveID));
						jQuery(linkDiv).empty().append(relativeLinkStrip(srcSlave, srcSlave));
					});
					App.UI.DOM.appendNewElement("div", el, App.UI.DOM.combineNodes(`Relative of slave: `, select));

					const linkDiv = App.UI.DOM.appendNewElement("div", el, ``);
					App.UI.DOM.appendNewElement("div", el, "Warning: related slaves will influence each other's opinion of you, and may become difficult to control if not properly broken.", "note");
					App.UI.DOM.appendNewElement("div", el, App.UI.DOM.passageLink("Back", "Starting Girls"));
					jQuery(headerLinks).empty().append(el);
				}
			)
		);
	}

	linkArray.push(App.UI.DOM.passageLink("Take control of your arcology", "Acquisition"));
	headerLinks.append(App.UI.DOM.generateLinksStrip(linkArray));
	el.append(headerLinks);
	App.UI.DOM.appendNewElement("hr", el);

	App.StartingGirls.cleanup(V.activeSlave);
	SlaveDatatypeCleanup(V.activeSlave);

	if (V.activeSlave.father === -1) {
		if (V.PC.dick === 0) {
			V.activeSlave.father = 0;
		} else if ((V.PC.actualAge - V.activeSlave.actualAge) < V.minimumSlaveAge || ((V.PC.actualAge - V.activeSlave.actualAge) < V.potencyAge)) {
			V.activeSlave.father = 0;
		}
		if (V.saveImported === 1) {
			V.activeSlave.father = 0;
		}
	}
	if (V.activeSlave.mother === -1) {
		if (V.PC.vagina === -1) {
			V.activeSlave.mother = 0;
		} else if (((V.PC.actualAge - V.activeSlave.actualAge) < V.minimumSlaveAge) || ((V.PC.actualAge - V.activeSlave.actualAge) < V.fertilityAge)) {
			V.activeSlave.mother = 0;
		}
		if (V.saveImported === 1) {
			V.activeSlave.mother = 0;
		}
	}

	App.UI.DOM.appendNewElement("h2", el, "You are customizing this slave:");
	el.append(App.Desc.longSlave(V.activeSlave, {market: "starting"}));

	const tabBar = new App.UI.Tabs.TabBar("StartingGirls");
	tabBar.addTab("Profile", "profile", App.StartingGirls.profile(V.activeSlave));
	tabBar.addTab("Physical", "physical", App.StartingGirls.physical(V.activeSlave));
	tabBar.addTab("Upper", "upper", App.StartingGirls.upper(V.activeSlave));
	tabBar.addTab("Lower", "lower", App.StartingGirls.lower(V.activeSlave));
	tabBar.addTab("Genetic Quirks", "genes", App.StartingGirls.genes(V.activeSlave));
	tabBar.addTab("Mental", "mental", App.StartingGirls.mental(V.activeSlave));
	tabBar.addTab("Skills", "skills", App.StartingGirls.skills(V.activeSlave));
	tabBar.addTab("Stats", "stats", App.StartingGirls.stats(V.activeSlave));
	tabBar.addTab("Family", "family", App.Intro.editFamily(V.activeSlave));
	tabBar.addTab("Body Mods", "body-mods", App.UI.bodyModification(V.activeSlave, true));
	tabBar.addTab("Salon", "salon", App.UI.salon(V.activeSlave, true, true));
	tabBar.addTab("Finalize", "finalize", App.StartingGirls.finalize(V.activeSlave),
		startingSlaveCost(V.activeSlave) > V.cash ? "show-warning" : undefined);
	el.append(tabBar.render());

	return el;
};

repo_name: Arkerthan/fc

license: mit


code:
/**
 *
 * @param {App.Entity.SlaveState} soul
 * @param {App.Entity.SlaveState} body
 * @param {boolean} fromGenepool is slave from the genepool?
 */
globalThis.bodySwap = function(soul, body, fromGenepool) {
	WombInit(body); // Just to be sure.
	soul.genes = body.genes;
	soul.natural = body.natural;
	soul.physicalAge = body.physicalAge;
	soul.visualAge = body.visualAge;
	soul.ageImplant = body.ageImplant;
	soul.health = body.health;
	soul.weight = body.weight;
	soul.muscles = body.muscles;
	soul.height = body.height;
	soul.heightImplant = body.heightImplant;
	soul.race = body.race;
	soul.origRace = body.origRace;
	soul.pubicHColor = body.pubicHColor;
	soul.skin = body.skin;
	soul.origSkin = body.origSkin;
	soul.markings = body.markings;
	soul.eye = body.eye;
	soul.hears = body.hears;
	soul.earImplant = body.earImplant;
	soul.earShape = body.earShape;
	soul.earT = body.earT;
	soul.earTColor = body.earTColor;
	soul.smells = body.smells;
	soul.tastes = body.tastes;
	soul.horn = body.horn;
	soul.hornColor = body.hornColor;
	soul.PTail = body.PTail;
	soul.tail = body.tail;
	soul.tailShape = body.tailShape;
	soul.tailColor = body.tailColor;
	soul.PBack = body.PBack;
	soul.wingsShape = body.wingsShape;
	soul.appendages = soul.appendages;
	soul.appendagesColor = soul.appendagesColor;
	soul.appendagesEffectColor = body.appendagesEffectColor;
	soul.appendagesEffect = body.appendagesEffect;
	soul.origHColor = body.origHColor;
	soul.hColor = body.hColor;
	soul.hLength = body.hLength;
	soul.hStyle = body.hStyle;
	soul.pubicHStyle = body.pubicHStyle;
	soul.waist = body.waist;
	soul.arm = body.arm;
	soul.leg = body.leg;
	soul.PLimb = body.PLimb;
	soul.readyProsthetics = body.readyProsthetics;
	soul.heels = body.heels;
	soul.voice = body.voice;
	soul.voiceImplant = body.voiceImplant;
	soul.shoulders = body.shoulders;
	soul.shouldersImplant = body.shouldersImplant;
	soul.boobs = body.boobs;
	soul.boobsImplant = body.boobsImplant;
	soul.boobsImplantType = body.boobsImplantType;
	soul.boobShape = body.boobShape;
	soul.nipples = body.nipples;
	soul.nipplesAccessory = body.nipplesAccessory;
	soul.areolae = body.areolae;
	soul.areolaeShape = body.areolaeShape;
	soul.boobsTat = body.boobsTat;
	soul.lactation = body.lactation;
	soul.lactationDuration = body.lactationDuration;
	soul.induceLactation = body.induceLactation;
	soul.boobsMilk = body.boobsMilk;
	soul.lactationAdaptation = body.lactationAdaptation;
	soul.hips = body.hips;
	soul.hipsImplant = body.hipsImplant;
	soul.butt = body.butt;
	soul.buttImplant = body.buttImplant;
	soul.buttImplantType = body.buttImplantType;
	soul.buttTat = body.buttTat;
	soul.face = body.face;
	soul.faceImplant = body.faceImplant;
	soul.faceShape = body.faceShape;
	soul.lips = body.lips;
	soul.lipsImplant = body.lipsImplant;
	soul.lipsTat = body.lipsTat;
	soul.teeth = body.teeth;
	soul.vagina = body.vagina;
	soul.vaginaLube = body.vaginaLube;
	soul.vaginaTat = body.vaginaTat;
	soul.fertKnown = body.fertKnown;
	soul.fertPeak = body.fertPeak;
	soul.broodmother = body.broodmother;
	soul.broodmotherFetuses = body.broodmotherFetuses;
	soul.broodmotherOnHold = body.broodmotherOnHold;
	soul.broodmotherCountDown = body.broodmotherCountDown;
	soul.labia = body.labia;
	soul.clit = body.clit;
	soul.dick = body.dick;
	soul.foreskin = body.foreskin;
	soul.anus = body.anus;
	soul.analArea = body.analArea;
	soul.dickTat = body.dickTat;
	soul.prostate = body.prostate;
	soul.balls = body.balls;
	soul.scrotum = body.scrotum;
	soul.ovaries = body.ovaries;
	soul.anusTat = body.anusTat;
	soul.brand = body.brand;
	soul.shouldersTat = body.shouldersTat;
	soul.armsTat = body.armsTat;
	soul.legsTat = body.legsTat;
	soul.backTat = body.backTat;
	soul.stampTat = body.stampTat;
	soul.hormones = body.hormones;
	soul.chem = body.chem;
	soul.vaginalAttachment = body.vaginalAttachment;
	soul.chastityVagina = body.chastityVagina;
	soul.chastityPenis = body.chastityPenis;
	soul.chastityAnus = body.chastityAnus;
	if (soul.custom && body.custom) {
		soul.custom.tattoo = body.custom.tattoo;
	}
	soul.bellyTat = body.bellyTat;
	soul.abortionTat = body.abortionTat;
	soul.birthsTat = body.birthsTat;
	soul.pubertyAgeXX = body.pubertyAgeXX;
	soul.pubertyXX = body.pubertyXX;
	soul.pubertyAgeXY = body.pubertyAgeXY;
	soul.pubertyXY = body.pubertyXY;
	soul.breedingMark = body.breedingMark;
	soul.underArmHColor = body.underArmHColor;
	soul.underArmHStyle = body.underArmHStyle;
	soul.ballType = body.ballType;
	soul.eggType = body.eggType;
	soul.bald = body.bald;
	soul.hormoneBalance = body.hormoneBalance;
	soul.breastMesh = body.breastMesh;
	soul.vasectomy = body.vasectomy;
	soul.haircuts = body.haircuts;
	soul.ovaryAge = body.ovaryAge;
	soul.readyOva = body.readyOva;
	soul.womb = body.womb; // this is array assigned by reference, if the slave body that is ${body} will be still used anywhere in code (not discarded) — it's WRONG (they now technically share one womb object). Please tell me about it then. But if the previous slave body is just discarded — it's no problem then.
	soul.pregAdaptation = body.pregAdaptation;
	soul.geneMods = body.geneMods;
	soul.NCSyouthening = body.NCSyouthening;
	soul.eyebrowHColor = body.eyebrowHColor;
	soul.eyebrowHStyle = body.eyebrowHStyle;
	soul.eyebrowFullness = body.eyebrowFullness;
	soul.wombImplant = body.wombImplant;
	soul.ovaImplant = body.ovaImplant;
	soul.geneticQuirks = body.geneticQuirks;
	soul.albinismOverride = body.albinismOverride;
	soul.clone = body.clone;
	soul.cloneID = body.cloneID;
	soul.inbreedingCoeff = body.inbreedingCoeff;

	soul.canRecruit = 0;

	if (!fromGenepool) { // swapping NOT gene pool records
		soul.counter.publicUse = body.counter.publicUse;
		soul.counter.laborCount = body.counter.laborCount;
		soul.porn = body.porn;
		soul.aphrodisiacs = body.aphrodisiacs;
		soul.curatives = body.curatives;
		soul.drugs = body.drugs;
		soul.prestige = body.prestige;
		soul.prestigeDesc = body.prestigeDesc;
		soul.minorInjury = body.minorInjury;
		soul.eyewear = body.eyewear;
		soul.earwear = body.earwear;
		soul.piercing = body.piercing;
		soul.armAccessory = body.armAccessory;
		soul.legAccessory = body.legAccessory;
		soul.bellyAccessory = body.bellyAccessory;
		soul.preg = body.preg;
		soul.pregSource = body.pregSource;
		soul.pregType = body.pregType;
		soul.labor = body.labor;
		soul.clitSetting = body.clitSetting;
		soul.diet = body.diet;
		soul.dietCum = body.dietCum;
		soul.dietMilk = body.dietMilk;
		soul.clothes = body.clothes;
		soul.collar = body.collar;
		soul.faceAccessory = body.faceAccessory;
		soul.mouthAccessory = body.mouthAccessory;
		soul.shoes = body.shoes;
		soul.makeup = body.makeup;
		soul.nails = body.nails;
		soul.vaginalAccessory = body.vaginalAccessory;
		soul.dickAccessory = body.dickAccessory;
		soul.buttplug = body.buttplug;
		soul.buttplugAttachment = body.buttplugAttachment;
		soul.induce = body.induce;
		soul.mpreg = body.mpreg;
		soul.pregKnown = body.pregKnown;
		soul.pregWeek = body.pregWeek;
		soul.belly = body.belly;
		soul.bellyPreg = body.bellyPreg;
		soul.bellyFluid = body.bellyFluid;
		soul.bellyImplant = body.bellyImplant;
		soul.bellySag = body.bellySag;
		soul.bellySagPreg = body.bellySagPreg;
		soul.bellyPain = body.bellyPain;
		soul.cervixImplant = body.cervixImplant;
		soul.scar = body.scar;
		soul.pregControl = body.pregControl;
		deflate(soul);
	}
};
/**
 *
 * @param {App.Entity.SlaveState} soul
 * @param {App.Entity.SlaveState} body
 */
globalThis.bodySwapName = function(soul, body) {
	if (body.bodySwap === 0) {
		if (body.birthSurname) {
			if (body.birthName !== "") {
				soul.origBodyOwner = SlaveFullBirthName(body);
			} else {
				soul.origBodyOwner = body.slaveName + " " + body.birthSurname;
			}
		} else if (body.birthName) {
			if (body.slaveSurname) {
				if (
					(V.surnameOrder !== 1 && ["Cambodian", "Chinese", "Ancient Chinese Revivalist", "Hungarian", "Japanese", "Edo Revivalist", "Korean", "Mongolian", "Taiwanese", "Vietnamese"].includes(body.nationality)) ||
					V.surnameOrder === 2
				) {
					soul.origBodyOwner = body.slaveSurname + " " + body.birthName;
				} else {
					soul.origBodyOwner = body.birthName + " " + body.slaveSurname;
				}
			} else {
				soul.origBodyOwner = body.birthName;
			}
		} else if (body.slaveSurname) {
			soul.origBodyOwner = SlaveFullName(body);
		} else {
			soul.origBodyOwner = body.slaveName;
		}
	} else {
		soul.origBodyOwner = body.origBodyOwner;
	}
};

/**
 *
 * @param {App.Entity.SlaveState} soul
 * @returns {DocumentFragment}
 */
globalThis.bodySwapSelection = function(soul) {
	const {him} = getPronouns(soul);
	const el = new DocumentFragment();
	const cost = 10000;
	App.UI.DOM.appendNewElement("div", el, `The surgeon awaits the pair of slaves to be strapped into the surgery. So far only ${soul.slaveName} is prepped:`, "scene-intro");
	App.UI.DOM.appendNewElement("div", el, `Select ${(V.seeExtreme) ? `an eligible slave (any slave who is not a fuckdoll)` : `a slave`} who will be trading bodies with ${him}. This operation will cost ${cashFormat(cost)}.`);

	for (const body of V.slaves) {
		if (body.ID === soul.ID) { // Do not allow slave to be swapped with themselves
			continue;
		}
		if (body.indenture !== -1) {
			continue;
		}
		const slaveDiv = document.createElement("div");
		slaveDiv.append(
			App.UI.DOM.link(
				body.slaveName,
				() => {
					V.swappingSlave = body.ID;
					cashX(forceNeg(cost), "slaveSurgery", body);
				},
				[],
				"Slave Slave Swap"
			)
		);
		const relTerm = relativeTerm(soul, body);
		if (relTerm) {
			slaveDiv.append(` ${relTerm}`);
		}
		if (body.relationshipTarget === soul.ID) {
			const {wife} = getPronouns(body);
			switch (body.relationship) {
				case 1:
					slaveDiv.append(` friends`);
					break;
				case 2:
					slaveDiv.append(` best friends`);
					break;
				case 3:
					slaveDiv.append(` friends with benefits`);
					break;
				case 4:
					slaveDiv.append(` lover`);
					break;
				case 5:
					slaveDiv.append(` slave${wife}`);
					break;
			}
		}
		if (body.rivalryTarget === soul.ID) {
			switch (body.relationship) {
				case 1:
					slaveDiv.append(`dislikes`);
					break;
				case 2:
					slaveDiv.append(`rival`);
					break;
				case 3:
					slaveDiv.append(`bitterly hates`);
					break;
			}
		}
		el.append(slaveDiv);
	}

	return el;
};

/**
 *
 * @param {App.Entity.SlaveState} body
 * @returns {DocumentFragment}
 */
globalThis.huskSwapSelection = function(body) {
	const el = new DocumentFragment();
	const cost = 10000;
	App.UI.DOM.appendNewElement("div", el, `"This operation is neither simple nor is it perfected. There are extreme health risks involved and no guarantee of success. Strap a slave into your remote surgery to consent to the operation. Indentured servants${(V.incubator.capacity > 0 || V.nurseryChildren) ? ` and slaves with reserved children` : ``} are not eligible."
	`, "scene-intro");
	App.UI.DOM.appendNewElement("div", el, `Select the slave whose mind will be transferred into the waiting husk. Amputated slaves must not be wearing prosthetics. This operation will cost ${cashFormat(cost)}.`);

	for (const soul of V.slaves) {
		if (isSlaveAvailable(soul)) {
			if (soul.fuckdoll === 0) {
				if (!hasAnyProstheticLimbs(soul)) {
					if (soul.indenture === -1) {
						if (soul.breedingMark === 0 || V.propOutcome === 0 || V.eugenicsFullControl === 1 || !FutureSocieties.isActive('FSRestart')) {
							if (WombReserveCount(soul) === 0) {
								if (soul.ID !== body.ID) {
									App.UI.DOM.appendNewElement("div", el,
										App.UI.DOM.link(
											soul.slaveName,
											() => {
												V.swappingSlave = soul.ID;
												cashX(forceNeg(cost), "slaveSurgery", soul);
											},
											[],
											"Husk Slave Swap"
										)
									);
								}
							}
						}
					}
				}
			}
		}
	}

	return el;
};